How can I compute vertices on a sphere?
- How to compute vertices on a sphere (basic maths pracice)
- How to use vertex arrays
Of course there is a glut command for rendering spheres. But there are two disadvantages: What GLUT does is not the fastest way and you cannot specify different colors for the vertices. And what I did in this tutorial is also not possible with glutWireSphere(): You cannot move certain points up and down. So it is necessary to compute the vertices our own. To do this, you can use several circles ( in the x-z-plane), each with another radius and y-value. The highest and lowest circles have a radius of zero, so we can say, it is only one vertex. Let's use a counter i that counts from zero to the number of circles - 3: minus two because two "circles" aren't circles, and minus one because we start counting at zero. The first thing is to think of the radius of the sphere: one is the easiest, if you want to draw bigger or smaller spheres you call glScale(). We now need the radius of each circle. Note that the beginning vertices of each circle lie on an arc (180°) with the radius of the sphere. The distance of those vertices is not the same, only the y-value-distance. Finally, the formula is r = sin ( acos (yValueOfCircle)); Now it is quite easy to compute the vertices: You have the y-value and the radius of the circle, that is parallel to the x-z-plane. You need a second counter, which you use to compute the angle, and then just use sin() and cos(). That's it.
How can I use vertex arrays?
First of all an explanation, what vertex arrays are: The more values you specify per vertex (position, color, normal vector...) the more calls you need. This means time, and so calling several gl* -calls is quite inefficient. So vertex arrays help you to need less calls. You pass a pointer to your vertex data (which must be in the right format) to OpenGL and then you can decide, which ones of these vertices shall be rendered and how. Another advantage is possible, when vertices are used in several polygons (this happens very often): Some implementaitions might cache the rendered vertices and wouldn't have to rerender them in the next polygon. As you see, vertex arrays can greatly improve rendering speed. There are several possibilites to tell OpenGL which vertices shall be rendered. In this example I use glDrawElements(). This means, I create an "index"-array. Here I store, which vertices shall be rendered. One vertex appears probably more than once in this array, because it is part of several polygons. To dereference a single vertex you call glArrayElement() , to dereference a sequence of vertices you call glDrawArrays().
Ok now, the only two things now you haven't heard yet is how to turn on the vertex array functionality and how to pass the data pointers. First you have to enable each array, this is done by glEnableClientState(). You can use GL_VERTEX_ARRAY, GL_NORMAL_ARRAY; GL_COLOR_ARRAY, GL_INDEX_ARRAY (this means color indices, not the vertex indices I mentioned before), GL_TEXTURE_COORD_ARRAY or GL_EDGE_FLAG_ARRAY as parameter.
Then you call glVertexPointer / glNormalPointer / glColorPointer / glIndexPointer / glTexCoordPointer / glEdgeFlagPointer. The first parameter tells OpenGL, how many components there are per vertex. For example you would use 2 for 2d-vertices, 3 for 3d-vertices and 4 for 4d-vertices in glVertexPointer. The second parameter specifies the data type (values could be GL_BYTE, GL_INT, GL_FLOAT and so on).The third one is used, when your data is not tightly packed. This is case, if you use a "vertex"-struct, where several values for a vertex (position and normal vector, for example) are stored. Then you pass the size of your vertex struct, otherwise you take zero. The last parameter is a pointer to the data.
That's all, look here to see how I realized this tutorial.
Any comments? Conact me!