2017-08-29 2 views
0

Ich habe einen Code, der zunächst einen Shader (unserShader), einen VAO und einen VBO hatte. Es würde eine Szene mit einem texturierten Würfel und seiner Reflexion auf dem Boden mittels Schablonentests wiedergeben. Jetzt wollte ich einen Framebuffer für die Nachbearbeitung hinzufügen, also brauchte ich einen zweiten Shader. Ich habe einen zweiten Shader (ScreenShader) und einen zweiten VBO hinzugefügt. Ich verwende sie noch nicht in meiner Zeichnung, aber die simple Tatsache, dass ich sie hinzufüge, lässt meinen Code ein schwarzes, rotes Dreieck statt der üblichen Szene rendern.OpenGL: zweite VBO verwöhnt zuerst VBO

Mein Code sieht wie folgt aus:

Shader ourShader(string("core.vs"), string("core.frag")); // shader class creating a shader program from vertex shader and fragment shader source files. 
    Shader screenShader(string("core2.vs"), string("core2.frag")); 

    // Setting up attributes, VAO, VBO 
    GLuint VAO; 
    array<GLuint, 2> VBO; 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(2, &VBO[0]); 

    glBindVertexArray(VAO); 

    // Data for first shader and first VBO 
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesCube), verticesCube, GL_STATIC_DRAW); 

    GLint posAttribLoc = glGetAttribLocation(ourShader.Program, "position"); 
    glVertexAttribPointer(posAttribLoc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); // specify (to the active VAO) how to retrieve the values for the attribute "position" from the data stored ("vertices" here) on the active VBO (GPU) 
    glEnableVertexAttribArray(posAttribLoc); // enable attribute for rendering 

    GLint colAttribLoc = glGetAttribLocation(ourShader.Program, "color"); 
    glVertexAttribPointer(colAttribLoc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(colAttribLoc); 

    GLint texAttribLoc = glGetAttribLocation(ourShader.Program, "texCoord"); 
    glVertexAttribPointer(texAttribLoc, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(texAttribLoc); 

    // ##### PART GIVING A WEIRD RESULT ##### 
    // Data for second shader and second VBO 
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesRectangle), verticesRectangle, GL_STATIC_DRAW); 

    GLint posAttribLoc2 = glGetAttribLocation(screenShader.Program, "position"); 
    glVertexAttribPointer(posAttribLoc2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); // specify (to the active VAO) how to retrieve the values for the attribute "position" from the data stored ("vertices" here) on the active VBO (GPU) 
    glEnableVertexAttribArray(posAttribLoc2); // enable attribute for rendering 

    GLint texAttribLoc2 = glGetAttribLocation(screenShader.Program, "texCoord"); 
    glVertexAttribPointer(texAttribLoc2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(texAttribLoc2); 
    // ##### END ##### 

    // Setting up texture that will be used for the first shader 
    GLuint texture; 
    int width, height; 
    glGenTextures(1, &texture); 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture); // makes "texture" the current texture and attaches it to texture unit 0 

    // Set the wrapping 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

    // Set the filtering 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    unsigned char* image = SOIL_load_image("res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); 
    glGenerateMipmap(GL_TEXTURE_2D); 
    SOIL_free_image_data(image); 

    // Unbind VBO, texture before main loop 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    glfwSwapInterval(1); 
    glfwSetKeyCallback(window, Input::keyCallback); // Input is a singleton class handling inputs. It works well. 
    glfwSetCursorPosCallback(window, Input::mouseCallback); 
    glfwSetScrollCallback(window, Input::scrollCallback); 

    while (glfwWindowShouldClose(window) == GLFW_FALSE) { 
     // MAIN LOOP 
     // ... 
    } 
    glDeleteVertexArrays(1, &VAO); 
    glDeleteBuffers(2, &VBO[0]); 

Die mainloop ist nicht wichtig, denke ich. Was ich sagen möchte ist, dass, wenn ich die paar Zeilen entferne, die sich mit dem zweiten VBO beschäftigen, dann wird die Szene gut wiedergegeben. Ansonsten bekomme ich ein komisch gefärbtes Dreieck.

Und meine zwei Shader verwenden diese Quelldateien für ihre jeweiligen Vertex Shader und Fragment Shader. Übrigens bekomme ich von meinen Shadern keine Kompilierungsfehler.

core.vs:

#version 330 core 
in vec3 position; 
in vec2 texCoord; 
in vec3 color; 

out vec2 TexCoord; 
out vec3 Color; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = projection*view*model*vec4(position, 1.0); 
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 
    Color = color; 
} 

core.frag:

#version 330 core 
in vec2 TexCoord; 
in vec3 Color; 

out vec4 outColor; 
uniform sampler2D ourTexture0; 

void main() 
{ 
    outColor = vec4(Color, 1)*texture(ourTexture0, TexCoord); 
} 

core2.vs:

#version 330 core 
in vec2 position; 
in vec2 texCoord; 
out vec2 TexCoord; 
void main() 
{ 
    gl_Position = vec4(position, 0.0, 1.0); 
    TexCoord = texCoord; 
} 

core2.frag:

#version 330 core 
in vec2 TexCoord; 
out vec4 outColor; 
uniform sampler2D texFramebuffer; 
void main() 
{ 
    outColor = texture(texFramebuffer, TexCoord); 
} 

Die Eckpunkte wie folgt aussehen (aber nur der Weg, sie ist wichtig, zu lesen):

GLfloat verticesRectangle[] = { 
     // position  // texture coordinates 
     -0.5f, -0.5f, 0.0f, 0.0f,  
     0.5f, -0.5f, 1.0f, 0.0f,  
     -0.5f, 0.5f, 0.0f, 1.0f,  
     0.5f, 0.5f,  1.0f, 1.0f  
    }; 

    GLfloat verticesCube[] = { 
     // position   // color   // texture coordinates 
     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 

     -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 

     -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 

     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 

     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 

     -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 
     -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 
     -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 

     -1.0f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // reflection surface // not a part of the cube itself 
     -1.0f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 
     1.0f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
     1.0f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
     -1.0f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 
     1.0f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f 
    }; 

Ich habe schon bei Binding a second vertex buffer seems to spoil my first vertex buffer, OpenGL OES ios 5.1 aussah, aber die Person, hatte dieses Problem, weil er nicht seine VAO richtig benutzt hat.

+0

Was ist der Punkt vaos der Verwendung, wenn Sie eine haben? – Frank

Antwort

2

Wahrscheinlich haben zwei Ihrer Attributpositionen denselben Wert. Da Sie nur einen VAO verwenden, überschreiben Sie einige der Bindungen. Die korrekte Verwendung mehrerer unabhängiger Geometrien ist die Verwendung von VAO pro Geometrie.

Der richtige Code hat irgendwie so aussehen:

glBindVertexArray(vao1); 
glBindBuffer(VBO[0]) 
glVertexAttribPointer... 
glEnableVertexAttribArray... 
//Setup all attributes for first VBO 

glBindVertexArray(vao2); 
glBindBuffer(VBO[1]) 
glVertexAttribPointer... 
glEnableVertexAttribArray... 
//Setup all attributes for second VBO 

Wenn das Rendering auf folgende Arten tun:

glBindVertexArray(vao1); 
glDraw*... //Draw VAO1 

glBindVertexArray(vao2); 
glDraw*.... //Draw VAO2 
+0

Bitte beachten Sie, dass Sie tatsächlich 2 VBOs nicht benötigen. Wenn die Eckpunktformate gleich sind, können alle Objekte in demselben VBO gespeichert werden. Sie benötigen 2 VAOs, die auf die korrekten Positionen in den gebundenen VBO-Puffern zeigen. – StarShine

+1

Es kann auch im selben Puffer gespeichert werden, wenn das Format nicht das gleiche ist. Puffer sind nur Rohdaten. – BDL