# Drawing in Space: Geometric Primitives and Buffers in OpenGL

• Print
This chapter is from the book

## Draw Something!

Now, we have a way of specifying a point in space to OpenGL. What can we make of it, and how do we tell OpenGL what to do with it? Is this vertex a point that should just be plotted? Is it the endpoint of a line or the corner of a cube? The geometric definition of a vertex is not just a point in space, but rather the point at which an intersection of two lines or curves occurs. This is the essence of primitives.

A primitive is simply the interpretation of a set or list of vertices into some shape drawn on the screen. There are 10 primitives in OpenGL, from a simple point drawn in space to a closed polygon of any number of sides. One way to draw primitives is to use the glBegin command to tell OpenGL to begin interpreting a list of vertices as a particular primitive. You then end the list of vertices for that primitive with the glEnd command. Kind of intuitive, don't you think?

### Drawing Points

Let's begin with the first and simplest of primitives: points. Look at the following code:

```glBegin(GL_POINTS);        // Select points as the primitive
glVertex3f(0.0f, 0.0f, 0.0f);    // Specify a point
glVertex3f(50.0f, 50.0f, 50.0f);   // Specify another point
glEnd();          // Done drawing points```

The argument to glBegin, GL_POINTS, tells OpenGL that the following vertices are to be interpreted and drawn as points. Two vertices are listed here, which translates to two specific points, both of which would be drawn.

This example brings up an important point about glBegin and glEnd: You can list multiple primitives between calls as long as they are for the same primitive type. In this way, with a single glBegin/glEnd sequence, you can include as many primitives as you like. This next code segment is wasteful and will execute more slowly than the preceding code:

```glBegin(GL_POINTS);    // Specify point drawing
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();

glBegin(GL_POINTS);    // Specify another point
glVertex3f(50.0f, 50.0f, 50.0f);
glEnd()```

In the foregoing examples, did you notice the indenting style used for the calls to glVertex? Most OpenGL programmers use this convention to make the code easier to read. It is not required, but it does make finding where primitives start and stop easier.

#### Our First Example

The code in Listing 3.2 draws some points in our 3D environment. It uses some simple trigonometry to draw a series of points that form a corkscrew path up the z-axis. This code is from the POINTS program, which is on the CD in the subdirectory for this chapter. All the sample programs use the framework we established in Chapter 2. Notice that in the SetupRC function, we are setting the current drawing color to green.

#### Listing 3.2 Rendering Code to Produce a Spring-Shaped Path of Points

```// Define a constant for the value of PI
#define GL_PI 3.1415f

// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
}

// Called to draw scene
void RenderScene(void)
{
GLfloat x,y,z,angle; // Storage for coordinates and angles

// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT);

// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);

// Call only once for all remaining points
glBegin(GL_POINTS);

z = -50.0f;
for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
{
x = 50.0f*sin(angle);
y = 50.0f*cos(angle);

// Specify the point and move the Z value up a little
glVertex3f(x, y, z);
z += 0.5f;
}

// Done drawing points
glEnd();

// Restore transformations
glPopMatrix();

// Flush drawing commands
glFlush();
}```

Only the code between calls to glBegin and glEnd is important for our purpose in this and the other examples for this chapter. This code calculates the x and y coordinates for an angle that spins between 0° and 360° three times. We express this programmatically in radians rather than degrees; if you don't know trigonometry, you can take our word for it. If you're interested, see the box "The Trigonometry of Radians/Degrees." Each time a point is drawn, the z value is increased slightly. When this program is run, all you see is a circle of points because you are initially looking directly down the z-axis. To see the effect, use the arrow keys to spin the drawing around the x- and y-axes. The effect is illustrated in Figure 3.3. Figure 3.3 Output from the POINTS sample program.

One Thing at a Time

Again, don't get too distracted by the functions in this example that we haven't covered yet (glPushMatrix, glPopMatrix, and glRotate). These functions are used to rotate the image around so you can better see the positioning of the points as they are drawn in 3D space. We cover these functions in some detail in Chapter 4. If we hadn't used these features now, you wouldn't be able to see the effects of your 3D drawings, and this and the following sample programs wouldn't be very interesting to look at. For the rest of the sample code in this chapter, we show only the code that includes the glBegin and glEnd statements. 