2017-05-28 7 views
0

私のプログラムでは、1つのVAO、2つのVBOおよび2つのEBOが使用されます。異なるVBOからの描画の問題

//cube 
GLfloat vertices1[] = { 
    0.5f, 0.5f, 0.5f, 
    0.5f, 0.5f, -0.5f, 
    0.5f, -0.5f, 0.5f, 
    0.5f, -0.5f, -0.5f, 
    -0.5f, 0.5f, 0.5f, 
    -0.5f, 0.5f, -0.5f, 
    -0.5f, -0.5f, 0.5f, 
    -0.5f, -0.5f, -0.5f, 
}; 
GLint indices1[]{ 
    2, 0, 4, 
    4, 6, 2, 
    0, 2, 3, 
    3, 1, 0, 
    5, 1, 3, 
    3, 7, 5, 
    0, 1, 5, 
    4, 0, 5, 
    6, 4, 7, 
    4, 5, 7, 
    7, 3, 2, 
    7, 2, 6, 
}; 

//loaded model 
std::vector <GLfloat> teddy_vertices; 
std::vector <GLuint> teddy_indices; 
loadOBJ("teddy.obj", teddy_vertices, teddy_indices); 

GLuint VAO, TEDDY, TEDDY_EBO, newVBO, newEBO; 
glGenVertexArrays(1, & VAO); 
glGenBuffers(1, & TEDDY); 
glGenBuffers(1, & TEDDY_EBO); 
glGenBuffers(1, & newVBO); 
glGenBuffers(1, & newEBO); 

glBindVertexArray(VAO); 
glBindBuffer(GL_ARRAY_BUFFER, newVBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size() * sizeof(GLfloat), & teddy_vertices.front(), GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, TEDDY_EBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, teddy_indices.size() * sizeof(GLuint), & teddy_indices.front(), GL_STATIC_DRAW); 

glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind 

glBindVertexArray(0); 

//... 

while (!glfwWindowShouldClose(window)) { 
    glfwPollEvents(); 

    glClearColor(0.2 f, 0.3 f, 0.3 f, 1.0 f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glm::mat4 model_matrix = glm::mat4(1.0 f); 
    glm::mat4 view; 
    glm::mat4 tilt_view; 
    glm::mat4 projection; 

    view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); //cameraPos + cameraFront 

    projection = glm::perspective(fov, (GLfloat) WIDTH/(GLfloat) HEIGHT, 0.1 f, 100.0 f); 

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model_matrix)); 
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); 
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); 
    glUniform4fv(color, 1, glm::value_ptr(glm::vec4(1, 1, 1, 1))); 

    glBindVertexArray(VAO); 

    if (!teddy_render) { 
     glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
     glDrawElements(
      GL_TRIANGLES, 
      teddy_indices.size(), 
      GL_UNSIGNED_INT, 
      (void *) 0 
     ); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 
    } else { 
     glBindBuffer(GL_ARRAY_BUFFER, newVBO); 
     glDrawElements(
      GL_TRIANGLES, 
      36, 
      GL_UNSIGNED_INT, 0); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 
    } 
    glBindVertexArray(0); 

    glfwSwapBuffers(window); 
} 

glfwTerminate(); 
return 0; 
} 

をこのコードがのみ間違ってロードされたオブジェクトを描画し、望んでいたときに、他のVBOから描画されない:プログラムは、このプログラムがどのように機能すべきかである 非常に奇妙なVBOから描画します。ゲームループ内のコードに変更された場合

glBindVertexArray(VAO); 

//if (!teddy_render){ 
glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
glDrawElements(
    GL_TRIANGLES, 
    teddy_indices.size(), 
    GL_UNSIGNED_INT, 
    (void *) 0 
); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 
//} 
//else{ 
// glBindBuffer(GL_ARRAY_BUFFER, newVBO); 
// glDrawElements(
//    GL_TRIANGLES, 
//    36, 
//    GL_UNSIGNED_INT, 0); 
// glBindBuffer(GL_ARRAY_BUFFER, 0); 
//} 

その後、ロードされたオブジェクトをレンダリングします。ゲームループ上記の構成では、キューブのオブジェクトの後に設定されている場合、その後、キューブはロードされたオブジェクトがまだコメントアウトキューブコードでゲームループにバインドされているにもかかわらず、レンダリング:

glBindVertexArray(VAO); 

glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size() * sizeof(GLfloat), & teddy_vertices.front(), GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, TEDDY_EBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, teddy_indices.size() * sizeof(GLuint), & teddy_indices.front(), GL_STATIC_DRAW); 

glBindBuffer(GL_ARRAY_BUFFER, newVBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, 0); 

glBindVertexArray(0); 

ありがとうございました。

EDIT: これはEBOSなし1 VAOと多くVBOsを使用するコードを動作しているが:

std::vector<GLfloat> teddy_vertices; 
loadOBJ("teddy.obj", teddy_vertices); //read the vertices from the teddy.obj file 

GLuint VAO, VBO, VBO_AXIS, TEDDY; 
glGenVertexArrays(1, &VAO); 
glGenBuffers(1, &VBO); 
glGenBuffers(1, &VBO_AXIS); 
glGenBuffers(1, &TEDDY); 
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). 
glBindVertexArray(VAO); 

glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, VBO_AXIS); 
glBufferData(GL_ARRAY_BUFFER, sizeof(axis), axis, GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size()*sizeof(GLfloat), &teddy_vertices.front(), GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 

glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind 

glBindVertexArray(0); 

//... in game loop 

    glBindVertexArray(VAO); 

    if (!teddy_render){ 
     glBindBuffer(GL_ARRAY_BUFFER, VBO); 
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
     glEnableVertexAttribArray(0); 
     glDrawArrays(render_mode, 0, 36); 
    } 
    else{ 
     glBindBuffer(GL_ARRAY_BUFFER, TEDDY); 
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
     glEnableVertexAttribArray(0); 
     glDrawArrays(render_mode, 0, teddy_vertices.size()); 
    } 
    glBindVertexArray(0); 

答えて

0

のみONE要素が各VAOに割り当てられたバッファが。したがって、glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *)への最後の呼び出しが有効になります。

what VAOs areを参照してください。

+0

私は1 VAOで多くのVBO2を使用するプログラムを持っています。編集をご覧ください。 EBOを使用するプログラムでは、配列バッファをバインドした後に、要素ループバッファをゲームループにバインドするのはなぜですか? – rur2641

+0

@ rur2641:答えは同じです。多くのVBOを持つことができますが、** ONE **要素バッファのみがあります。あなたのコードはそうではありません。 – ybungalobill

関連する問題