601 likes | 878 Views
OpenGL. Graphics Programming. Graphics Programming. OpenGL Low-level API cross-language cross-platform 2D, 3D computer graphics. GLUT - The OpenGL Utility Toolkit. simple, easy and small window system independent toolkit for writing OpenGL programs; implements a simple windowing API;
E N D
OpenGL Graphics Programming Katia Oleinik: koleinik@bu.edu
Graphics Programming OpenGL • Low-level API • cross-language • cross-platform • 2D, 3D computer graphics
GLUT - The OpenGL Utility Toolkit • simple, easy and small • window system independent toolkit for writing OpenGL programs; • implements a simple windowing API; • makes it considerably easier to learn and explore OpenGL; • provides portable API – you can write a single OpenGL program; • designed for constructing small sized OpenGL programs; • is not a full-featured toolkit for large applications that requires sophisticated user interface • has C/C++ and FORTRAN programming bindings • available on nearly all platforms
Simple GLUT program Step0.c Log on to katana % cp –r /scratch/ogltut/ogl . % cd ogl Note that after tutorial, examples will be available via the web, but not in the location above. Go to http://scv.bu.edu/documentation/presentations/intro_to_OpenGL/ogltut/
Simple GLUT program Step0.c #include <stdio.h> #include <stdlib.h> #include <GL/glut.h> voiddisplay(void); voidinit(void); int main(int argc, char **argv){ glutInit(&argc, argv); // GLUT Configuration glutCreateWindow("Sample GL Window"); // Create Window and give a title glutDisplayFunc(display); /* Set display as a callback for the current window */ init(); /* Set basic openGL states */ /* Enter GLUT event processing loop, which interprets events and calls respective callback routines */ glutMainLoop(); return0; }
Simple GLUT program Step0.c /* called once to set up basic opengl state */ voidinit( ){ } /* display is called by the glut main loop once for every animated frame */ voiddisplay( ){ }
Steps to edit, compile and run the program • Edit the source file in the editor, save it and exit • >makefile_name • >file_name • For step0.c: • >makestep0 • >step0
More GLUT functions Step1.c intmain(int argc, char **argv){ glutInit(&argc, argv); // GLUT Configuration glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutInitWindowSize( 500, 500 ); // Set size and position of the window glutWindowPosition( 200, 200 ); glutCreateWindow(“GL Primitives"); // Create Window and give a title glutDisplayFunc(display); /* Set a callback for the current window */ init(); /* Set basic openGL states */ /* Enter GLUT event processing loop */ glutMainLoop(); return0; }
Initialize openGL scene Step1.c /* called once to set up basic openGLstate */ voidinit(void){ glEnable(GL_DEPTH_TEST); /* Use depth buffering for hidden surface removal*/ glMatrixMode(GL_PROJECTION); /* Set up the perspective matrix */ glLoadIdentity(); /* left, right, bottom, top, near, far */ /* near and far values are the distances from the camera to the front and rear clipping planes */ glOrtho(-4.0, 4.0, -4.0, 4.0, 1., 10.0); // orthgraphicview glMatrixMode(GL_MODELVIEW); /* Set up the model view matrix */ glLoadIdentity(); /* Camera position */ /* By the default, the camera is situated at the origin, points down the negative z-axis, and has an upper vector (0,1,0)*/ gluLookAt(0.,0.,5.,0.,0.,0.,0.,1.,0.); }
More GLUT functions Step1.c /* drawing routine, called by the display function every animated frame */ voidmydraw(){ glColor3f( 1.0, 0.0, 0.0); // red color glutSolidSphere(1., 24, 24); // draw a sphere of radius 1. } /* display is called by the glut main loop once for every animated frame */ voiddisplay(){ /* initialize color and depth buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* call the routine that actually draws what you want */ mydraw(); glutSwapBuffers(); /* show the just-filled frame buffer */ }
GLUT primitives • void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); • void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); • void glutSolidCube(GLdouble size); • void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); • void glutSolidTorus(GLdoubleinnerRadius, GLdoubleouterRadius, GLintnsides, GLint rings); • void glutSolidDodecahedron(void); // radius sqrt(3) • void glutSolidTetrahedron(void); // radius sqrt(3) • void glutSolidIcosahedron(void) // radius 1 • void glutSolidOctahedron(void); // radius 1
Interactive Exercise #1: working with GLUT primitives Step1.c • Run interactive exercise #1 • >int_gl_prim • Use up and down arrows to explore different GLUT primitives • Use w/s keys to switch between wire and solid state
GLUT primitives Step1.c • glutSolidSphereglutWireSphere • glutSolidCubeglutWireCube • glutSolidConeglutWireCone • glutSolidTorusglutWireTorus • glutSolidDodecahedronglutWireDodecahedron • glutSolidOctahedronglutWireOctahedron • glutSolidTetrahedronglutWireTetrahedron • glutSolidIcosahedronglutWireIcosahedron • glutSolidTeapotglutWireTeapot • More info: http://www.opengl.org/documentation/specs/glut/spec3/node80.html
Interactive Exercise #2: Exploring openGL colors Step1.c • Run interactive exercise • >int_gl_color • Press c/s keys to switch between object/background mode • Use r/g/b keys to switch between red/green/blue components • Use arrow keys to modify the value of color component
Setting up the scene and adding color Step1.c /* display is called by the glut main loop once for every animated frame */ voiddisplay(){ /* initialize background color and clear color and depth buffers */ glClearColor(0.7f, 0.7f, 0.7, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mydraw(); glutSwapBuffers(); }
Setting up the scene and adding color Step1.c voidmydraw() { glColor3f( 1.0, 0.0, 0.0); /* red color */ glutSolidTeapot(.5); /* draw teapot */ } More information about gl color routines: http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml
Open GL transformation Step1.c
Viewing: Camera Analogy Step1.c
Viewport transformation Step1.c • indicates the shape of the available screen area into which the scene is mapped • Since viewport specifies the region the image occupies on the computer screen, you can think of the viewport transformation as defining the size and location of the final processed photograph - for example, whether the photograph should be enlarged or shrunk. • if the window changes size, the viewport needs to change accordingly void glViewport( intx, inty, intwidth, intheight);
Viewport transformation Step1.c glViewport( 0, 0, width, height);
ProjectionPerspective vs. Orthographic Step1.c Objects which are far away are smaller than those nearby; Does not preserve the shape of the objects. Perspective view points give more information about depth; Easier to view because you use perspective views in real life. Useful in architecture, game design, art etc. All objects appear the same size regardless the distance; Orthographic views make it much easier to compare sizes of the objects. It is possible to accurately measure the distances All views are at the same scale Very useful for cartography, engineering drawings, machine parts.
Projection transformation Step1.c glMatrixMode(GL_PROJECTION); glLoadIdentity(); //perspective projection glFrustum(left, right, bottom, top, near, far); Or //orthographic projection glOrtho (left, right, bottom, top, near, far);
Perspective Transformation Step1.c //perspective projection voidglFrustum(double left, double right, double bottom, double top, double near, double far);
Perspective Transformation Step1.c Four sides of the frustum, its top, and its base correspond to the six clipping planes of the viewing volume. Objects or parts of objects outside these planes are clipped from the final image Does not have to be symmetrical
Perspective Transformation Step1.c //perspective projection voidgluPerspective( double fovy, double aspect, double near, double far);
Orthographic Transformation Step1.c //orthographic projection void glOrtho( double left, double right, double bottom, double top, double near, double far);
Modelview Matrix Step1.c //perspective projection void gluLookAt(double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
Setting up the scene Step1.c void init(void) { /* called once to set up basic opengl state */ glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); /* Set up the projection matrix */ glLoadIdentity(); // left,right,bottom,top,near,far glFrustum(-1.0, 1.0, -1.0, 1.0, 1., 10.0); // perspective view // glOrtho (-1.0, 1.0, -1.0, 1.0, 1., 10.0); // orthographic view // gluPerspective(45.0f, 1., 1., 10.); // perspective view glMatrixMode(GL_MODELVIEW); /* Set up the model view matrix */ glLoadIdentity(); eyecenterup-direction gluLookAt(0.,0.,2.,0.,0.,0.,0.,1.,0.); /* Camera position */ }
Interactive exercise #3: setting up the camera Step1.c • Run interactive exercise • >int_gl_camera • Use a/ n/ f keys to choose angle/ near/ far modes. • Use ex/ ey/ ezkeys to choose x, y, z values for eye location. • Use cx/ cy/ czkeys to choose x, y, z values for center location.
Assignment #1: setting up the scene step1.c • Modify input file step1.c • Draw a ball with the color of your choice • Set orthographic projection, so that the diameter of the ball would be about 20% of the width of the screen. • Set up camera on z axis 5 units away from the origin
Additional GLUT callback routines step2.c GLUT supports many different callback actions, including: glutDisplayFunc()defines the function that sets up the image on the screen glutReshapeFunc() function is called when the size of the window is changed glutKeyBoardFunc() callback routine to respond on keyboard entry glutMouseFunc() callback to respond on pressing the mouse button glutMotionFunc() callback to respond mouse move while a mouse button is pressed glutPassiveMouseFunc() callback to respond to mouse motion regardless state of mouse button glutIdleFunc() callback routine for idle state, usually used for animation More info: http://www.opengl.org/resources/libraries/glut/spec3/node45.html
Additional GLUT callback routines step2.c intmain(intargc, char **argv) { . . . /* Set callback function that responds on keyboard pressing */ glutKeyboardFunc(keypress); . . . } /* keyboard callback routine */ voidkeypress( unsigned char key, int x, int y) { if (key == 'q' || key =='Q' || key ==27)exit(0); // exit }
Callback routines & Window Resizing Step2.c int main(int argc, char **argv) { . . . /* Set display as a callback for the current window */ glutDisplayFunc(display); /* Set callback function that respond to resizing the window */ glutReshapeFunc(resize); /* Set callback function that responds on keyboard pressing */ glutKeyboardFunc(keypress); /* Set callback function that responds on the mouse click */ glutMouseFunc(mousepress); . . . }
Callback routines & Window Resizing Step2.c voidkeypress( unsigned char key, int x, int y) { … } voidmousepress( int button, int state, int x, int y) { … } voidresize(int width, int height) { double aspect; glViewport(0,0,width,height); /* Reset the viewport */ aspect = (double)width / (double)height; /* compute aspect ratio*/ glMatrixMode(GL_PROJECTION); glLoadIdentity(); //reset projection matrix if (aspect < 1.0) { glOrtho(-4., 4., -4./aspect, 4./aspect, 1., 10.); }else { glOrtho(-4.*aspect, 4.*aspect, -4., 4., 1., 10.); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0., 0., 5., 0., 0., 0., 0., 1., 0.); }
Assignment #2: callback routines and viewport step2.c • Modify input file step2.c • Enable a Keyboard callback routine that prints the pressed key in the command window • Make the program exit, when ESC (ascii=27), "q" or "Q" are pressed • Enable a Mouse callback routine that prints on the screen the information about which mouse button was pressed
Geometric Primitives step3.c
OpenGL Primitives step3.c glBegin(GL_LINES); glVertex3f(10.0f, 0.0f, 0.0f); glVertex3f(20.0f, 0.0f, 0.0f); glVertex3f(10.0f, 5.0f, 0.0f); glVertex3f(20.0f, 5.0f, 0.0f); glEnd(); http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml
Define a box step3.c voidboxDef( float length, float height, float width) { glBegin(GL_QUADS); /* you can color each side or even each vertex in different color */ glColor3f(0., .35, 1.); glVertex3f(-length/2., height/2., width/2.); glVertex3f( length/2., height/2., width/2.); glVertex3f( length/2., height/2.,-width/2.); glVertex3f(-length/2., height/2.,-width/2.); /* add here other sides */ ….. glEnd(); }
OpenGL Transformations step3.c Object Coordinates Eye Coordinates Clip Coordinates Device Coordinates Window Coordinates
Model View Transformations step3.c glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslate(x, y, z); /* transformation L*/ glRotate (angle, x, y, z); /* transformation M */ glScale (x, y, z); /* transformation N */ Order of operations: L * M * N * v DrawGeometry
Model View Transformations step3.c View from a plane Orbit an object voidpilotView( … ) { glRotatef(roll, 0.0, 0.0, 1.0); glRotatef(pitch, 0.0, 1.0, 0.0); glRotatef(heading, 1.0, 0.0, 0.0); glTranslatef(-x, -y, -z); } voidpolarView( … ) { glTranslatef(0.0, 0.0, -distance); glRotated(-twist, 0.0, 0.0, 1.0); glRotated(-elevation, 1.0, 0.0,0.0); glRotated(azimuth, 0.0, 0.0, 1.0); } http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml
Assignment #3: GL primitives and transformations step3.c • Modify input file step3.c • Create a thin box, centered around 0, using GL_QUADS type. This box should be .01 thick (along y axis), 2.0 units in length (in x axis), .4 units in width (along z axis). • Define a different (from your sphere) color for the box. Remember you can assign a different color for each quad or even to each vertex(!). • Move your sphere 1 unite up along y axis. • Move box down y axis, so its upper plane is on the level y=0. • Modify your keypress callback function to respond on pressing "w" and "s" keys to switch between wire and solid states: The GL constants are GL_FILL and GL_LINE
OpenGL Display Lists step4.c // create one display list intindex = glGenLists(1); // compile the display list glNewList(index, GL_COMPILE); glBegin(GL_TRIANGLES); glVertex3fv(v0); glVertex3fv(v1); glVertex3fv(v2); glEnd(); glEndList(); ... // draw the display list glCallList(index); ... // delete it if it is not used any more glDeleteLists(index, 1);
Assignment #4: using GL lists step4.c • Modify input file step4.c • use glScale to scale down the ball. Try to place glScalecommand before glTranslate and then after. Compare the results. • Add to the keyPress callback routine: if user presses "<" and ">" (or left, right) buttons, the platform (box) moves to the left and to the right accordingly. • Remember it should not go beyond the clipping planes, so x coordinate for the translation can not exceed plus/minus 4
Lighting step5.c Ambient Ambient, Diffuse & Specular Ambient & Diffuse Diffuse Diffuse & Specular Specular
Light(s) Position step5.c At least 8 lights available. GLfloatlight_pos[] = { x, y, z, w } // 4th value: w=1 – for positional, w=0 – for directional glLightfv (GL_LIGHT0, GL_POSITION, light_pos) http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml
step5.c Material Properties
Default Lighting values step5.c
Default Material values step5.c