I’m working in a 3D project. But I’m not very well in OpenGL.
Some one give me a structure of a building, and I have to draw it in 3D.
A building includes a footprint, a height and latitude. So a building looks like a box 3D, some things likes this (please view the image). A building can have more than 4 vertex:
He gives me a building class looks like this (I have removed some data) and he said that I should use the glDrawElements function. This is the building class code (please read the cpp file):
I have used the glDrawElements function like this :
[b]
glEnableClientState ( GL_VERTEX_ARRAY );
int nbVertices = pbuilding->getData()->GetWallVerticesCount();
GLfloat *vertices = pbuilding->getData()->GLWallVertices();
glVertexPointer( 3, GL_FLOAT, 0, vertices );
int n = pbuilding->getData()->getNbRings();
unsigned int* pn = pbuilding->getData()->GetWallIndicesCount();
unsigned int** indices = pbuilding->getData()->GLWallIndices();
for (int i=0; i<n; ++i){
if (n == 0)
glDrawElements(GL_TRIANGLES, pn[i], GL_UNSIGNED_SHORT, (GLvoid*)indices[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
[/b]
[/b][/QUOTE]
But it does not run, the programme was crashed when it start to draw.
Does any one can tell how to can I draw this building?
Thanks so much,
First: In your source file, your indices array (unsigned int** m_WallIndices;) is of type unsigned int and when you use glDrawElements you use GL_UNSIGNED_SHORT. It should be GL_UNSIGNED_INT.
Second: In your for loop glDrawElements will never be called. If n == 0 the for loop will terminate immediately because of i < n. If n > 0 the for loop will iterate n times but n != 0, so the loop do nothing at all. This tell me that your program don’t crash when drawing.
Third: In your source file I see
// wall vertices:
// 4 points per wall
// 8 value per point: 2 texture coordinates + (x,y,z) coordinates, + normal coordinates computed later
m_WallVertices = new float [m_nbWallVertices * 8 * 4];
Your m_WallVertices array is interleaved with other data so
glVertexPointer( 3, GL_FLOAT, 0, vertices ); should be something like glVertexPointer( 3, GL_FLOAT, 8*sizeof(GL_FLOAT), &vertices[2] );
Look at the references pages for glVertexPointer and glDrawElements documentation.
First: I have changed as you said.
Second: n == 0 is only for testing :), I have removed.
Third: Could you please explain more detail? I need to starting at 0, so why we need to change to glVertexPointer( 3, GL_FLOAT, 8*sizeof(GL_FLOAT), &vertices[2] ) ?
For glVertexPointer, I noticed in your building.cpp file that the m_WallVertices array contain for each vertex a 2 dimensions texture coordinate + a normal. I have supposed that pbuilding->getData()->GLWallVertices() function call return the m_WallVertices array. So in memory the array will look like this:
m_WallVertices[0] = texture coordinate u for vertex 0
m_WallVertices[1] = texture coordinate v for vertex 0
m_WallVertices[2] = vertex position x for vertex 0
m_WallVertices[3] = vertex position y for vertex 0
m_WallVertices[4] = vertex position z for vertex 0
m_WallVertices[5] = vertex normal x for vertex 0
m_WallVertices[6] = vertex normal y for vertex 0
m_WallVertices[7] = vertex normal z for vertex 0
m_WallVertices[8] = texture coordinate u for vertex 1
…
m_WallVertices[10] = vertex position x for vertex 1
…
m_WallVertices[13] = vertex normal x for vertex 1
…
So with this array layout you have to tell OpenGL that your vertex position data begin at address &vertices[2] and you have to jump 8sizeof(GL_FLOAT) bytes to get the next vertex position data.If you use texturing, to tell OpenGL where the texture coordinate data is you need to call glTexCoorPointer(2,GL_FLOAT,8sizeof(GL_FLOAT),&vertices[0]).If you use OpenGL lighting you need to call glNormalPointer(GL_FLOAT,8*sizeof(GL_FLOAT),&vertices[5]).
After checking the code again it seems that the comment is misleading about the order of data for vertex position and normal. So glVertexPointer(3, GL_FLOAT, 8sizeof(GL_FLOAT),&vertices[5]) <=> glNormalPointer(GL_FLOAT,8sizeof(GL_FLOAT),&vertices[2]).
He gives me a building class
Ask your project coordinator for the exact layout of data for m_WallVertices array if you cannot find it yourself.