CS465, Computer Graphics, Fall
2012
Programming Assignment #
1
Drawing Geometric Objects with
GLSL
Demo Date: November 1, Thursday, 2012, Class Hour (13:40), in EB204
This assignment will NOT be done in groups. Every individual student should do his/her homework.
Demo will be at class hour in one of the labs in the new building.
Every student is required to be in the demo.
1. Introduction
This assignment requires you to design and implement a basic graphics
program that draws a 3D geometric object on the screen. This will be an
interactive program that allows the user to choose the object to draw (from a
choice of 5 objects), to choose various drawing attributes for the object
(such as color), to rotate and zoom on the object. Each time
the user selects one of the drawing options the image on the screen will be
redrawn with the new choices. To develop this program you will need to learn
to use both the OpenGL, and FreeGLUT graphics libraries. The FreeGLUT library
includes functions for implementing event-driven input and display handling
operations. This program will be an introduction to developing event-driven
graphics programs. The program must be developed using C++.
- A tutorial on on setting up the OpenGL and FreeGLUT libraries for the Visual Studio IDE is provided
at the Assistant's Website
2. Learning Objectives:
- Learn the basics of writing a graphics program using the OpenGL Shader Language(GLSL)
and the OpenGL Library(OGL).
- Learn to draw simple primitives and geometric objects using OGL and
FreeGLUT functions.
- Learn to set drawing attributes using OGL functions.
- Learn to design and code an event-driven application program using
FreeGLUT functions.
- Learn to use the FreeGLUT library keyboard handler function for
processing keyboard interaction.
- Learn to use the FreeGLUT pop-up menu functions for mouse interaction.
3. Problem Specification
Design an interactive graphics display program that draws geometric objects.
The program will draw one of 5 different shapes interactively chosen by the
user, and it will let the user select:
- Either wireframe or solid mode,
- The color
Your program must handle user input from the keyboard and the mouse, set the
drawing modes as specified below, and display results determined by the
currently selected drawing modes in a window on the screen.
3.1. Configurable Attributes
Object type and drawing mode (wireframe or solid) must be
set through pop-up menus created by FreeGLUT library functions. You must create a
hierarchical pop-up menu with three-menus (object type, drawing mode and color)
each poping up to related submenu entries.
- Object type -- set the current object to be drawn, one of the
following 5 choices:
- Cube: A cube object composed of 12 triangles(2 per side)
- Tetrahedron: A tetrahedron object composed of 4 equilateral triangle surfaces.
- Cylinder: An uncapped tesselated cylinder object.
- Sphere: A tesselated sphere object.
- An object whose geometry is specified by the data file
provided below.(see Implementation Hint 6)
NOTE: Above objects(except the 5th one) should be centered at the origin with respect to their center of gravity. You are free to decide on object parameters such as edge lengths(for the cube and the tetrahedron), radii(for the cylinder and the sphere)
and height(for the cylinder). Alternatively you can make these parameters configurable by the user from the graphical user interface. You should generate a triangulated polygonal mesh for the cylinder and the sphere objects (you may refer to Section 2.4 of your textbook (Edward Angel's book(6th. Edition)) on how to do it).
- Drawing mode -- wireframe (i.e., as lines) or filled polgon
mode
- Color-- set the current color in which to draw lines or
polygons (10 different colors are sufficient)
3.2. Keyboard Interface
- Arrow keys (see below) -- set the object rotation about X (up
and down arrow) and Z (left and right arrow) axes
- i -- initialize rotation
- z -- zoom-in and Z -- zoom-out
- h -- help, print
explanation of your input commands
- q -- quit (exit) the program
Your program must also
properly handle the reshape event; so you must define your own reshape
callback function.
4. Program Requirements
- IMPORTANT! Your application must use OpenGL Shader Language(GLSL) and make use of GLSL Vertex and Fragment Shaders. Programs implemented with Fixed Function OpenGL calls will not be graded( that means no calls to functions like glBegin() or glVertex(..) ).
- You must design this program as an event-driven main application that
responds to keyboard, mouse and reshape events. Thus, you should follow the
main program and function module model given in Edward Angel's book and
lecture
slides. (you can find the source codes and other supporting material for the
book Edward Angel, Interactive Computer Graphics: A Top-down Approach, Sixth Edition, here.
- Your program files must have documentation
comments.
Your program will be graded for:
- good programming design,
- good programming style,
- good program documentation, and
- correctness.
- You are required to run your program and demonstrate that it works.
You
are required to submit only the source files, i.e. the project files, ready to
be compiled and run. Please try to comply with the announced due date. You can
send the files via e-mail to your TA.
5. Implementation Hints
- Detailed documentation for OpenGL functions are described in your
textbook and the OpenGL Programming Guide.
- Use the FreeGLUT (Free GL Utility Toolkit) library functions as
described in your textbook. There is a WWW user manual at http://www.opengl.org/documentation/specs/glut/spec3/spec3.html. You
will need to read about functions in Sections:
- 4 Window Management
- 6 Menu Management
- 7 Callback Registration
- 11 Geometric Object Rendering.
- All your source files must have the statement #include <freeglut.h>
. There is no need to include <GL/gl.h> or <GL/glu.h> since
freeglut.h contains #include statements for these two header files.
- You need global variables that hold state values for your program,
e.g., a code number for the current object type to draw, a code value for the
current draw mode (wire frame or solid), and possibly other values. The
callback functions should merely assign a new value in your global data
structure. Then the display() function will read the current state
values to determine what object to draw, how to draw it, etc. Note, we are
forced to use global data even though that is not good software design because
of the way the FreeGLUT library software designers specified the input
callback functions.
- The various drawing mode control options listed above (type of object,
draw mode, color) should be handled by using these FreeGLUT lib
functions:
- glutKeyboardFunc()
- glutSpecialFunc()
- glutReshapeFunc()
- glutCreateMenu()
- gluAddMenuEntry()
- glutAddSubMenu()
- glutAttachMenu()
Each of these functions must be called one time at program
initialization with a parameter that is the name of your callback
function. Your actual callback functions must have the appropriate prototype.
You are welcome to design your own user input technique for setting
these state variable values with some other combination of key inputs or with
mouse inputs (if you define a mouse callback function and call
glutMouseFunction() or glutMotionFunction()).
- Your object #5 must be as defined in the file anyi.dat.
Dat
file:
A text file in which the
geometry information is encoded in the following order:
Number of
faces (int)
Number of
vertices (int)
List of
vertices (each entry has 3 float x,y,z coordinate values)
Face index
list (each entry has 3 integer vertex indices (oriented))
Each line in the face index
list has 3 indices that define a triangle of the surface. The index i
corresponds to the i th vertex of the vertex list in the appearance
order. Your program has to read the file
and appropriately place the data into arrays
before drawing operations(See examples in Section 2 of your textbook). Since this is a text file, you can view its
contents with a text editor if you wish.
- To handle rotation of your objects, include in your global data structure
an X rotation angle variable (xRot) and a Z rotation angle (zRot) variable (both initialized to 0.0). Then use the
following keyboard keys in your special key callback function (glutSpecialFunc()):
- GLUT_KEY_LEFT and GLUT_KEY_RIGHT keys:
add +3.0
degrees for GLUT_KEY_LEFT and -3.0 for GLUT_KEY_RIGHT to zRot. That is, pressing the Left
(or Right) arrow key should increase (or decrease) the current Z rotation of
the object by 3 degrees.
- GLUT_KEY_UP and GLUT_KEY_DOWN keys:
add +3.0 degrees
for GLUT_KEY_UP and -3.0 for GLUT_KEY_DOWN to xRot.
- i key: set both current rotation angle variables to zero (initial
value).
- To handle zooming on your objects, include in your global data structure a
scale factor variable (scaleFactor, initialized to 1.0). Then use the keyboard
keys z and Z in your keyboard callback function (glutKeyboardFunc()) to multiply
the current value of scaleFactor
with 1.1 (zoom-in) or 0.9 (zoom-out).
- For this assignment you'll use the predefined model,view and projection (MVP) transformation matrices. You'll pass these matrices as uniform variables to your vertex shader. display()
function should use the following OpenGL calls.
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
model_view = LookAt(eye,at,up) * RotateX(xRot) * RotateZ(zRot);
projection = Ortho(VIEW_LEFT,VIEW_RIGHT, VIEW_BOTTOM, VIEW_TOP, VIEW_NEAR, VIEW_FAR );
glUniformMatrix4fv(matrix_loc, 1, GL_TRUE, model_view);
glUniformMatrix4fv(projection_loc, 1, GL_TRUE, projection);
glDrawArrays(GL_TRIANGLES, 0, N);
glutSwapBuffers();
}
The details on how these model-view and projection matrices are formed will be discussed later in the course. Briefly, what they do is:
- glClear(...): : Clears the color and depth frame buffers at each frame such that they become ready for a new render.
- LookAt(...) Function: the LookAt(eye,at,up) function constructs a view transformation matrix where the eye(camera) position is determined
by the vector eye. A good value for the eye vector could be [ 0 0 -3]T and the look at position of the camera is determined by the vector at. For now you may consider this at vector as the zero vector such that the
camera looks towards the center of the coordinate frame. You may also take the up vector as the y-vector [ 0 1 0 ]T.
- RotateX(...) and RotateZ(...) Functions: RotateX(xRot) * RotateZ(zRot) combined constructs the modeling transformation matrix which rotates the object around x and z axes respectively using
euler angles.
- Ortho Function: Ortho(...) function sets up an ortographic projection matrix with the predefined clipping planes. For the Ortho(...) function, here are some good values to use, though you are
welcome (and encouraged) to experiment with other values:
#define
VIEW_LEFT -2.0
#define
VIEW_RIGHT 2.0
#define
VIEW_BOTTOM -2.0
#define
VIEW_TOP 2.0
#define
VIEW_NEAR 1.0
#define
VIEW_FAR 20.0
- glUniformMatrix4fv(...): Writes the updated values for model_view and projection matrices to their corresponding uniform variables specified at the shader side. matrix_loc and projection_loc are the
handles referring to these uniform variables. The following code block may be added to the FreeGLUT init callback function to allocate the handles matrix_loc and projection_loc:
matrix_loc = glGetUniformLocation( program, "model_view" );
projection_loc = glGetUniformLocation( program, "projection" );
In order to allocate these handles in this way, your vertex shader must also declare the uniform variables model_view and projection. An example vertex shader program you may use in this homework is given below:
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform mat4 model_view;
uniform mat4 projection;
void main()
{
gl_Position = projection*model_view*vPosition/vPosition.w; //Normalize the vertex position vector with the homogenous coordinate
//and transform the vertex position with the model-view and projection matrices
color = vColor;
}
-
IMPORTANT!!!... For implementation details please refer to the online resources of the Angel's textbook. Codes for the textbook examples are provided at this link. You may check the examples given for chapter 4 in CHAPTER04 folder.
The definitions of the methods such as LookAt(...),RotateX(...),RotateZ(...) and Ortho(...); common linear algebra operations; and vector and matrix data structures are provided in the include directory.(check mat.h and vec.h files).
- You may use all of the textbook resources(including the example code, slides etc.) given that you provide in-text references in your documentation. You can also refer to the online tutorials given at the Assistant's Website.
- If you have any questions feel free to ask your assistant with an e-mail. You may also schedule a visit to your assistant at his/her office during the office hours.
-
This assignment is not hard but it will require much effort and patience to complete. You have 4 weeks to finish the assignment hence START AS EARLY AS POSSIBLE!.
-
DO NOT TRY TO BE A LAST NIGHT HERO!... as you'll most likely to fail the assignment if you do so.