2015-12-03 82 views
1

我想用着色器使用OpenGL在我的屏幕上呈現兩個三角形;一個大紅色,一個小藍色。每個三角形由一組頂點位置和顏色以及一組頂點索引定義。我爲每個三角形使用不同的頂點數組對象。使用OpenGL和頂點數組對象呈現兩個對象

下面是我的代碼,我已經減少到最小的可編譯的例子,它仍然給我的問題。問題是隻有第二個三角形(object2,小的藍色三角形)被渲染。所以,即使我綁定第一個三角形(object1,大紅色三角形)的頂點數組對象,然後繪製元素,但不會呈現此對象。

我在做什麼錯?

#include <GL/glew.h> 
#include <GL/glut.h> 
#include <Eigen/Eigen> 
#include <fstream> 

GLuint object1_vertex_buffer, object1_colour_buffer, object1_index_buffer, object1_vertex_array; 
GLuint object2_vertex_buffer, object2_colour_buffer, object2_index_buffer, object2_vertex_array; 
GLuint shader_program, vertex_shader, fragment_shader; 

void RenderScene() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glClear(GL_DEPTH_BUFFER_BIT); 

    glBindVertexArray(object1_vertex_array); 
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)0); 

    glBindVertexArray(object2_vertex_array); 
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)0); 

    glutSwapBuffers(); 
} 

int main(int argc, char** argv) 
{ 
    // Make the objects 
    Eigen::Vector3f object1_vertices[3]; 
    object1_vertices[0] << 0, 0, 0; 
    object1_vertices[1] << 0.8, 0, 0; 
    object1_vertices[2] << 0.8, 0.8, 0; 
    Eigen::Vector3f object1_colours[3]; 
    object1_colours[0] << 1.0, 0.0, 0.0; 
    object1_colours[1] << 1.0, 0.0, 0.0; 
    object1_colours[2] << 1.0, 0.0, 0.0; 
    int object1_indices[3]; 
    object1_indices[0] = 0; 
    object1_indices[1] = 1; 
    object1_indices[2] = 2; 

    Eigen::Vector3f object2_vertices[3]; 
    object2_vertices[0] << 0, 0, 0; 
    object2_vertices[1] << 0.5, 0, 0; 
    object2_vertices[2] << 0.5, 0.5, 0; 
    Eigen::Vector3f object2_colours[3]; 
    object2_colours[0] << 0.0, 0.0, 1.0; 
    object2_colours[1] << 0.0, 0.0, 1.0; 
    object2_colours[2] << 0.0, 0.0, 1.0; 
    int object2_indices[3]; 
    object2_indices[0] = 0; 
    object2_indices[1] = 1; 
    object2_indices[2] = 2; 

    // Set up OpenGL 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowSize(1000, 1000); 
    glutCreateWindow("Test"); 
    glutDisplayFunc(RenderScene); 
    glewInit(); 
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 
    glEnable(GL_DEPTH_TEST); 

    // Make the buffers 
    glGenBuffers(1, &object1_vertex_buffer); 
    glGenBuffers(1, &object1_colour_buffer); 
    glGenBuffers(1, &object1_index_buffer); 
    glGenVertexArrays(1, &object1_vertex_array); 
    glGenBuffers(1, &object2_vertex_buffer); 
    glGenBuffers(1, &object2_colour_buffer); 
    glGenBuffers(1, &object2_index_buffer); 
    glGenVertexArrays(1, &object2_vertex_array); 

    // Fill the buffer data 
    glBindVertexArray(object1_vertex_array); 
    glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(object1_vertices), &object1_vertices[0], GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glBindBuffer(GL_ARRAY_BUFFER, object1_colour_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(object1_colours), &object1_colours[0], GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object1_indices[0], GL_STATIC_DRAW); 

    glBindVertexArray(object2_vertex_array); 
    glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(object2_vertices), &object2_vertices[0], GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glBindBuffer(GL_ARRAY_BUFFER, object2_colour_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(object2_colours), &object2_colours[0], GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object2_indices[0], GL_STATIC_DRAW); 

    // Make the shader program 
    shader_program = glCreateProgram(); 

    vertex_shader = glCreateShader(GL_VERTEX_SHADER); 
    std::ifstream vertex_file_in; 
    vertex_file_in.open("../src/vertex-shader.glsl"); 
    std::stringstream vertex_file_stream; 
    vertex_file_stream << vertex_file_in.rdbuf(); 
    std::string vertex_shader_string = vertex_file_stream.str(); 
    std::cout << vertex_shader_string << std::endl; 
    const GLchar* ptr_vertex_shader_string = &vertex_shader_string[0]; 
    const GLchar** vertex_shader_strings = &ptr_vertex_shader_string; 
    int vertex_shader_lengths[] = {(int)vertex_shader_string.length()}; 
    glShaderSource(vertex_shader, 1, vertex_shader_strings, vertex_shader_lengths); 
    glCompileShader(vertex_shader); 
    glAttachShader(shader_program, vertex_shader); 

    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 
    std::ifstream fragment_file_in; 
    fragment_file_in.open("../src/fragment-shader.glsl"); 
    std::stringstream fragment_file_stream; 
    fragment_file_stream << fragment_file_in.rdbuf(); 
    std::string fragment_shader_string = fragment_file_stream.str(); 
    const GLchar* ptr_fragment_shader_string = &fragment_shader_string[0]; 
    const GLchar** fragment_shader_strings = &ptr_fragment_shader_string; 
    int fragment_shader_lengths[] = {(int)fragment_shader_string.length()}; 
    glShaderSource(fragment_shader, 1, fragment_shader_strings, fragment_shader_lengths); 
    glCompileShader(fragment_shader); 
    glAttachShader(shader_program, fragment_shader); 

    glBindAttribLocation(shader_program, 0, "position"); 
    glBindAttribLocation(shader_program, 1, "colour"); 
    glLinkProgram(shader_program); 
    glUseProgram(shader_program); 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // Run the main loop 
    glutMainLoop(); 
} 

........ 
........ 
........ 

// Vertex shader 
#version 330 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 colour; 
out vec4 frag_colour; 

void main() 
{ 
    gl_Position = vec4(position, 1.0); 
    frag_colour = vec4(colour, 1.0); 
} 

........ 
........ 
........ 

// Fragment shader 
#version 330 
in vec4 frag_colour; 

void main() 
{ 
    gl_FragColor = frag_colour; 
} 

回答

3

glEnableVertexAttribArray必須要求每個VAO:

// Fill the buffer data 
glBindVertexArray(object1_vertex_array); 
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_vertices), &object1_vertices[0], GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glBindBuffer(GL_ARRAY_BUFFER, object1_colour_buffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_colours), &object1_colours[0], GL_STATIC_DRAW); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object1_indices[0], GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glEnableVertexAttribArray(1); 

glBindVertexArray(object2_vertex_array); 
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_vertices), &object2_vertices[0], GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glBindBuffer(GL_ARRAY_BUFFER, object2_colour_buffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_colours), &object2_colours[0], GL_STATIC_DRAW); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object2_indices[0], GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glEnableVertexAttribArray(1); 
相關問題