multithreading opengl glfw

multithreading - Carga de recursos GLFW 3.0 con OpenGL



(1)

Empecé a adentrarme en la escena ligeramente abrumadora de la carga de recursos de OpenGL en un hilo separado para que el hilo principal continúe representando un objeto. Al intervenir, noté que GLFW lanzó una versión actualizada hace un mes con una administración de contexto más sencilla.

Sin embargo, con glfwMakeContextCurrent () no he podido hacer esto posible. En el hilo de carga utilizo esta función y después de su finalización la vuelvo a agregar para que el hilo principal reciba el contexto para su uso posterior. Esto no me permite crear y compilar sombreadores o cualquier otra creación relacionada con OpenGL.

ACTUALIZADO:

¿Qué hay que hacer para poder usar GLFW en esta situación? Como GLFW es portátil, me encantaría usar un código que lo incluya. No sé los pasos necesarios para preparar un hilo teniendo en cuenta la API GLFW.

Como dice esta publicación de blog, necesito crear dos hilos con un contexto OpenGL (no en el mismo contexto; D) y luego compartir información. Sin embargo, las instrucciones que se muestran son específicas de la plataforma. ¿Cómo puedo utilizar GLFW entonces los pasos en el ejemplo son tan independientes de la plataforma como sea posible?


Use el parámetro share en glfwCreateWindow() :

#include <GL/glew.h> #include <GLFW/glfw3.h> #include <chrono> #include <thread> #include <atomic> // reload shared VBO with random data every second void MyThread( GLFWwindow* win, GLuint vbo, std::atomic< bool >& running ) { glfwMakeContextCurrent( win ); glewInit(); while( running ) { float temp[ 512 ]; for( size_t i = 0; i < 512; i+=2 ) { temp[ i+0 ] = static_cast< float >( rand() % 600 ); temp[ i+1 ] = static_cast< float >( rand() % 600 ); } glBindBuffer( GL_ARRAY_BUFFER, vbo ); glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 512, temp, GL_DYNAMIC_DRAW ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); // oddly important, might need to be glFinish() glFlush(); std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) ); } } int main( int argc, char** argv ) { if( !glfwInit() ) return -1; glfwWindowHint( GLFW_VISIBLE, GL_FALSE ); GLFWwindow* threadWin = glfwCreateWindow( 1, 1, "Thread Window", NULL, NULL ); glfwWindowHint( GLFW_VISIBLE, GL_TRUE ); GLFWwindow* window = glfwCreateWindow( 600, 600, "Hello World", NULL, threadWin ); glfwMakeContextCurrent( window ); glewInit(); // load shared VBO with dummy data float temp[ 512 ] = { 0 }; GLuint vbo; glGenBuffers( 1, &vbo ); glBindBuffer( GL_ARRAY_BUFFER, vbo ); glBufferData( GL_ARRAY_BUFFER, sizeof( float ) * 512, temp, GL_DYNAMIC_DRAW ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); std::atomic< bool > running( true ); std::thread aThread( MyThread, threadWin, vbo, std::ref( running ) ); while( !glfwWindowShouldClose( window ) ) { glfwPollEvents(); glClear( GL_COLOR_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0, 600, 0, 600, -1, 1 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glEnableClientState( GL_VERTEX_ARRAY ); glBindBuffer( GL_ARRAY_BUFFER, vbo ); glVertexPointer( 2, GL_FLOAT, 0, 0 ); glColor3ub( 255, 0, 0 ); glDrawArrays( GL_LINES, 0, 256 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glDisableClientState( GL_VERTEX_ARRAY ); std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); glfwSwapBuffers( window ); } running = false; aThread.join(); glfwTerminate(); return 0; }