我正在尝试使用四边形贴片来近似曲面。我使用 GL_QUADS 直接渲染并指定四边形补丁的四个顶点。
现在我正在尝试使用顶点缓冲区和顶点和法线的覆盖数组(verNor)来获得一些性能。问题是我得到了一些随机的形状,但不是我之前得到的正确形状。
我在这里放我的代码:
GLenum err = glewInit();
if (GLEW_OK != err){
std::cout<<"Filed to Initialize GLEW :: "<<glewGetErrorString(err)<<std::endl;
}
verNor = new GLfloat [NA*NP*6]; // NA and NP are number of points in lets say x and y axis
indices = new GLuint [(NA)*(NP)*4]; // When the tube is cut an spread out.
// VBOs
glGenBuffers(1, &vbo_tube); // Ask the GPU driver for a buffer array. "vbo" now has the ID
glGenBuffers(1, &ibo_indices);
// For Vertices and Normals which are interleved
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6*NA*NP, NULL, GL_STATIC_DRAW);
// Obtaining the pointer to the memory in graphics buffer
buffer_verNor = glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
// For Indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 4*(NA-1)*(NP-1), NULL, GL_STATIC_DRAW);
buffer_indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER,GL_WRITE_ONLY);
// Calculate the vertices of the points around the tube. Correctness guarenteed because I can draw exactly what I wanted
// using normal stright forward GL_QUADS that is drawing quad by quad and with out any VBOs
// Calculated vertices are stored in vPoints.
for (int i=0; i<NP; i++) {
for (int j=0; j<NA; j++) {
// Calculate the normals of each and every point above and store them in v3
// Storing the vertices
verNor[6*( (i)*NA+(j) )+0] = (GLfloat)vPoints[i*NA+j].GetX();
verNor[6*( (i)*NA+(j) )+1] = (GLfloat)vPoints[i*NA+j].GetY();
verNor[6*( (i)*NA+(j) )+2] = (GLfloat)vPoints[i*NA+j].GetZ();
// Storing the Normals
verNor[6*((i-1)*NA+(j-1))+3] = (GLfloat)v3.GetX();
verNor[6*((i-1)*NA+(j-1))+4] = (GLfloat)v3.GetY();
verNor[6*((i-1)*NA+(j-1))+5] = (GLfloat)v3.GetZ();
// Calculating the indices which form the quad
indices[4*((i)*NA+(j))+0] = (GLuint) (i)*NA+j ;
indices[4*((i)*NA+(j))+1] = (GLuint) (i+1)*NA+j ;
indices[4*((i)*NA+(j))+2] = (GLuint) (i+1)*NA+j+1 ;
indices[4*((i)*NA+(j))+3] = (GLuint) (i)*NA+j+1 ;
}
}
memcpy(buffer_verNor, verNor, 6*(NA)*(NP));
glUnmapBuffer(GL_ARRAY_BUFFER); // Unmapping the buffer
memcpy(buffer_indices, indices, 4*(NA-1)*(NP-1));
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glEnable(GL_LIGHTING);
// Performing the Vertex Buffer Stuff
// For Vertices and Normals
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glVertexPointer( 3, GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)((char*)NULL + 0*sizeof(GLfloat)) );
glNormalPointer( GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)(((char*)NULL)+3*sizeof(GLfloat)) );
// For Indices
// Mapping the indices_vbo memory here
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*4*(NA-1)*(NP-1), indices, GL_STATIC_DRAW);
// Enabling all the buffers and drawing the quad patches
glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
// Enabling normals and vertices to draw
glEnableClientState (GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// Drawing the patches
glDrawElements(GL_QUADS, (NA-1)*(NP-1), GL_UNSIGNED_INT,(GLvoid*)((char*)NULL));
// Disabling the buffer objects for safety
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDeleteBuffers(1, &vbo_tube);
glDeleteBuffers(1, &ibo_indices);
网格有 NP 点的 NA,所以我必须绘制 (NP-1)*(NA-1) 四边形。此外,只有当我在 glVertexPointer() 和 glNormalPointer() 函数中给出错误的偏移量和步幅时,我才能得到一些东西(但不正确)。我认为正确的是 vertexPointer :: Stride - 6*sizeof(GLfloat) , offset - 0(last argument) normalPointer :: Stride - 6*sizeof(GLfloat) , offset - 3*sizeof(GLfloat)