Your First Polygon

In the first tutorial I taught you how to create an OpenGL Window. In this tutorial I will teach you how to create both Triangles and Quads. We will create a triangle using GL_TRIANGLES, and a square using GL_QUADS.

Using the code from the first tutorial, we will be adding to the DrawGLScene() procedure. I will rewrite the entire procedure below. If you plan to modify the last lesson, you can replace the DrawGLScene() procedure with the code below, or just add the lines of code below that do not exist in the last tutorial.

int DrawGLScene(GLvoid)							// Here's Where We Do All The Drawing
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
	glLoadIdentity();						// Reset The View

When you do a glLoadIdentity() what you are doing is moving back to the center of the screen with the X axis running left to right, the Y axis moving up and down, and the Z axis moving into, and out of the screen.

The center of an OpenGL screen is 0.0f on the X and Y axis. To the left of center would be a negative number. To the right would be a positive number. Moving towards the top of the screen would be a positive number, moving to the bottom of the screen would be a negative number. Moving deeper into the screen is a negative number, moving towards the viewer would be a positive number.

glTranslatef(x, y, z) moves along the X, Y and Z axis, in that order. The line of code below moves left on the X axis 1.5 units. It does not move on the Y axis at all (0.0), and it moves into the screen 6.0 units. When you translate, you are not moving a set amount from the center of the screen, you are moving a set amount from wherever you currently were on the screen.

	glTranslatef(-1.5f,0.0f,-6.0f);					// Move Left 1.5 Units And Into The Screen 6.0

Now that we have moved to the left half of the screen, and we've set the view deep enough into the screen (-6.0) that we can see our entire scene we will create the Triangle. glBegin(GL_TRIANGLES) means we want to start drawing a triangle, and glEnd() tells OpenGL we are done creating the triangle. Typically if you want 3 points, use GL_TRIANGLES. Drawing triangles is fairly fast on most video cards. If you want 4 points use GL_QUADS to make life easier. From what I've heard, most video cards render objects as triangles anyways. Finally if you want more than 4 points, use GL_POLYGON.

In our simple program, we draw just one triangle. If we wanted to draw a second triangle, we could include another 3 lines of code (3 points) right after the first three. All six lines of code would be between glBegin(GL_TRIANGLES) and glEnd(). There's no point in putting a glBegin(GL_TRIANGLES) and a glEnd() around every group of 3 points. This applies to quads as well. If you know you're drawing all quads, you can include the second group of four lines of code right after the first four lines. A polygon on the other hand (GL_POLYGON) can be made up of any amount of point so it doesn't matter how many lines you have between glBegin(GL_POLYGON) and glEnd().

The first line after glBegin, sets the first point of our polygon. The first number of glVertex is for the X axis, the second number is for the Y axis, and the third number is for the Z axis. So in the first line, we don't move on the X axis. We move up one unit on the Y axis, and we don't move on the Z axis. This gives us the top point of the triangle. The second glVertex moves left one unit on the X axis and down one unit on the Y axis. This gives us the bottom left point of the triangle. The third glVertex moves right one unit, and down one unit. This gives us the bottom right point of the triangle. glEnd() tells OpenGL there are no more points. The filled triangle will be displayed.

	glBegin(GL_TRIANGLES);						// Drawing Using Triangles
		glVertex3f( 0.0f, 1.0f, 0.0f);				// Top
		glVertex3f(-1.0f,-1.0f, 0.0f);				// Bottom Left
		glVertex3f( 1.0f,-1.0f, 0.0f);				// Bottom Right
	glEnd();							// Finished Drawing The Triangle

Now that we have the triangle displayed on the left half of the screen, we need to move to the right half of the screen to display the square. In order to do this we use glTranslate again. This time we must move to the right, so X must be a positive value. Because we've already moved left 1.5 units, to get to the center we have to move right 1.5 units. After we reach the center we have to move another 1.5 units to the right of center. So in total we need to move 3.0 units to the right.

	glTranslatef(3.0f,0.0f,0.0f);					// Move Right 3 Units

Now we create the square. We'll do this using GL_QUADS. A quad is basically a 4 sided polygon. Perfect for making a square. The code for creating a square is very similar to the code we used to create a triangle. The only difference is the use of GL_QUADS instead of GL_TRIANGLES, and an extra glVertex3f for the 4th point of the square. We'll draw the square top left, top right, bottom right, bottom left (clockwise). By drawing in a clockwise order, the square will be drawn as a back face. Meaning the side of the quad we see is actually the back. Objects drawn in a counter clockwise order will be facing us. Not important at the moment, but later on you will need to know this.

	glBegin(GL_QUADS);						// Draw A Quad
		glVertex3f(-1.0f, 1.0f, 0.0f);				// Top Left
		glVertex3f( 1.0f, 1.0f, 0.0f);				// Top Right
		glVertex3f( 1.0f,-1.0f, 0.0f);				// Bottom Right
		glVertex3f(-1.0f,-1.0f, 0.0f);				// Bottom Left
	glEnd();							// Done Drawing The Quad
	return TRUE;							// Keep Going
}

Finally change the code to toggle window / fullscreen mode so that the title at the top of the window is proper.

Make sure you also change the title under // Create Our OpenGL Window (just above this code). Otherwise the 'fullscreen' Window will have a different title than the 'windowed mode' title.

			if (keys[VK_F1])				// Is F1 Being Pressed?
			{
				keys[VK_F1]=FALSE;			// If So Make Key FALSE
				KillGLWindow();				// Kill Our Current Window
				fullscreen=!fullscreen;			// Toggle Fullscreen / Windowed Mode
				// Recreate Our OpenGL Window ( Modified )
				if (!CreateGLWindow("NeHe's First Polygon Tutorial",640,480,16,fullscreen))
				{
					return 0;			// Quit If Window Was Not Created
				}
			}

Markus Knauer Adds: In the book ("OpenGL Programming Guide: The Official Guide to Learning OpenGL, Release 1", J. Neider, T. Davis, M. Woo, Addison-Wesley, 1993) the following paragraph will clearly explain what NeHe means when he refers to movement by units in OpenGL:

"[I mentioned] inches and millimeters - do these really have anything to do with OpenGL? The answer is, in a word, no. The projection and other transformations are inheritly unitless. If you want to think of the near and far clipping planes as located at 1.0 and 20.0 meters, inches, kilometers, or leagues, it's up to you. The only rule is that you have to use consistent unit of measurement."

In this tutorial I have tried to explain in as much detail, every step involved in drawing polygons, and quads on the screen using OpenGL. If you have comments or questions please email me. If you feel I have incorrectly commented something or that the code could be done better in some sections, please let me know. I want to make the best OpenGL tutorials I can. I'm interested in hearing your feedback.

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD ASM Code For This Lesson. ( Conversion by Foolman )
* DOWNLOAD Borland C++ Builder 6 Code For This Lesson. ( Conversion by Christian Kindahl )
* DOWNLOAD BeOS Code For This Lesson. ( Conversion by Rene Manqueros )
* DOWNLOAD C# Code For This Lesson. ( Conversion by Joachim Rohde )
* DOWNLOAD VB.Net CsGL Code For This Lesson. ( Conversion by X )
* DOWNLOAD Code Warrior 5.3 Code For This Lesson. ( Conversion by Scott Lupton )
* DOWNLOAD Cygwin Code For This Lesson. ( Conversion by Stephan Ferraro )
* DOWNLOAD D Language Code For This Lesson. ( Conversion by Familia Pineda Garcia )
* DOWNLOAD Delphi Code For This Lesson. ( Conversion by Michal Tucek )
* DOWNLOAD Dev C++ Code For This Lesson. ( Conversion by Dan )
* DOWNLOAD Game GLUT Code For This Lesson. ( Conversion by Milikas Anastasios )
* DOWNLOAD GLUT Code For This Lesson. ( Conversion by Andy Restad )
* DOWNLOAD Irix Code For This Lesson. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Java Code For This Lesson. ( Conversion by Jeff Kirby )
* DOWNLOAD Java/SWT Code For This Lesson. ( Conversion by Victor Gonzalez )
* DOWNLOAD Jedi-SDL Code For This Lesson. ( Conversion by Dominique Louis )
* DOWNLOAD JoGL Code For This Lesson. ( Conversion by Kevin J. Duling )
* DOWNLOAD LCC Win32 Code For This Lesson. ( Conversion by Robert Wishlaw )
* DOWNLOAD Linux Code For This Lesson. ( Conversion by Richard Campbell )
* DOWNLOAD Linux/GLX Code For This Lesson. ( Conversion by Mihael Vrbanec )
* DOWNLOAD Linux/SDL Code For This Lesson. ( Conversion by Ti Leggett )
* DOWNLOAD LWJGL Code For This Lesson. ( Conversion by Mark Bernard )
* DOWNLOAD Mac OS Code For This Lesson. ( Conversion by Anthony Parker )
* DOWNLOAD Mac OS X/Cocoa Code For This Lesson. ( Conversion by Bryan Blackburn )
* DOWNLOAD MASM Code For This Lesson. ( Conversion by Nico (Scalp) )
* DOWNLOAD Power Basic Code For This Lesson. ( Conversion by Angus Law )
* DOWNLOAD Pelles C Code For This Lesson. ( Conversion by Pelle Orinius )
* DOWNLOAD Perl Code For This Lesson. ( Conversion by Cora Hussey )
* DOWNLOAD Python Code For This Lesson. ( Conversion by Travis Wells )
* DOWNLOAD QT/C++ Code For This Lesson. ( Conversion by Popeanga Marian )
* DOWNLOAD REALbasic Code For This Lesson. ( Conversion by Thomas J. Cunningham )
* DOWNLOAD Ruby Code For This Lesson. ( Conversion by Ben Goodspeed )
* DOWNLOAD Scheme Code For This Lesson. ( Conversion by Jon DuBois )
* DOWNLOAD Solaris Code For This Lesson. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Visual Basic Code For This Lesson. ( Conversion by Ross Dawson )
* DOWNLOAD Visual Fortran Code For This Lesson. ( Conversion by Jean-Philippe Perois )
* DOWNLOAD Visual Studio .NET Code For This Lesson. ( Conversion by Grant James )

 

< Lesson 01Lesson 03 >