这是我目前正在尝试的...
变量初始化:
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));
初始化缓冲区:
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 个点和一条线