typical program structure: initialize window (glut) initialize event handlers and menus set some...

26
Typical Program Structure: Initialize Window (GLUT) • Initialize Event Handlers and Menus • Set some initial GL states/values • Pass control over to OpenGL

Post on 21-Dec-2015

229 views

Category:

Documents


0 download

TRANSCRIPT

Typical Program Structure:

Initialize Window (GLUT)

• Initialize Event Handlers and Menus

• Set some initial GL states/values

• Pass control over to OpenGL

Initialize Window (GLUT):• glutInit( &argc, argv ): Initialize glut passing in the command line arguments (if necessary).

• glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE GLUT_DEPTH): Set the window to handle RGBA, double-buffering, and depth.

• glutInitWindowSize(width,height): Set the size of the window.

• glutInitWindowPosition(0,0): Set the position of the window.

• glutCreateWindow( "OpenGL Viewer" ): Open the window with the appropriate name.

Initialize Event Handlers and Menus 1:• glutDisplayFunc( Draw ): Set up the function responsible for displaying the image.• glutReshapeFunc( Reshape ): Set the function to be invoked when the view window is reshaped.• glutKeyboardFunc( Keyboard ): Set the function that handles user keystrokes.• glutSpecialFunc( SpecialKeys ): Set the function that handles user special keystrokes (e.g. page-up, page-down, etc.).• glutMouseFunc( Mouse ): Set the function that handles mouse clicks.• glutMotionFunc( DepressedMotion ): Set the function that handles mouse motion when a button is pushed down.• glutPassiveMotionFunc( Motion ): Set the function that handles mouse motion when no button is pushed down.

Initialize Event Handlers and Menus 2:• int submenu1 = glutCreateMenu( DrawModeMenu ): Create a new menu with an associated function, and set it to be the current menu.

• glutAddMenuEntry( " Filled ", GL_FILL ): Add a menu entry to the current menu with the specified title and argument to be passed in to the associated function.

• glutAddMenuEntry( " Outline ", GL_LINE )

• glutCreateMenu( MainMenu )

• glutAddSubMenu(" Polygon mode ", submenu1): Add a submenu to the current menu with specified title and menu handle.

• ...

• glutAttachMenu( GLUT_RIGHT_BUTTON ): Link the menu with a button.

Set some initial GL states/values:• glEnable(GL_DEPTH_TEST): Enable the use of the depth test.

• glEnable(GL_NORMALIZE): Have GL automatically scale normal vectors to unit size

• glClearColor(rvScene.background[0], rvScene.background[1], rvScene.background[2],0.f): Set the color to be used to clear the screen.

Pass control over to OpenGL:• glutMainLoop( ): This function passed control over to glut which is responsible for handling events and drawing to the viewport. (This function never returns.)

Drawing in OpenGL:• Set up the projection model

• Set up the camera position/orientation

• Set up the lights

• Draw the geometric shapes:

• Perform the appropriate transformation

• Set up the materials and textures (if necessary)

• Draw the geometric shapes

OpenGL Function Calls:•A number of OpenGL calls have multiple implementations depending on how parameters are passed in. It is not uncommon to see commands of the form:

glFunctName{234}{ifd}[v]( )

This means that there are multiple implementation depending on how many parameters are being set, whether the parameters are integers, floating point numbers, or double precision numbers, and depending on whether the parameters are passed as individual values or as a pointer to the beginning of an array containing the values.

• OpenGL likes to keep only the currently used object at the forefront of the memory. So if you want to change a matrix, a texture map, material, normal, color, etc. make sure that what you want to use is the currently active one.

www.eecs.tulane.edu/www/graphics/doc/OpenGL-Man-Pages/opengl_index_spec.html

Draw, When?• The projection model uses information about the aspect ratio so the the projection model should be set when the window is created and again if the window is moved (i.e. if Reshape is called).

• The camera should be set up before the first time the scene is drawn and again if the camera position/orientation gets modified.

• The lights should be set up before the first time the scene is drawn and again if the position of the lights is changed.

• The geometric shapes should be redrawn every time the scene is redrawn.

•The transformations should be set as appropriate.

• The material should be set up before the corresponding shape is drawn. If a texture is used then is should be set up once to get a texture handle and then the texture handle gets used with the material.

Draw, How (Projection Model)?

To set up the projection model you need to update the current projection matrix. To do this:

• Call glMatrixMode( GL_PROJECTION ) to set the current matrix to the projection matrix.• Call glLoadIdentity( ) to set the matrix to the identity matrix.• Call gluPerspective(Gldouble fovy, Gldouble aspect, Gldouble zNear, Gldouble zFar) to set up the matrix for projective viewing. The fovy parameter is the height-angle (not the half-height-angle) in degrees (not radians). The aspect parameter is the aspect ratio. The zNear and zFar parameters specify the distance to the near and far z-planes.

Draw, How (Camera position/orientation)?

The easiest way to set up the camera position and orientation is:• Call glMatrixMode( GL_MODELVIEW ) to set the current matrix to the model-view matrix.• Call glLoadIdentity( ) to set the matrix to the identity matrix.• Call gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz ) to set up the position/orientation of the camera. The eye* parameters specify the location of the camera. The center* parameters specify the point the camera should be looking at. (This can be any point along the ray from the camera along the camera-forward direction.) The up* parameters specify the up-direction of the camera. (Note that the center* parameters can be obtained by adding the forward direction of the camera to its location.)

Draw, How (Lights)?• Set up the light model using the glLightModel* commands

• Enable general lighting by calling the glEnable(GL_LIGHTING) command.

• For each light call glLight*( ) with the light index, the parameter name, and the parameter value. The light indices are GL_LIGHT0, GL_LIGHT1, etc. (at least through GL_LIGHT8 are guaranteed to be supported). The parameter names are:

GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITON, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION

Draw, How (Lights) continued?

Note that some of the above parameters have default values so, depending on the light source, you may not have to set them.

Additionally, keep in mind that the GL_SPOT_CUTOFF value takes on values in the range [0-128] so you will need to scale the value you read in from the .ray file. (As that value is in the range [0.0-1.0].)

Draw, How (Transformations)?

Initially:

Call glMatrixMode( GL_MODEL_VIEW ) to ensure that the working matrix is the model-view matrix. (At this point you should have already set up your camera position/orientation so you should not call glLoadIdentity( ) as this will throw away that information.)

If you intend to apply transformations that are not permanent you should call glPushMatrix( ) before applying the transformation, and then glPopMatrix( ) after you are done. (Done properly this will mean that you do not have to reset your camera position/orientation every time you draw the scene.)

Draw, How (Transformations) continued?

The current matrix can be modified by either calling the OpenGL commands:

• glTranslate*( x,y,z ): Where (x,y,z) is the vector by which the translation should occur.

• glRotate*( angle, x, y, z ): Where angle represents the angle by which the rotation should occur and (x,y,z) represent the vector about which the rotation should occur.

• glScale*( x, y, z ): where x ,y , z specify the scale factor along the x, y, and z directions respectively.

Alternatively, you can explicitly multiply/set the matrix by calling:

glMultMatrix*( matrix ) or glLoadMatrix( matrix )

Where matrix is a pointer to a 4x4 matrix stored in column-major order as sixteen consecutive values.

Draw, How (Transformations) continued?

You should note that transformations are applied on the right so the last transformation specified is the first to be used.

Draw, How (Materials)?

The material specifications are set using by calling the command glMaterial* with the face specification, the material parameter name, and the material parameter value(s).

The face specification can be one of:

GL_FRONT, GL_BACK, GL_FRONT_AND_BACK

The material parameter name can be one of:

GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE

Note that the GL_SHININESS values takes on values in the range [0-128] so you will need to scale the value you read in from the .ray file. (As that value is in the range [0.0-1.0].)

Draw, How (Materials) continued?

If a texture is associated with the material you will also have to:

• Call glEnable( GL_TEXTURE_2D ) to enable the use of textures

• Call glBindTexture(GL_TEXTURE_2D, textureHandle) to set the texture to be used. (More on textureHandle momentarily.)

If no texture is associated with the material you will have to call glDisable( GL_TEXTURE_2D ) to disable the use of textures.

Draw, How (Textures)?

To obtain a texture handle (to be used by the material) you must:

• Call glGenTextures( … ) with the number of texture handles to be generated and a pointer to the beginning of the array the should be written, to have OpenGL give you the next available texture handle(s).

• Call glBindTexture( GL_TEXTURE_2D, textureHandle ) to specify that subsequent texture information should be associated with the specified handle.

• Call glTexParameter( GL_TEXTURE_2D, … ) with the parameter name and corresponding value.

Draw, How (Textures) continued?•Some of the parameter names are:

• GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T: These specify if the texture “wraps” in the s and t direction, and the associated values are GL_CLAMP and GL_REPEAT

• GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER: These specify the filters to be used when the pixel being drawn is either to big or too small. The associated values are: GL_NEAREST and GL_LINEAR.

If you are using mipmaps then the GL_TEXTURE_MIN_FILTER can also have the following associated values:

GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR

Draw, How (Textures) continued?

Finally, to actually specify the texture you need to give the pixel information. This can be done by calling gluBuild2DMipmaps( … ).

Draw, How (Geometry)?

Geometry is most basically drawn by drawing primitives (points, polygons, and lines) and is done by:

• Specifying the type of primitive to be drawn

• Specifying the information to be associated with the next vertex (including material, color, normals, etc)

• Specifying the vertex coordinates.

Draw, How (Geometry) continued?

The type of primitive to be drawn is specified by surrounding the vertex specifications with glBegin( ... ) and glEnd( ). Where glBegin( … ) can take one of the following parameters:

GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_POLYGON

When drawing quads and polygons you must ensure that the polygon is planar and convex. Vertices should be given in counter clockwise order. (See OpenGL manual for vertex ordering when using *_STRIP.)

Draw, How (Geometry) continued?• See earlier notes for material specification

• Normals are specified using the glNormal*( … ) commands.

• Texture coordinates are specified using the glTexCoord2*( … ) commands.

• Colors are specified using the glColor*( … ) commands. (I think these are ignored if lighting is enabled.)

Draw, How (Geometry) continued?

Vertex location is specified by invoking (one of) the glVertex*( … ) commands.

Draw, How (Geometry) continued?

If you want to draw complex models, triangle by triangle specifications may not be the easiest way to do things. Glu provides functions calls to make your life easier.

To use these functions you must:

• Create a GLUquadricObj by calling

GLUquadricObj* qobj=gluNewQuadric( )

• Possibly specify parameters by calling one of:• gluQuadricDrawStyle(qobj, … )• gluQuadricOrientation(qobj, … )• gluQuadricNormals(qobj, … )• gluQuadricTexture(qobj, … )

• Invoke one of gluSphere( … ), gluCylinder( … ), gluDisk( … ), gluPartialDisk( … ) with qobj and the appropriate radius, width, height, tesselation, etc. parameters.