How to Make a Cube in OpenGL by lfsmj2010

VIEWS: 2 PAGES: 7

									How to Make a Cube in OpenGL
End ProductOpenGL is a powerful 3D programming tool used to draw complex
three-dimensional scenes from simple primitives. This article will teach
you how to draw a simple cube that you can spin to view in three
dimensions!
For this project you will need a code editor and some knowledge of C
programming.

<Steps

Part 1: Initial Setup and main()

1) Install OpenGL
To begin follow thesesteps to installing OpenGLon your system. If you
already have OpenGL and a c compiler installed you can skip this step and
go to the next.

2) Create the Document
Create a new file in your favorite code editor and save it as mycube.c

3) #includes
These are the basic includes we will need for our program. It is
important to realize that there are actually different includes required
for the different operating systems. Be sure to include all of these to
ensure your program is versatile and can run for any user.//
Includes#include <stdio.h>#include <stdarg.h>#include <math.h>#define
GL_GLEXT_PROTOTYPES#ifdef __APPLE__#include <GLUT/glut.h>#else#include
<GL/glut.h>#endif


4) Function Prototypes and Global Variables
Our next step is to declare some function prototypes.// Function
Prototypesvoiddisplay();voidspecialKeys();// Global
Variablesdoublerotate_y=0;doublerotate_x=0;

I will explain each of these functions and the global variables in detail
as we implement them later on in this tutorial. For now, it is important
that you declare them.

5) Setting up the main() Function
intmain(intargc,char*argv[]){// Initialize GLUT and process user
parametersglutInit(&argc,argv);// Request double buffered true color
window with Z-bufferglutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);

This statement sets up our environment. A big thing to remember when
writing OpenGL programs is that you must ask for everything. This
requires you to have a greater understanding of how your program works
and what you need to include to get the functionality that you want. In
this line, we will set up the display with double buffering, RGB color,
and a Z-buffer.
Double bufferingis a technique used in graphics programs to eliminate a
problem that arises due to how images are drawn to the screen. Each time
we redraw the scene, the display must first be erased then the new
information will be drawn. Without double buffering you will observe a
flickering effect as the screen is erased and redrawn repeatedly.This
problem is fixed by adding a second buffer to draw to. With this method,
an image is drawn to the first buffer and that buffer is shown to you.
The next frame will be drawn to the second buffer and when that¡¯s done,
the two buffers will switch places. We will immediately see the second
buffer, but, hidden from us, the first buffer is being erased and redrawn
with the third frame which will be swapped in when finished.
We also want to enable theRGB colorsystem in our window. I¡¯ll explain
more about how color is used in OpenGL when we work on the display
function.
Z-bufferingis how we get the 3D effects that we want. OpenGL uses a three
dimensional coordinate system with x, y and z axes. To give the effect
that an object is closer to you its position on the z axis is increased,
however, to make it appear further away its position on the z axis is
decreased. I will talk a little more about this when we draw our vertices
for the cube.

6) Creating the Window
The next step is tocreate the windowwithin which we will draw the cube.
In this tutorial, I call our window "Awesome Cube".// Create
windowglutCreateWindow("Awesome Cube");


7) Enable Depth Test
OpenGL is a strict language in that it does not assume any special
features are enabled. For our program to properly display in 3-dimensions
using the Z-buffer that we looked at earlier, we need toenable depth-
test. As you continue to explore OpenGL, you will discover many features
that you will need to enable including lighting, textures, cull-facing
and much more.// Enable Z-buffer depth testglEnable(GL_DEPTH_TEST);


8) Callback Functions
Here are the callback functions we wrote the prototypes for earlier. Each
time through the main loop, these functions will be called. The display
function redraws the scene based on any changes to variables that were
made since the previous call. The specialKeys function allows us to
interact with the program.// Callback
functionsglutDisplayFunc(display);glutSpecialFunc(specialKeys);


9) Callback Functions
The final step in our initial setup is tostart the MainLoop. This will
recall the main function until we close the program to allow for
animations and user interaction.// Pass control to GLUT for
eventsglutMainLoop();// Return to OSreturn0;}


Part 2: The display() Function
All the work of drawing our cube will be done in this function. The
general idea behind our cube is to draw all six sides individually and
place them in the appropriate position.
Conceptually, each side is going to be drawn by defining the four corners
and letting OpenGL connect the lines and fill it in with a color that we
define. Below are the steps to doing this.

1) glClear()
The first step we need to take in this function is toclear the color and
Z buffer. Without these steps, the old drawings may still be visible
under the new drawings and objects drawn would not be in the correct
location on the screen.voiddisplay(){// Clear screen and Z-
bufferglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


2) glBegin() and glEnd()
OpenGL defines objects as combinations of different polygons. Using
theglBegin()command, we effectively put down a pencil that will draw a
shape. To lift up the pencil and begin a new shape, we must use
theglEnd()command. In this tutorial we will be using GL_POLYGON to draw
each side of the cube but it is possible to use other parameter options
such as GL_LINE, GL_QUAD, or GL_TRIANGLE to create other shapes.
Here we will be starting with the front of our cube. Later we will add
color to all 6 sides.// Multi-colored side - FRONTglBegin(GL_POLYGON);//
Vertices will be added in the next stepglEnd();


3) glVertex3f()
Once we have stated that we want to begin our polygon, we need todefine
the verticesof the object. glVertex has multiple forms depending on what
you want to do with your object.
The first is how many dimensions you are working in. The 3 above in
glVertex3f says we are drawing in 3 dimensions. It is also possible to
work in 2 or 4 dimensions. The f above in glVertex3f says we are working
with floating point numbers. You can also use shorts, integers or
doubles.
Notice that these points are defined in acounter-clockwisemanner. This is
not very important at the moment but when we begin to work with lighting,
textures, and cull-facing, this will become incredibly important so get
in the habit of defining your points counter-clockwise now.
Now we add the vertices between the glBegin() and glEnd() lines.// Multi-
colored side - FRONTglBegin(GL_POLYGON);glVertex3f(-0.5,-0.5,-0.5);//
P1glVertex3f(-0.5,0.5,-0.5);// P2glVertex3f(0.5,0.5,-0.5);//
P3glVertex3f(0.5,-0.5,-0.5);// P4glEnd();


4) glColor3f()
glColorworks in a similar manner to glVertex. We can define points as
shorts, integers, doubles, or floats. Each color has a value from 0 to 1.
All 0's makes the point black and all 1's will make the point white. The
3 in glColor3f() refers to the RGB color system with no alpha channel.
The alpha of a color defines it's transparency. To change the alpha
level, use glColor4f() with the last parameter being a value of 0 to 1
for opaque to transparent.
When we call glColor3f() every vertex drawn from that point on will be of
that color. Therefore, If we want all four vertices to be red, just set
the color once anytime before the glVertex3f() commands and all vertices
will be red.
The Front side defined below shows how to define a new color for each
vertex. When we do this, we can see an interesting property of the OpenGL
colors. Since each vertex of the polygon has it's own color, OpenGL will
automatically blend the colors! The next step will show how to assign
four vertices with the same color.//Multi-colored side -
FRONTglBegin(GL_POLYGON);glColor3f(1.0,0.0,0.0);glVertex3f(0.5,-0.5,-
0.5);// P1 is redglColor3f(0.0,1.0,0.0);glVertex3f(0.5,0.5,-0.5);// P2 is
greenglColor3f(0.0,0.0,1.0);glVertex3f(-0.5,0.5,-0.5);// P3 is
blueglColor3f(1.0,0.0,1.0);glVertex3f(-0.5,-0.5,-0.5);// P4 is
purpleglEnd();


5) The Other Sides
I encourage you to work out what the location of each vertex will be for
the other five sides of the cube but for simplicity, I have computed
those for you and have included them in ourfinal display()
functionbelow.// White side -
BACKglBegin(GL_POLYGON);glColor3f(1.0,1.0,1.0);glVertex3f(0.5,-
0.5,0.5);glVertex3f(0.5,0.5,0.5);glVertex3f(-0.5,0.5,0.5);glVertex3f(-
0.5,-0.5,0.5);glEnd();// Purple side -
RIGHTglBegin(GL_POLYGON);glColor3f(1.0,0.0,1.0);glVertex3f(0.5,-0.5,-
0.5);glVertex3f(0.5,0.5,-0.5);glVertex3f(0.5,0.5,0.5);glVertex3f(0.5,-
0.5,0.5);glEnd();// Green side -
LEFTglBegin(GL_POLYGON);glColor3f(0.0,1.0,0.0);glVertex3f(-0.5,-
0.5,0.5);glVertex3f(-0.5,0.5,0.5);glVertex3f(-0.5,0.5,-0.5);glVertex3f(-
0.5,-0.5,-0.5);glEnd();// Blue side -
TOPglBegin(GL_POLYGON);glColor3f(0.0,0.0,1.0);glVertex3f(0.5,0.5,0.5);glV
ertex3f(0.5,0.5,-0.5);glVertex3f(-0.5,0.5,-0.5);glVertex3f(-
0.5,0.5,0.5);glEnd();// Red side -
BOTTOMglBegin(GL_POLYGON);glColor3f(1.0,0.0,0.0);glVertex3f(0.5,-0.5,-
0.5);glVertex3f(0.5,-0.5,0.5);glVertex3f(-0.5,-0.5,0.5);glVertex3f(-0.5,-
0.5,-0.5);glEnd();glFlush();glutSwapBuffers();}


We also want to add in two last lines of code for this function. These
areglFlush();andglutSwapBuffers();which give us the double-buffering
effect we learned about earlier.

Part 3: User Interactivity

1) specialKeys()
We are almost done but at the moment, we can draw a cube but have no way
of rotating it. To do this, we willcreate a specialKeys()function to
allow us to press the arrow keys and rotate the cube!
This function is why we declared the global variables rotate_x and
rotate_y. When we press the right and left arrow keys, rotate_y will be
incremented or decremented by 5 degrees. Similarly, when we press the up
and down arrow keys, rotate_x will change
accordingly.voidspecialKeys(intkey,intx,inty){// Right arrow - increase
rotation by 5 degreeif(key==GLUT_KEY_RIGHT)rotate_y+=5;// Left arrow -
decrease rotation by 5 degreeelseif(key==GLUT_KEY_LEFT)rotate_y-
=5;elseif(key==GLUT_KEY_UP)rotate_x+=5;elseif(key==GLUT_KEY_DOWN)rotate_x
-=5;// Request display updateglutPostRedisplay();}


2) glRotate()
Our last statement is to add the statement that will rotate our object.
Go back to thedisplay()function and before the FRONT side, add these
lines:// Reset transformationsglLoadIdentity();// Rotate when user
changes rotate_x and
rotate_yglRotatef(rotate_x,1.0,0.0,0.0);glRotatef(rotate_y,0.0,1.0,0.0);/
/ Multi-colored side - FRONT....


First notice that the syntax ofglRotatef()is similar to that of
glColor3f() and glVertex3f() but always requires 4 parameters. The first
parameter is the degree of rotation to be applied. The next three
parameters define which axis to rotate about with the first being the x
axis, second being the y axis, and third being the z axis. Right now we
only need to rotate about the x and y-axis.
All transformations that we write in our program need lines similar to
this. Conceptually, we think of this as rotating our object about the x
axis by the amount defined by rotate_x and then rotating around the y
axis by rotate_y. However, OpenGL combines all these statements into one
matrix transformation. Each time we call the display function, we build a
transformation matrix andglLoadIdentity()assures that we will start out
with a new matrix in each pass.
The other transformation functions we could apply are glTranslatef() and
glScalef(). These functions are similar to glRotatef() with the exception
the they only take 3 parameters, the x, y, and z amounts to translate or
scale the object.
In order to get the correct effect when applying all three
transformations to one object, we need to apply them in the correct
order. Always write them in the orderglTranslate, glRotate, then glScale.
OpenGL essentially applies the transformations in a bottom up manner. To
understand this try to imagine what a simple 1x1x1 cube would look like
with the transformations if OpenGL applied them from top to bottom and if
OpenGL applied them from bottom to top.
Add the following commands to scale the cube by 2 along the x-axis, 2
along the y-axis, rotate the cube by 180 degrees about the y-axis, and
translate the cube by 0.1 along the x-axis. Make sure to arrange these as
well as the previous glRotate() commands in the correct order as
described above. (If you are unsure, I have done this in the final code
at the end of the tutorial.)// Other
transformationsglTranslatef(0.1,0.0,0.0);glRotatef(180,0.0,1.0,0.0);glSca
lef(2.0,2.0,0.0);


Compiling
The very last step to finishing your first OpenGL project is tocompile
and run your code. Assuming you are using gcc as your compiler, run these
commands from your terminal to compile and test your program.On
Linux:gcccube.c-ocube-lglut-lGL./mycube

On Mac:gcc-ofoo foo.c-frameworkGLUT-frameworkOpenGL
./mycube

On Windows:gcc-Wall-ofoofoo.c-lglut32cu-lglu32-lopengl32./mycube


Final Code
There you have it. Your first OpenGL program! I have provided you with my
source code below as a reference point.//// File:        mycube.c//
Author:      Matt Daisley// Created:     4/25/2012// Project:     Source
code for Make a Cube in OpenGL// Description: Creates an OpenGL window
and draws a 3D cube//              That the user can rotate using the
arrow keys//// Controls:    Left Arrow - Rotate Left//
Right Arrow - Rotate Right//               Up Arrow   - Rotate Up//
Down Arrow - Rotate Down// ---------------------------------------------
-------------// Includes// ----------------------------------------------
------------#include <stdio.h>#include <stdarg.h>#include <math.h>#define
GL_GLEXT_PROTOTYPES#ifdef __APPLE__#include <GLUT/glut.h>#else#include
<GL/glut.h>#endif// -----------------------------------------------------
-----// Function Prototypes// -------------------------------------------
---------------voiddisplay();voidspecialKeys();// -----------------------
-----------------------------------// Global Variables// ----------------
------------------------------------------
doublerotate_y=0;doublerotate_x=0;// ------------------------------------
----------------------// display() Callback function// ------------------
----------------------------------------voiddisplay(){// Clear screen
and Z-bufferglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// Reset
transformationsglLoadIdentity();// Other Transformations// glTranslatef(
0.1, 0.0, 0.0 );      // Not included// glRotatef( 180, 0.0, 1.0, 0.0 );
// Not included// Rotate when user changes rotate_x and
rotate_yglRotatef(rotate_x,1.0,0.0,0.0);glRotatef(rotate_y,0.0,1.0,0.0);/
/ Other Transformations// glScalef( 2.0, 2.0, 0.0 );          // Not
included//Multi-colored side -
FRONTglBegin(GL_POLYGON);glColor3f(1.0,0.0,0.0);glVertex3f(0.5,-0.5,-
0.5);// P1 is redglColor3f(0.0,1.0,0.0);glVertex3f(0.5,0.5,-0.5);// P2 is
greenglColor3f(0.0,0.0,1.0);glVertex3f(-0.5,0.5,-0.5);// P3 is
blueglColor3f(1.0,0.0,1.0);glVertex3f(-0.5,-0.5,-0.5);// P4 is
purpleglEnd();// White side -
BACKglBegin(GL_POLYGON);glColor3f(1.0,1.0,1.0);glVertex3f(0.5,-
0.5,0.5);glVertex3f(0.5,0.5,0.5);glVertex3f(-0.5,0.5,0.5);glVertex3f(-
0.5,-0.5,0.5);glEnd();// Purple side -
RIGHTglBegin(GL_POLYGON);glColor3f(1.0,0.0,1.0);glVertex3f(0.5,-0.5,-
0.5);glVertex3f(0.5,0.5,-0.5);glVertex3f(0.5,0.5,0.5);glVertex3f(0.5,-
0.5,0.5);glEnd();// Green side -
LEFTglBegin(GL_POLYGON);glColor3f(0.0,1.0,0.0);glVertex3f(-0.5,-
0.5,0.5);glVertex3f(-0.5,0.5,0.5);glVertex3f(-0.5,0.5,-0.5);glVertex3f(-
0.5,-0.5,-0.5);glEnd();// Blue side -
TOPglBegin(GL_POLYGON);glColor3f(0.0,0.0,1.0);glVertex3f(0.5,0.5,0.5);glV
ertex3f(0.5,0.5,-0.5);glVertex3f(-0.5,0.5,-0.5);glVertex3f(-
0.5,0.5,0.5);glEnd();// Red side -
BOTTOMglBegin(GL_POLYGON);glColor3f(1.0,0.0,0.0);glVertex3f(0.5,-0.5,-
0.5);glVertex3f(0.5,-0.5,0.5);glVertex3f(-0.5,-0.5,0.5);glVertex3f(-0.5,-
0.5,-0.5);glEnd();glFlush();glutSwapBuffers();}// -----------------------
-----------------------------------// specialKeys() Callback Function// -
---------------------------------------------------------
voidspecialKeys(intkey,intx,inty){// Right arrow - increase rotation by
5 degreeif(key==GLUT_KEY_RIGHT)rotate_y+=5;// Left arrow - decrease
rotation by 5 degreeelseif(key==GLUT_KEY_LEFT)rotate_y-
=5;elseif(key==GLUT_KEY_UP)rotate_x+=5;elseif(key==GLUT_KEY_DOWN)rotate_x
-=5;// Request display updateglutPostRedisplay();}// -------------------
---------------------------------------// main() function// -------------
---------------------------------------------
intmain(intargc,char*argv[]){// Initialize GLUT and process user
parametersglutInit(&argc,argv);// Request double buffered true color
window with Z-
bufferglutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);// Create
windowglutCreateWindow("Awesome Cube");// Enable Z-buffer depth
testglEnable(GL_DEPTH_TEST);// Callback
functionsglutDisplayFunc(display);glutSpecialFunc(specialKeys);// Pass
control to GLUT for eventsglutMainLoop();// Return to OSreturn0;}
<

Sources and Citations
Installing OpenGL
Nehe Productions Tutorials in OpenGL
OpenGL: A Primer, 3/E
CSCI 4229 Introduction to Computer Graphics. Professor Schre¨¹der,
University of Colorado at Boulder

<

								
To top