2013-07-22 6 views
8

Ich habe begonnen, in die leicht überwältigende Szene von OpenGL Läden von Ressourcen auf einem separaten Thread zu bekommen, damit der Haupt-Thread ein Objekt zu machen, fortgesetzt werden kann. Als ich eintrat, bemerkte ich, dass GLFW einen Monat später eine aktualisierte Version mit einfacherem Kontext-Management veröffentlichte.GLFW 3.0 Ressourcen Loading Mit OpenGL

jedoch mit glfwMakeContextCurrent() Ich habe nicht in der Lage gewesen, dies möglich zu machen. Im Lade-Thread benutze ich diese Funktion und nach ihrer Fertigstellung füge ich sie wieder hinzu, so dass der Haupt-Thread dann den Kontext zur weiteren Verwendung erhält. Dies erlaubt mir nicht, Shader oder andere OpenGL-ähnliche Kreationen zu erstellen und zu kompilieren.

AKTUALISIERT:

Was getan werden muss, so kann ich GLFW in dieser Situation verwenden? Da GLFW tragbar ist, würde ich gerne Code verwenden, der es enthält. Ich kenne nicht die notwendigen Schritte, um einen Thread vorzubereiten, der die GLFW-API berücksichtigt.

Wie this Blog Post Staaten, muss ich zwei Threads mit einem OpenGL-Kontext erstellen (nicht den gleichen Kontext; D) und dann Informationen teilen. Die angezeigten Anweisungen sind jedoch plattformspezifisch. Wie kann ich dann GLFW nutzen, damit die Schritte im Beispiel so plattformunabhängig wie möglich sind?

+1

haupt nicht klar, was Sie fragen. Können Sie es auf ein konkretes Beispiel reduzieren? – DarenW

+2

Sie können den gleichen Kontext in zwei separaten Threads nicht aktuell machen. –

+0

Hoffentlich habe ich alle Bedenken angesprochen. – Behemyth

Antwort

16

Verwenden Sie den share Parameter auf 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; 
} 
+1

Danke für die Antwort! – Behemyth