2017-08-29 23 views
0

私は最初に1つのシェーダ(ourShader)、1つのVAOと1つのVBOを持つコードを持っています。これは、ステンシルテストを使用して、テクスチャ付き立方体と地面上のその反射を持つシーンをレンダリングします。今、後処理のためにフレームバッファを追加したいので、2番目のシェーダが必要でした。 2番目のシェーダ(screenShader)と2番目のVBOを追加しました。私はまだ私の描画でそれらを使用していませんが、私はそれらを追加している単純な事実は、通常のシーンの代わりに、黒い赤い三角形を描画します。OpenGL:最初のVBOを駄目にする2番目のVBO

私のコードは次のようになります。

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]); 

メインループは、私が考える重要ではありません。私が言いたいのは、2番目のVBOを扱ういくつかの行を削除すると、シーンがうまくレンダリングされるということです。それ以外の場合、私は奇妙な色の三角形を取得します。

私の2つのシェーダは、それぞれの頂点シェーダとフラグメントシェーダにこれらのソースファイルを使用します。ちなみに、私はシェイダーからコンパイルエラーを受け取りません。

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); 
} 

個の頂点がこの(しかし、それらを読むための唯一の方法は重要である)のようになります。

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 
    }; 

私はすでにBinding a second vertex buffer seems to spoil my first vertex buffer, OpenGL OES ios 5.1を見てきましたが、彼は正しく彼のVAOを使用していなかったので、人は、この問題を抱えていました。

+0

あなたが1つしかない場合はVAOsを使用してのポイントは何ですか? – Frank

答えて

2

属性の場所のうち、おそらく2つが同じ値を持っています。 1つのVAOだけを使用するので、いくつかのバインディングがオーバーライドされます。独立した複数のジオメトリを使用する正しい方法は、ジオメトリごとにVAOで使用することです。

正しいコードは次のように何とか見ています

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 

は、次の操作を行いレンダリングする場合:

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

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

実際には2つのVBOは必要ありません。頂点の形式が同じ場合は、すべてのオブジェクトを同じVBOに格納できます。バインドされたVBOバッファ内の正しい位置を指し示す2つのVAOが必要です。 – StarShine

+1

フォーマットが同じでない場合は、同じバッファに格納することもできます。バッファは生データです。 – BDL

関連する問題