2017-05-28 62 views
0

我的計劃使用一個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繪製。

如果在遊戲循環代碼被更改爲:

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

謝謝。

編輯: 這是工作,它使用許多維也納組織用1 VAO代碼而不EBOS:

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

我有一個程序使用許多VBO2與1 VAO。請參閱編輯。在使用EBO的程序中,綁定數組緩衝區不起作用後,爲什麼會在遊戲循環中綁定元素數組緩衝區? – rur2641

+0

@ rur2641:答案依然如此。你可以有許多VBO,但只有** ONE **元素緩衝區。否則,你的代碼不會。 – ybungalobill