OpenGL Primitives

We will be looking at the components of OpenGL and how to set it up later on. First we will look at the core of OpenGL, which is drawing.

OpenGL provides 10 low-level drawing primitives for drawing points, lines, triangles and polygons. All the primitives are described as a list of vertices.

Drawing a Primitive

To draw a primitive, tell OpenGL which primitive you want to draw using the function glBegin(...), then specify a list of vertices for the primitive, and finally use glEnd(). In the following example, a triangle is drawn in the current colour.

 

	glBegin(GL_TRIANGLES); // draw a triangle
		
		glVertex2d(100.0d,0.0,); //specify a point
		glVertex2d(0.0d,1.0d); //specify a point
		glVertex2d(0.0d,100.0d); //specify a point
	
	glEnd(); //Trangle finished  

Primitives

OpenGL Primitive types

 

The constant passed to glBegin(...) determines the type of primitive drawn. The following constants are available;

GL_POINTS Treats each vertex as a single point. Vertex n defines point n. N points are drawn.

GL_LINES Treates each pair of vertices as an independent line segment. Vertices 2n-1 and 2n define line n. N/2 lines are drawn.

GL_LINE_STRIP
Draws a connected group of line segments from the first vertex to the last. Vertices n and n+1 define line n. N-1 lines drawn.

GL_LINE_LOOP
Draws a connected group of line segments from the first vertex to the last, then back to the first. Vertices n and n+1 define line n. The last line, however, is defined by vertices N and 1. N lines are drawn.

GL_TRIANGLES
Treates each triplet of vertices as an independent triangle. Vertices 3n-2, 3n-1, and 3n define triangle n. N/3 triangles are drawn.

GL_TRIANGLE_STRIP
Draws a connected group of triangles. One triangle is defined for each vertex presented after the first two vertices. For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.

GL_TRIANGLE_FAN
Draws a connected group of triangles. One triangle is defined for each vertex presented after the first two vertices. Vertices 1, n+1, and n+2 define triangle n. N-2 triangles are drawn.

GL_QUADS Treats each group of four vertices as an independent quadrilateral. Vertices 4n-3, 4n-2, 4n-1, and 4n define quadrilateral n. N/4 quadrilaterals are drawn.

GL_QUAD_STRIP
Draws a connected group of quadrilaterals. One quadrilateral is defined for each pair of vertices presented after the first pair. Vertices 2n-1, 2n, 2n+2, and 2n+1 define quadrilateral n. N/2-1 quadrilaterals are drawn. Note that the order in which vertices are used to construct a quadrilateral from strip data is different from that used with independent data.

GL_POLYGON
Draws a single, convex polygon. Vertices 1 through N define this polygon.


Suffixes

Note; many OpenGL functions ahve several different versions, to take different sort of parameters. e.g the function glVertex3f(...) has a suffix "3f", indicating that this function takes 3 floating point parameters. Similarly the function glVertex2i(...) will take 2 integers. glVertex3dv(...) takes a pointer to an array of 3 doubles.

 

Example of primitives

This executable from the book "OpenGl Game Programming - K. Hawkins, D.Astle", show most of the Primitves as well as different drawing features.

To change the primitive being displayed and the properties applied to it,
use the following controls:

Key Action
--- ------
1 Draw points
2 Draw lines
3 Draw triangles
4 Draw a triangle strip
5 Draw a triangle fan
6 Draw quads
7 Draw a polygon
a Toggle antialiasing
s Toggle stippling
p Rotate through polygon modes

 

Dynamic Primitives

Primitve data does not need to be hard coded in the program. This code shows primitves being drawn based on previously computed vertex data (this executable shows the code in action)

 	glBegin(GL_LINE_STRIP); // draw a sequence of lines
		for(int i=0;i<100;i++){
			glVertex3f(x[i],y[i],z[i]); //specify a point, 
										//x[], y[] and z[] are arrays of random floats
		}
	glEnd(); 

 

In particular, primitive data can be progammatically calculated: (example executable)

 	 
	 const double PI=3.141;
	 const double r=200;
	 const int sides=20;

	glBegin(GL_TRIANGLE_FAN);
	glVertex2i(0,0);// centre
	 for(int i = 0;i>=sides;i++){
        int x= int(r*cos(i*(2*PI/sides)));        
		int y= int(r*sin(i*(2*PI/sides)));
		glVertex2i(x,y);//point on edge  
	 }
	
    glEnd();
   
for hidden surface removal, this buffer must also be cleared before drawing. Both buffers can be cleared with one function:

 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear both buffers

OpenGL manages buffering, these examples all use double buffering. The type of buffering used is specifed in the PixelFormat (more on that later). All drawing is done on the back buffer, and is therefore invisible to the user until the buffers are swapped. The buffers must be swapped after drawing each frame.