你如何渲染多个VBO / IBO?

时间:2013-06-26 19:06:50

标签: opengl graphics

这是我目前正在尝试的......

变量初始化:

GLuint vertexbuffer;
GLuint uvbuffer;
GLuint normalbuffer;
GLuint colorbuffer;
GLuint elementbuffer;
GLuint VertexArrayID;

std::vector<unsigned short> indices;
std::vector<glm::vec3> indexed_vertices;
std::vector<glm::vec2> indexed_uvs;
std::vector<glm::vec3> indexed_normals;
std::vector<glm::vec4> indexed_colors;


GLuint vertexbuffer2;
GLuint uvbuffer2;
GLuint normalbuffer2;
GLuint colorbuffer2;
GLuint elementbuffer2;
GLuint VertexArrayID2;

std::vector<unsigned short> indices2;
std::vector<glm::vec3> indexed_vertices2;
std::vector<glm::vec2> indexed_uvs2;
std::vector<glm::vec3> indexed_normals2;
std::vector<glm::vec4> indexed_colors2;

struct PackedVertex{
    glm::vec3 position;
    glm::vec2 uv;
    glm::vec3 normal;
    glm::vec4 color;
    bool operator<(const PackedVertex that) const{
        return memcmp((void*)this, (void*)&that, sizeof(PackedVertex))>0;
    };
};

std::vector<glm::vec3>  in_vertices;
std::vector<glm::vec2>  in_uvs;
std::vector<glm::vec3>  in_normals;
std::vector<glm::vec4>  in_colors;

in_vertices.push_back(glm::vec3(0,0,0));
in_vertices.push_back(glm::vec3(1,0,0));
in_uvs.push_back(glm::vec2(0,0));
in_uvs.push_back(glm::vec2(0,0));

in_normals.push_back(glm::vec3(0,1,0));
in_normals.push_back(glm::vec3(0,1,0));
in_colors.push_back(glm::vec4(1,1,1,1));
in_colors.push_back(glm::vec4(1,0,0,1));


std::vector<glm::vec3>  in_vertices2;
std::vector<glm::vec2>  in_uvs2;
std::vector<glm::vec3>  in_normals2;
std::vector<glm::vec4>  in_colors2;


in_vertices2.push_back(glm::vec3(0,1.3,0));
in_vertices2.push_back(glm::vec3(1,1.3,0));

in_uvs2.push_back(glm::vec2(0,0));
in_uvs2.push_back(glm::vec2(0,0));

in_normals2.push_back(glm::vec3(0,1,0));
in_normals.push_back(glm::vec3(0,1,0));

in_colors2.push_back(glm::vec4(0,0,1,1));
in_colors2.push_back(glm::vec4(0,0,1,1));

Intit the buffers:

void InitializeVertexBuffer(GLuint &theBuffer, GLenum target,  GLenum usage, const void* data,  int size)
{
    glGenBuffers(1, &theBuffer);
    glBindBuffer(target, theBuffer);
    glBufferData(target, size, data, usage);
    glBindBuffer(target, 0);
}

设置IBO / VAO / VBO:

// For each input vertex
for ( unsigned int i=0; i<2; i++ ){

    // Try to find a similar vertex in out_XXXX
    unsigned short index;
    bool found = getSimilarVertexIndex(in_vertices[i], in_uvs[i], in_normals[i],     indexed_vertices, indexed_uvs, indexed_normals, index);

    if ( found ){ // A similar vertex is already in the VBO, use it instead !
        indices.push_back( index );
    }else{ // If not, it needs to be added in the output data.
        indexed_vertices.push_back( in_vertices[i]);
        indexed_uvs     .push_back( in_uvs[i]);
        indexed_normals .push_back( in_normals[i]);
        indexed_colors .push_back( in_colors[i]);
        indices .push_back( (unsigned short)indexed_vertices.size() - 1 );
    }
}



    size_t colorDataOffset = 0;
InitializeVertexBuffer(vertexbuffer, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_vertices[0], indexed_vertices.size() * sizeof(glm::vec3)  );
InitializeVertexBuffer(uvbuffer, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_vertices[0], indexed_vertices.size() * sizeof(glm::vec2)  );
InitializeVertexBuffer(normalbuffer, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_normals[0], indexed_normals.size() * sizeof(glm::vec3)  );
InitializeVertexBuffer(colorbuffer, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_colors[0], indexed_colors.size() * sizeof(glm::vec4)  );
InitializeVertexBuffer(elementbuffer, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indices[0], indices.size() * sizeof(unsigned short)  );

//Generate VAO
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// 2nd attribute buffer : normals
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// 3nd attribute buffer : UVs
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// 4th attribute buffer : colors
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);   


//****Second one*****//

        // For each input vertex
    for ( unsigned int i=0; i<2; i++ ){

        // Try to find a similar vertex in out_XXXX
        unsigned short index;
        bool found = getSimilarVertexIndex(in_vertices2[i], in_uvs2[i], in_normals2[i],     indexed_vertices2, indexed_uvs2, indexed_normals2, index);

        if ( found ){ // A similar vertex is already in the VBO, use it instead !
            indices2.push_back( index );
        }else{ // If not, it needs to be added in the output data.
            indexed_vertices2.push_back( in_vertices2[i]);
            indexed_uvs2     .push_back( in_uvs2[i]);
            indexed_normals2 .push_back( in_normals[i]);
            indexed_colors2 .push_back( in_colors2[i]);
            indices2.push_back( (unsigned short)indexed_vertices2.size() - 1 );
        }
    }

size_t colorDataOffset = 0;
InitializeVertexBuffer(vertexbuffer2, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_vertices2[0], indexed_vertices2.size() * sizeof(glm::vec3)   );
InitializeVertexBuffer(uvbuffer2, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_vertices2[0], indexed_vertices2.size() * sizeof(glm::vec2)  );
InitializeVertexBuffer(normalbuffer2, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_normals2[0], indexed_normals2.size() * sizeof(glm::vec3)  );
InitializeVertexBuffer(colorbuffer2, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indexed_colors2[0], indexed_colors2.size() * sizeof(glm::vec4)  );
InitializeVertexBuffer(elementbuffer2, GL_ARRAY_BUFFER, GL_STATIC_DRAW, &indices2[0], indices2.size() * sizeof(unsigned short)  );

//Generate VAO
glGenVertexArrays(1, &VertexArrayID2);
glBindVertexArray(VertexArrayID2);


    // 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0  );

// 2nd attribute buffer : normals
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer2);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// 3nd attribute buffer : UVs
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// 4th attribute buffer : colors
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer2);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, (void*)0 );

// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer2);              

现在画画

do{
glUseProgram(programID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
// Draw the primatives !
glDrawElements(GL_POINTS, 2, GL_UNSIGNED_SHORT, (void*)0);


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer2);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, (void*)0);

glUseProgram(0); 
glfwSwapBuffers();
..}

因此当我启动第二个VBO时,我只得到2个蓝点而不是2个点和一行

1 个答案:

答案 0 :(得分:1)

这是因为您必须重新定义顶点属性数组。在通过glVertexAttribPointer()设置缓冲区布局后,必须直接绘制elementbuffer

基本示例(缩短以防止另一面代码墙):

//draw the points
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

//set up other buffers that belong to your point-setup

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glDrawElements(GL_POINTS, 2, GL_UNSIGNED_SHORT, (void*)0);

//draw the lines
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

//set up other buffers that belong to your line-setup

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer2);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, (void*)0);

当您进行glDrawElements()来电时,会从glVertexAttribPointer()设置的地址中读取数据,因此您每次进行抽奖前都必须通过glVertexAttribPointer()设置指针-call(除非你想从同一个VBO中绘制相同的东西或不同的东西)。