【发布时间】:2014-08-25 07:19:58
【问题描述】:
我设置了一个单独的线程来处理游戏端口上的屏幕刷新。这使我可以专注于使用简单的块图形更新用于主游戏的内存缓冲区。我所要担心的是改变什么在哪里,渲染线程会自动更新背景中的显示纹理。它工作得很好(在渲染循环之间添加延迟之后)。问题是在看似随机的情况下,SDL_CreateWindow 调用将永远不会返回。它不会给出错误,它只是坐在那里什么都不做。该线程的 InitVideo 部分是:
const HWND desk = GetDesktopWindow();
RECT dsize;
FILE *cfile;
int count1, count2;
printf("Reading font file\r\n");
fopen_s(&cfile,"character.dat","rb");
for(count1 = 0; count1 < 128; count1++)
for(count2 = 0; count2 < 8; count2++)
chROM[count1][count2] = (unsigned char)fgetc(cfile);
fclose(cfile);
printf("Font data read\r\n");
GetWindowRect(desk,&dsize);
if (fullscreen) {
width = dsize.right;
height = dsize.bottom;
} else {
height = (int)(dsize.bottom * .85);
if (((height * 6) / 5) > dsize.right) {
width = (int)(dsize.right * .85);
height = (int)((width * 5) / 6);
} else width = (int)((height * 6) / 5);
}
printf("Initializing SDL\r\n");
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
printf("SDL Initialization failed\r\n");
Sleep(2000);
exit(-1);
}
printf("Creating Window\r\n");
if (fullscreen)
screen = SDL_CreateWindow("Ultima: Escape from Mount Drash!!",SDL_WINDOWPOS_UNDEFINED \
,SDL_WINDOWPOS_UNDEFINED,0,0,SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL);
else screen = SDL_CreateWindow("Ultima: Escape from Mount Drash",SDL_WINDOWPOS_CENTERED \
,SDL_WINDOWPOS_CENTERED,width,height,SDL_WINDOW_OPENGL);
if(!screen) {printf("Failed to create screen\r\n");Sleep(2000);exit(-1);}
printf("Screen Created\r\n");
主要介绍点代码为:
int main(int argc, char* argv[])
{
unsigned char lv$[10];
int count;
srand((unsigned int)time(NULL));
_beginthread(Video, 0, NULL);
Sleep(5000);
睡眠命令是给视频时间初始化和打开。启动并运行后,它只是黑屏几秒钟,但我可以忍受。无论如何,第一个屏幕只是一个信息屏幕。如果我碰巧在屏幕打开并开始渲染之前将某些东西放入缓冲区,那应该不是问题。无论如何,它在创建时都用零填充(在标头 - 全局变量中,因此渲染和主线程都可以访问它。)
问题是,大约 10 次中有 8 次,窗户永远不会打开。输出在“Creating Window”处停止,永远不会得到其他任何东西。我已经等了 30 分钟,一无所获。我必须强制退出(通过窗户)。我无法弄清楚任何类型的模式。我将毫无问题地加载游戏一次,然后接下来的五次(打开或关闭 Visual Studio)它将失败。然后它将在接下来的 10 次成功,然后失败 20 次,依此类推......当它工作时,它工作得很好,没有任何问题或崩溃(到目前为止)。通过调试模式(Visual C++ 2010)到那一点,然后就坐在那里。没有错误消息,什么都没有。我按 F11(步入),它就在那里。进不去,进不去。
我试图在 SDL 论坛上发布问题,但显然它已被锁定,因此我无法发布新消息。而且,是的,我确实使用电子邮件验证了我的帐户。
【问题讨论】:
-
sdl 是否允许您从与主线程不同的线程更新视图?通常允许主线程在屏幕上绘制,并将逻辑移动到不同的线程
-
SDL 从未以线程安全的方式设计,Sam 已公开承认这一点。创建主窗口的线程是唯一可以/应该访问它的线程(包括例如处理事件)。从我所看到的情况来看,这更多是对底层 API 的限制。
-
所有 SDL 都在一个线程中处理。我在线程之外所做的只是改变一个缓冲区(实际上是一个数组)。渲染线程读取数组,将其转换为 ARGB 像素,更新纹理,渲染它,等待片刻,然后重复。它还轮询事件并将结果放入我可以从主线程读取的结构中,但我还没有完成编写该代码。
标签: c++ multithreading visual-studio-2010 visual-c++ sdl-2