OpenGL VBO within multiple threads

后端 未结 3 1264
清酒与你
清酒与你 2021-01-05 19:33

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 til

相关标签:
3条回答
  • 2021-01-05 20:13

    You only need to call wglMakeCurrent exactly once in each thread. This works reliably, it is what I'm doing (though with OpenGL 3.3). This marks one context belonging to one thread. It stays that way until you tell OpenGL differently, so do it once at the beginning and forget (in fact, you don't need to call it at all if you create contexts in their respective threads using them, but do it anyway just to be 100% safe, also I prefer creating all contexts before starting up, it's not as messy...).

    You need not worry about the function pointer, by the way, just use the same one you've used in the render thread (assuming you've properly initialized it there).
    Technically, it is invalid to use a function pointer from another context. However, WGL kindly guarantees (hidden in the small print!) that function pointers are identical for all contexts having the same pixel format. Thus, you're good to go.

    An alternative that works with a single context is to glMapBuffer in the render thread and pass the pointer to the worker thread. Then, upon completion (signalling a semaphore, for example), glUnmapBuffer, again in the render thread.
    Some people prefer this, as it does not involve context juggling and presumably works better on some old buggy drivers. I don't like it because of the extra synchronization needed. It's a matter of taste, same effect.

    0 讨论(0)
  • 2021-01-05 20:20

    This is really not that complicated.

    You just make two buffer objects: one that you're using for current rendering and one that you will be using in the future. When the unused buffer is full of data, the rendering thread switches to rendering from that one. The previously used buffer becomes the unused one.

    You can upload the data in one of two ways. One way is for your data creation thread to create an array of data that the rendering thread will upload to the buffer object with glBufferData. Obviously this will require some synchronization, but it's sync code that you need: your render thread must ultimately be informed when data is ready so that it can render with the new data.

    The other way is for your rendering thread to be told that data needs to start being generated. At which point, it will map the unused buffer object and pass the mapped pointer to the data creation thread. That thread will generate data directly into that mapped pointer. When it finishes, it informs the render thread, which will unmap the buffer and then render with the data.

    Neither method requires multiple contexts or threading through OpenGL code.

    Note that performance will be best served by not making the buffers bigger and smaller. Pick a size and stick with it; you don't want to resize buffers with glBufferData.

    0 讨论(0)
  • 2021-01-05 20:27

    I have already an answer for this kind of tasks.

    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).

    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
    0 讨论(0)
提交回复
热议问题