[OpenGL] - Problem mit Shader



  • Hallo,

    ich versuche momentan ein farbiges Rechteck mit Hilfe von OpenGL darzustellen. Ein einfarbiges, weißes Rechteck bekomme ich hin, aber sobald ich im Vertex- und Fragmentshader ein Farbattribut hinzufüge, wird nichts mehr dargestellt.

    Hier erstmal die Shader:

    // Vertexshader
    #version 330
    
    in vec4 inPosition;
    in vec4 inColor;
    
    out vec4 vertexColor;
    
    void main()
    {
    	vertexColor = inColor;
        gl_Position = inPosition;
    }
    
    // Fragmentshader
    #version 330
    
    in vec4 vertexColor;
    out vec4 fragColor;
    
    void main()
    {
        fragColor = vertexColor;
    }
    

    Die Shader werden erfolgreich geladen und gelinkt, alle Attribute sind auch per glGetAttributeLocation verfügbar.

    Im Konstruktor der Klasse Rectangle werden nun die Buffer und das VAO gesetzt. Etwa so:

    glGenVertexArrays(1, &m_vao);
        glBindVertexArray(m_vao);
    
        Buffer vertexBuffer(GL_ARRAY_BUFFER, m_verts, sizeof(dvec4)*4);
        glVertexAttribPointer(positionAttrib, 4, GL_DOUBLE, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(positionAttrib);
    
        Buffer colorBuffer(GL_ARRAY_BUFFER, m_colors, sizeof(dvec4)*4);
        glVertexAttribPointer(colorAttrib, 4, GL_DOUBLE, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(colorAttrib);
    
        glBindVertexArray(0);
    

    m_verts und m_colors sind jeweils normale 4-elementige Arrays vom Typ glm::core::type::dvec4 . positionAttrib und colorAttrib sind die Indizes der Attribute "inPosition" und "inColor".

    Der Konstruktor der Klasse Buffer macht nur folgendes:

    Buffer::Buffer(GLenum target, const void* data, GLsizei size)
    {
        glGenBuffers(1, &m_name);
        glBindBuffer(target, m_name);
        glBufferData(target, size, data, GL_STATIC_DRAW);
    }
    

    Um das ganze schließlich auf den Bildschirm zu bringen mache ich schließlich folgendes:

    glBindVertexArray(m_vao);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    
        glBindVertexArray(0);
    

    Ich weiß echt nicht wo der Fehler liegen könnte. Falls noch irgendwelche Codeteile fehlen, bitte sagen.

    Danke im Voraus!



  • Ich mein, musst du eigentlich sonst würd wohl das weiße Quad auch nicht gehn aber: Bindest du dein fragColor auch mit glBindFragDataLocation()?



  • Mh, ne - den Befehl kannte ich bisher gar nicht.

    Ich habe jetzt glBindFragDataLocation(m_program.name(), 0, "fragColor"); ergänzt, aber ändern tut sich nichts...

    In der aktuellen OpenGL SuperBible steht auch folgendes:

    If we have only one output from our fragment program, it is internally assigned as "output zero."

    Die entsprechende Stelle in der Spezifikation konnte ich jetzt auf die Stelle nicht finden, aber ich vermute das ist der Grund, warum es vorher auch ohne glBindFragDataLocation geklappt hat.

    Es ist wirklich wie verhext. Selbst wenn ich den Fragmentshader folgendermaßen ändere, funktioniert es nicht:

    #version 330
    
    in vec4 vertexColor;
    out vec4 fragColor;
    
    void main()
    {
        //fragColor = vertexColor;
    	fragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
    

    Das weiße Rechteck bekomme ich übrigens mit folgender Konstellation:

    // Vertexshader
    #version 330
    
    in vec4 inPosition;
    //in vec4 inColor;
    
    //out vec4 vertexColor;
    
    void main()
    {
    	//vertexColor = inColor;
        gl_Position = inPosition;
    }
    
    // Fragmentshader
    #version 330
    
    //in vec4 vertexColor;
    out vec4 fragColor;
    
    void main()
    {
        //fragColor = vertexColor;
    	fragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
    

    Es "funktioniert" also irgendwie nur, solange ich nur eine Inputvariable habe.



  • Mal ein Beispiel für mehrere Attribute:

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(NLVertexData), 0);
            glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(NLVertexData), (void*)(3*sizeof(float)));
            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(NLVertexData), (void*)(7*sizeof(float)));
    

    http://code.google.com/p/nightlight2d/source/browse/trunk/NightLightDLL/NLSpriteBatcher.cpp

    Shader:

    layout(location = 0) in vec3 Position;
    layout(location = 1) in vec4 Colors; 
    layout(location = 2) in vec4 TextureCoord;
    




  • Mh, also ich sehe meinen Fehler immer noch nicht. Ob ich die AttributeLocations manuell setze oder ob ich sie auslese, sollte doch egal sein.

    Ich habe hier mal einen fast kompilierbaren Code hochgeladen, der den Fehler hat. Man muss noch GLFW, GLEW und OpenGL einbinden, ansonsten braucht man nichts. GLFW sollte sich auch problemlos durch GLUT, etc. ersetzen lassen.

    Vielleicht könntet ihr da mal reinschauen.



  • Probier mal erst dein Attribut zu aktivieren und dann den Pointer zu setzen.
    So:

    glEnableVertexAttribArray(positionLoc);
        glEnableVertexAttribArray(colorLoc);
    
        glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
    

    Ich bevorzuge halt die layout-variante.



  • Ändert leider nichts. :|
    Ich hab' die Frage mal im OpenGL Message Board gestellt.


Log in to reply