Each face needs 6 times of glVertex*() calls to make 2 triangles, for example, the front face has v0-v1-v2 and v2-v3-v0 triangles. A cube has 6 faces, so the total number of glVertex*() calls is 36. If you also specify normals, texture coordinates and colors to the corresponding vertices, it increases the number of OpenGL function calls.
The other thing that you should notice is the vertex "v0" is shared with 3 adjacent faces; front, right and top face. In immediate mode, you have to provide this shared vertex 6 times, twice for each side as shown in the code.
glBegin(GL_TRIANGLES); // draw a cube with 12 triangles
// front face =================
glVertex3fv(v0); // v0-v1-v2
glVertex3fv(v1);
glVertex3fv(v2);
glVertex3fv(v2); // v2-v3-v0
glVertex3fv(v3);
glVertex3fv(v0);
// right face =================
glVertex3fv(v0); // v0-v3-v4
glVertex3fv(v3);
glVertex3fv(v4);
glVertex3fv(v4); // v4-v5-v0
glVertex3fv(v5);
glVertex3fv(v0);
// top face ===================
glVertex3fv(v0); // v0-v5-v6
glVertex3fv(v5);
glVertex3fv(v6);
glVertex3fv(v6); // v6-v1-v0
glVertex3fv(v1);
glVertex3fv(v0);
... // draw other 3 faces
glEnd();
Using vertex arrays reduces the number of function calls and redundant
usage of shared vertices. Therefore, you may increase the performance of
rendering. Here, 3 different OpenGL functions are explained to use
vertex arrays; glDrawArrays(), glDrawElements() and glDrawRangeElements().
Initialization
OpenGL provides glEnableClientState() and glDisableClientState() functions to activate and deactivate 6 different types of arrays. Plus, there are 6 functions to specify the exact positions(addresses) of arrays, so, OpenGL can access the arrays in your application.- glVertexPointer(): specify pointer to vertex coords array
- glNormalPointer(): specify pointer to normal array
- glColorPointer(): specify pointer to RGB color array
- glIndexPointer(): specify pointer to indexed color array
- glTexCoordPointer(): specify pointer to texture cords array
- glEdgeFlagPointer(): specify pointer to edge flag array
glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
- size: The number of vertex coordinates, 2 for 2D points, 3 for 3D points.
- type: GL_FLOAT, GL_SHORT, GL_INT or GL_DOUBLE.
- stride: The number of bytes to offset to the next vertex (used for interleaved array).
- pointer: The pointer to the vertex array.
glNormalPointer(GLenum type, GLsizei stride, const GLvoid* pointer)
- type: GL_FLOAT, GL_SHORT, GL_INT or GL_DOUBLE.
- stride: The number of bytes to offset to the next normal (used for interleaved array).
- pointer: The pointer to the vertex array.
glDrawArrays()
glDrawArrays() reads vertex data from the enabled arrays by marching straight through the array without skipping or hopping. Because glDrawArrays() does not allows hopping around the vertex arrays, you still have to repeat the shared vertices once per face.glDrawArrays() takes 3 arguments. The first thing is the primitive type. The second parameter is the starting offset of the array. The last parameter is the number of vertices to pass to rendering pipeline of OpenGL.
For above example to draw a cube, the first parameter is GL_TRIANGLES, the second is 0, which means starting from beginning of the array. And the last parameter is 36: a cube has 6 sides and each side needs 6 vertices to draw 2 triangles, 6 × 6 = 36.
GLfloat vertices[] = {...}; // 36 of vertex coords
...
// activate and specify pointer to vertex array
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
// draw a cube
glDrawArrays(GL_TRIANGLES, 0, 36);
// deactivate vertex arrays after drawing
glDisableClientState(GL_VERTEX_ARRAY);
As a result of using glDrawArrays(), you can replace 36 glVertex*() calls with a single glDrawArrays() call. However, we still need to duplicate the shared vertices, so the number of vertices defined in the array is still 36 instead of 8. glDrawElements() is the solution to reduce the number of vertices in the array, so it allows transferring less data to OpenGL.
to be continued ....
No comments:
Post a Comment