2017-12-15 3 views
0

Ich versuche, einen OpenGL-Code von GLFW zu Qt zu übertragen, um es in ein größeres Projekt zu integrieren. Aber egal, was ich versucht habe, ich konnte keine Textur auftauchen lassen und alles, was ich bekomme, ist ein schwarzer Bildschirm.OpenGL-Code funktioniert auf GLFW aber nicht auf Qt OpenGL

In Qt kompiliert das Programm ohne Fehler und ich habe es geschafft, ein mehrfarbiges Dreieck zu zeichnen, bevor Sie versuchen, Texturen einzufügen.

Ich habe versucht, die Qt OpenGL-Objekte für Shader, Shader-Programme, Texturen und Code neu zu schreiben, basierend auf ihren Beispielen, aber immer noch nichts.

Unten ist eine einfache Qt-Implementierung, die versucht, eine Textur anzuzeigen, die zu einem schwarzen Bildschirm führt. Eine genaue GLFW Äquivalent funktioniert:

CustomViewGL::CustomViewGL(QWidget *parent): QOpenGLWidget(parent) 
{ 
    QSurfaceFormat format; 

    format.setMajorVersion(3); 
    format.setMinorVersion(3); 
    format.setProfile(QSurfaceFormat::CoreProfile); 
    setFormat(format); 
} 

void CustomViewGL::initializeGL() 
{ 
    glewExperimental=true; 

    if (glewInit() != GLEW_OK) 
    { 
     qDebug() << "Failed to initialize GLEW"; 
    } 

    std::string vertexShaderSource = 
      " #version 330 core\n         " 
      "              " 
      " layout (location = 0) in vec3 aPos;     " 
      " layout (location = 1) in vec2 aTexCoord;   " 
      "              " 
      " out vec2 TexCoord;         " 
      "              " 
      " void main()           " 
      " {             " 
      "              " 
      " TexCoord = aTexCoord;        " 
      " gl_Position = vec4(aPos, 1.0);     " 
      "              " 
      " }\0             "; 

    std::string fragmentShaderSource = 
      " #version 330 core\n         " 
      "              " 
      " in vec2 TexCoord;         " 
      " out vec4 FragColor;         " 
      " uniform sampler2D tex;        " 
      " void main()           " 
      " {             " 
      "              " 
      " FragColor = texture(tex, TexCoord);     " 
      "              " 
      " }\0             "; 

    // Variables 
    unsigned int shaderVertex, shaderFragment, shaderProgram; 

    .... 
    .... 
    // Compile Shaders // 
    ... 
    ... 

    glUseProgram(shaderProgram); 

    // Vetrices 
    float rectangle[] = { 
     // positions   // texture coords 
     1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right 
     1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right 
     -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left 
     -1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left 
    }; 

    unsigned int indices[] = { // note that we start from 0! 
     0, 1, 3, // first triangle 
     1, 2, 3 // second triangle 
    }; 

    QImage texture = QImage("wall.jpg").convertToFormat(QImage::Format_RGB888); 

    // Variables 
    unsigned int VAO, VBO, EBO, tex; 

    // VAO, VBO, Attributes Configuration 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 

    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle), rectangle, GL_STATIC_DRAW); 


    glGenBuffers(1, &EBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); 
    glEnableVertexAttribArray(0); 

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); 
    glEnableVertexAttribArray(1); 

    // Texture 

    glGenTextures(1, &tex); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, tex); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 

    float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.width(), texture.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, texture.bits()); 

    glGenerateMipmap(GL_TEXTURE_2D); 
} 

void CustomViewGL::paintGL() 
{ 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*) 0); 
} 
+0

Bearbeiten Sie in einem [MCVE]. – genpfault

+0

@genpfault Es ist OpenGL-Code, ist so minimal wie es nur sein kann. Nur das Wichtigste ist im Code enthalten. Es ist vollständig, alles ist enthalten und überprüfbar, Sie können es kopieren und einfügen und prüfen, ob es funktioniert. Es tut nichts besonderes, lädt nur eine Textur und zeigt sie auf dem Bildschirm an. – Manos

+0

Ging ein bisschen zu weit auf der "minimalen" Seite der Dinge, das wird nicht kompiliert wie es ist: keine '# include's, keine' CustomViewGL' Deklaration, fehlende 'wall.jpg'. – genpfault

Antwort

0

In Bezug auf QOpenGLWidget, wie ich in meinem Kommentar über die Frage geschrieben haben, das erste Verhalten, das Ich mag nicht, dass die dort kein Puffer-Swap-Funktion ist. Qt entscheidet willkürlich, wann man Sachen zeichnet, wie in diesem question auch gesagt, was ich definitiv nicht will. Zweitens, obwohl ich die Textur binden und die Texturdaten setzen würde, würde sie nicht auf dem Bildschirm erscheinen, außer a) bind es jedes Mal in der paintGL Funktion oder b) rufe glActiveTexture (GL_TEXTURE1) nach dem Binden und Setzen von TEXTURE0 Daten auf, was bei ist am wenigsten seltsam.

Also entschied ich mich zu QGLWidget, die the official Qt documentation recommends to avoid zu wechseln. QGLWidget bietet die Möglichkeit, den Auto-Swap-Puffer zu deaktivieren, verfügt über eine Swap-Pufferfunktion und arbeitete ordnungsgemäß mit dem in der Frage erwähnten Code (der selbst eine direkte Kopie von einer funktionierenden GLFW-basierten Implementierung war).

Um Auto Puffer Swap zu deaktivieren, wählen Sie OpenGL-Version, setzen Anti-Aliasing und die gemeinsam genutzten Kontext, unter dem Code als Konstruktor verwendet wird:

CustomViewGL::CustomViewGL(QWidget *parent, const QGLWidget *shareWidget): 
    QGLWidget(parent, shareWidget) // QGLWidget accepts as a second 
{         // constructor argument another QGLWidget 
    QGLFormat format;    // thus context sharing between this and 
            // the shareWidget is created 

    format.setVersion(3,3); // Set OpenGL version, here 3.3 
    format.setProfile(QGLFormat::CoreProfile); // Core Profile 
    format.setSamples(16); // Anti Alliasing 

    setFormat(format); 

    setAutoBufferSwap(false); // Prevents Qt from drawing whenever it wants 
} 

Die Header-Datei Angabe des Konstrukteurs ist:

Dann implementieren Sie die geschützte Funktion initializeGL() und geben Sie den Initialisierungscode ein und Sie sind bereit zu gehen.

Verwandte Themen