我正在制作游戏,而我实际上正在制作地图。
使用某些算法在程序上生成地图。这没有问题。
问题是我的地图可能很大。所以我考虑过以大块的形式切割地图。
我的块很好,它们各有512 * 512像素,但唯一的问题是:我必须生成一个纹理(实际上是来自SFML的RenderTexture)。它需要大约0.5毫秒才能生成,所以每当我生成一个块时它就会冻结游戏。
我已经想过要解决这个问题的方法:我已经建立了一个带工厂的线程池。我只需要向它发送一个任务,它就会创建一个块。
现在它全部实现了,它会引发像:
这样的opengl警告“RenderTarget.cpp(219)中的内部OpenGL调用失败:GL_INVALID_OPERATION,在当前状态下不允许指定的操作”。
我不知道这是否是处理大块的好方法。我还想过将块保存到图像/文件中,但我担心保存/加载它们需要花费太多时间。
你知道更好的方法来处理这种“无限”的地图吗?
答案 0 :(得分:2)
要尝试的事情:
答案 1 :(得分:2)
这是一个无效的操作,因为您必须有一个绑定到每个线程的上下文。更重要的是,所有GL窗口系统API都在线程和上下文之间强制执行严格的1:1映射...没有线程可能有多个上下文绑定,并且没有上下文可能绑定到多个线程。您需要做的是使用共享上下文(一个上下文用于绘图,一个用于每个工作线程),缓冲区对象和纹理之类的东西将在所有 共享 上下文之间共享但是像FBO和VAO这样的状态机和容器对象不会。
您是否正在为此地图使用平铺渲染,或者这只是一个巨大的纹理?
如果您不需要更新“块”图像的各个子区域,则只需在工作线程中创建新纹理即可。工作线程可以创建新纹理,并在绘图线程开展业务时为其提供数据。只有在工作线程完成后,您才会尝试使用其中一个块进行绘制。这可能会增加块开始加载和最终出现在完成的场景之间的整体延迟,但您应该获得更一致的帧速率。
如果您需要使用单个纹理,我建议您双重缓冲纹理。有一个在绘图线程中使用,另一个在工作线程发出glTexSubImage2D (...)
。当工作线程完成更新纹理区域时,您可以交换用于绘制和更新的纹理。这将减少所需的同步量,但会在更新最终显示在屏幕上之前再次增加延迟。