1

在此处输入图像描述

目的是什么:

我对线程比较陌生。我一直在尝试制作能够快速高效地渲染的四叉树渲染地形。当前渲染的地形数量会大大滞后于用户,如果它都是最大细节的话。这就是我使用 QuadTree 来渲染它的原因。该引擎还支持输入和物理,因此我决定使用渲染线程。这引起了很多问题。

问题(的): 当我没有线程时,由于引擎中的其他系统而有一点延迟。导致延迟的主要原因是 QuadTree 中地形的加载和删除(我什至不确定这是否是最佳方法。)现在,渲染发生得非常快,而且似乎没有延迟。当相机静止时,游戏运行良好。我让游戏运行了一个小时,没有发现崩溃。

加载地形时,它使用渲染代码使用的几个变量。即,绑定缓冲区 -

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);

我相信这个变量与另一个线程同时被访问。这会导致崩溃。如何解决这个问题?我尝试过使用互斥锁,但这似乎不起作用。我将在哪里锁定和解锁互斥锁来解决这个问题?

另一个似乎导致相同错误的变量是“IsLeaf”。

加载大量地形后导致另一个崩溃 (std::badAlloc)。尽管它正在被清理干净。我认为这是由于我的删除代码,但我不知道出了什么问题。

我目前添加和删除图块的方式是检查相机的范围并删除/创建图块。我想渲染我所在的瓷砖及其周围的瓷砖。但是,这在从 4 个主要图块之一转换时不起作用。使用范围创建不起作用,因为它是大图块中心的范围,而不是小图块的中心。我也尝试过每隔几秒钟删除整个地图,这似乎也有效,但滞后更多。有没有更好的方法来进行创建和销毁?

不同分辨率之间存在差距。有没有办法减少这些?目前我渲染的瓷砖比他们需要的大一点,但这对主要的分辨率变化没有帮助。

如果您知道如何解决其中一个错误,我们将不胜感激。

代码(这里上传太多)

http://pastebin.com/MwXaymG0

http://pastebin.com/2tRbqtEB

4

1 回答 1

5

OpenGL 上下文一次只能绑定到一个线程(通过 Windows 上的 wglMakeCurrent())。

因此,您不应该跨线程使用 gl* 函数,即使您使用互斥锁来保护对内存中某些变量的访问,调用也会失败。

我的建议是将您的 gl* 调用移动到您的渲染线程中,但是,在您的其他线程中包含地形加载、平截头体计算、裁剪等内容。渲染线程只需要检查一个对象是否有新数据,然后执行适当的 GL 调用作为其更新/渲染的一部分。

于 2013-08-19T12:23:51.377 回答