多个线程中的OpenGL VBO [英] OpenGL VBO within multiple threads

查看:83
本文介绍了多个线程中的OpenGL VBO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用C ++/OpenGL开发一个程序,该程序绘制了整个世界的地形.我有一个以图块形式存储的海拔高度数据库.每次我启动程序时,都会加载一个图块.然后,随着人的移动,应该加载另一个图块,这种情况不会每帧发生一次,也许每5分钟一次.

I am developing a program in C++/OpenGL which draws terrain of the entire world. I have a database of altitude heights stored as tiles. Every time I start the program, a tile is loaded. Then as the person moves, another tile should load, this does not happen every frame, maybe once every 5 minutes.

我将初始图块加载到视频卡的内存中:

I load the initial tile in the video card's memory:

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VBOsz * 3 * sizeof(float), tile_data, GL_STATIC_DRAW_ARB);

...有法线,颜色和索引缓冲区

...There are normals, color and index buffers

然后我画它们:

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VBOsz * 3 * sizeof(float), tile_data, GL_STATIC_DRAW_ARB);


glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

...

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBuffer[idx]);
glDrawElements(GL_TRIANGLES, IndexBuffersz, GL_UNSIGNED_INT, BUFFER_OFFSET(0));

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

由于我希望程序尽可能平滑,因此无法在同一帧上计算顶点+颜色+法线+其他纹理,因为创建贴图大约需要20秒.

Since I want the program to be as smooth as possible, I can't calculate the vertex+color+normal+ other textures the same frame, as it takes about 20 seconds to create a tile.

因此,我决定创建一个加载器线程,该线程将检查何时需要加载新的图块,然后再加载它.完成所有操作后,就应该交换VBO(因此[idx].

So I decided to make a loader thread that would check for when a new tile needs to be loaded and then load it. When it would be all done, it should just swap the VBO(hence the [idx].

因此对于加载器线程,我知道我需要第二个OpenGL上下文,我创建了一个,并在它们之间共享列表.这个想法是可行的,但是在加载器线程中,当我发送新的VBO数据时,我需要以下功能:wglMakeCurrent

So for a loader thread, I know that I need a second OpenGL context, I created one and I share the lists between them. The idea is working, but in the loader thread, when I send the new VBO data, I need this function: wglMakeCurrent

仅当所有数据都已加载时,我才可以将上下文设置为渲染线程(主程序的线程).这导致在这段时间内没有任何内容被绘制,这使程序无用.

Only when all the data has been loaded, I can set the context to the rendering thread(main program's thread). This causes nothing to be drawn for that amount of time, which makes the program useless.

您对解决方案有任何想法吗?我需要更改概念吗?

Do you have any ideas on a solution? Do I need to change the concept?

我正在使用OpenGL 2.1.升级到OpenGL 3是否可以解决问题?

I am using OpenGL 2.1. Will upgrading to OpenGL 3 solve the problem?

推荐答案

我已经有答案任务.

简而言之,您将创建两个共享上下文.然后,按照 Damon 的建议,使上下文在其自己的线程上为当前状态,仅在线程执行开始时一次.这两个上下文将同时在不同的线程(一个线程,一个上下文)上处于最新状态.

In few words, you create two sharing contextes. Then, as suggested by Damon, make the contextes current on their own thread, only once at the beginning of the thread execution. The two contextes will be current at the same time on different threads (one thread, one context).

然后,辅助线程将不用于渲染,而是用于加载资源(我的意思是,实际上是加载地形数据,纹理...,并在每个数据上创建相应的OpenGL对象,例如纹理和缓冲区对象) .这是在主上下文正在绘制时发生的.

Then, the secondary thread won't be used for rendering, but for loading resources (I mean, actually loading terrain data, textures... and create a corresponding OpenGL object on each data, such as textures and buffer objects). This happens while the main context is drawing.

基本上,您不必担心在应用程序周围使用指针并阻止渲染线程来上传数据.但以创建另一个上下文为代价.让驱动程序同步上下文状态:如果它可以顺利执行操作,则您的应用程序将从中受益.至少,您的代码会更干净.

Essentially, you don't need to worry about bringing a pointer around the application and blocking the rendering thread for uploading data; but at the cost of creating another context. Let the driver to synchronize context states: if it can perform that operations smoothly your application will will benefit of it; at least, you code will be cleaner.

我在这个问题上的其他贡献:

Other contributions of mine on the subject:

  • Resource design : read about resource sharing
  • Sharing between contextes with different versions

这篇关于多个线程中的OpenGL VBO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆