CS559: Computer Graphics Lecture 2: OpenGL Transformation Li Zhang Spring 28
Today Transformation in OpenGL Reading Chapter 3
Last time
Primitive Details glpolygonmode(glenum face, GLenum mode); face: GL_FRONT, GL_BACK mode: GL_POINT, GL_LINE, GL_FILL glpolygonmode(gl_front, GL_FILL); glrectf(,,, ); glpolygonmode(gl_back, GL_LINE); glrectf(,,, );
Primitive Details Determine Polygon Orientation area( PP P 4) 2 3P = area ( PP 2Q2Q ) + area( P2 P3 Q3Q2 ) area( P3 P4 Q4Q3 ) area( P4 PQ 4Q ) Q 3 Q 4 Q 2 y P 4 P 3 P 2 area = N n= 2 ( x i + x i+ )( yi+ yi ) N N N = + N xi yi+ xi yi xi+ yi+ x 2 n= n= n= n= = 2 N ( xi yi+ xi+ yi ) n= Orientation == sign of the area i+ y i Q Stokes' R dxdy = R P Theorem xdy x
Icosahedron Normal Vectors
Icosahedron //initial icosahedron Static float t[2][3][3] = { ; void display(void) {
Icosahedron //initial icosahedron Static float t[2][3][3] = { ; void display(void) { //clear buffer //set up viewport and frustum if (animation) angle+=.3; if (angle>36) angle =36.; glloadidentity(); glrotatef(angle,,,);
Icosahedron //initial icosahedron Static float t[2][3][3] = { ; void display(void) { //clear buffer //set up viewport and frustum if (animation) angle+=.3; if (angle>36) angle =36.; glloadidentity(); glrotatef(angle,,,); // subdivide each face of the triangle for (int i = ; i < 2; i++) { Subdivide(t[i][], t[i][], t[i][2], subdiv);
Icosahedron //initial icosahedron Static float t[2][3][3] = { ; void display(void) { //clear buffer //set up viewport and frustum if (animation) angle+=.3; if (angle>36) angle =36.; glloadidentity (); glrotatef(angle,,,); // subdivide each face of the triangle for (int i = ; i < 2; i++) { Subdivide(t[i][], t[i][], t[i][2], subdiv); glflush(); glutswapbuffers();
Icosahedron void Subdivide(GLfloat v[3], GLfloat v2[3], GLfloat v3[3], int depth) {
Icosahedron void Subdivide(GLfloat v[3], GLfloat v2[3], GLfloat v3[3], int depth) { if (depth == ) { glcolor3f(.5,.5,.5); glbegin(gl_triangles); glvertex3fv(v); glvertex3fv(v2); glvertex3fv(v3); glend();
Icosahedron void Subdivide(GLfloat v[3], GLfloat v2[3], GLfloat v3[3], int depth) { if (depth == ) { glcolor3f(.5,.5,.5); glbegin(gl_triangles); glvertex3fv(v); glvertex3fv(v2); glvertex3fv(v3); glend(); else { GLfloat v2[3], v23[3], v3[3]; for (int i = ; i < 3; i++) { v2[i] = (v[i]+v2[i])/2.; v23[i] = (v2[i]+v3[i])/2.; v3[i] = (v3[i]+v[i])/2.; Normalize(v2); Normalize(v23); Normalize(v3);
Icosahedron void Subdivide(GLfloat v[3], GLfloat v2[3], GLfloat v3[3], int depth) { if (depth == ) { glcolor3f(.5,.5,.5); glbegin(gl_triangles); glvertex3fv(v); glvertex3fv(v2); glvertex3fv(v3); glend(); else { GLfloat v2[3], v23[3], v3[3]; for (int i = ; i < 3; i++) { v2[i] = (v[i]+v2[i])/2.; v23[i] = (v2[i]+v3[i])/2.; v3[i] = (v3[i]+v[i])/2.; Normalize(v2); Normalize(v23); Normalize(v3); Subdivide(v, v2, v3, depth ); Subdivide(v2, v23, v2, depth ); Subdivide(v3, v3, v23, depth ); Subdivide(v2, v23, v3, depth );
Fixed Camera location So far => Change Camera location Single object => Multiple objects
Examples of multiple objects
3D Geometry Pipeline M object M view Model Space (Object Space) World Space M project Eye Space (View Space) y = M M M M object x image project view M image Canonical View Space Screen Space (2D) Image Space (pixels) Raster Space
3D Geometry Pipeline Model Transformation View Transformation Model Space (Object Space) World Space Eye Space (View Space) Screen Space (2D) Image Space (pixels) Raster Space
3D Geometry Pipeline Model View Transformation Model Space (Object Space) Projection Eye Space (View Space) View port Transformation Screen Space (2D) Image Space (pixels) Raster Space
3D Geometry Pipeline glmatrixmode(gl_modelview) glloadidentity(); glrotate( ); Model View Transformation Model Space (Object Space) glmatrixmode(gl_projection) glloadidentity(); glfrustum( ); Projection View port Transformation Eye Space (View Space) glviewport( ); Screen Space (2D) Image Space (pixels) Raster Space
Cube.cpp
Cube.cpp Event Driven Programming Window management library GLUT / FLTK Events: key strokes, mouse clicks Event handlers: mouse(), display(), reshape()
Cube.cpp int main(int argc, char** argv) { glutinit(&argc, argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); glutinitwindowsize (5, 5); glutinitwindowposition (, ); glutcreatewindow (argv[]); init (); glutdisplayfunc(display); glutreshapefunc(reshape); glutkeyboardfunc(keyboard); glutmainloop(); return ; void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: //correspond to ESC exit(); break;
Cube.cpp int main(int argc, char** argv) { glutinit(&argc, argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); glutinitwindowsize (5, 5); glutinitwindowposition (, ); glutcreatewindow (argv[]); init (); glutdisplayfunc(display); glutreshapefunc(reshape); glutkeyboardfunc(keyboard); glutmainloop(); return ; void reshape (int w, int h) { glviewport(,, w, h); glmatrixmode(gl_projection); glloadidentity(); glfrustum(.,.,.,.,.5, 2.);
Cube.cpp void display(void) { glclear(gl_color_buffer_bit); glcolor3f(.,.,.); glmatrixmode(gl_modelview); glloadidentity(); /* clear the matrix */ /* viewing transformation */ glulookat(.,., 5.,.,.,.,.,.,.); glscalef(., 2.,.); /* modeling transformation */ glutwirecube(.); glflush(); int main(int argc, char** argv) { glutinit(&argc, argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); glutinitwindowsize (5, 5); glutinitwindowposition (, ); glutcreatewindow (argv[]); init (); glutdisplayfunc(display); glutreshapefunc(reshape); glutkeyboardfunc(keyboard); glutmainloop(); return ;
Modeling Transformation gltranslatef(float x, float y, float z) glrotatef(float angle, float x, float y, float z) glscalef(float x, float y, float z) glscalef(2.,.5,.)
General Modeling Transform glloadidentify() glloadmatrixf(float *M) glmultimatrixf(float *M) double M[4][4]; M[2][] corresponds to??? M[]
Matrix Chain glmatrixmode(gl_modelview); glloadidentity(); glmultmatrixf(n); /* apply transformation N */ glmultmatrixf(m); /* apply transformation M */ glmultmatrixf(l); /* apply transformation L */ glbegin(gl_points); glvertex3f(v); /* draw transformed vertex v */ glend(); /* which is (N*(M*(L*v))) */
Matrix Chain glmatrixmode(gl_modelview); glloadidentity(); glmultmatrixf(v); glmultmatrixf(r); glmultmatrixf(t); glbegin(gl_points); glvertex3f(v); glend(); glmatrixmode(gl_modelview); glloadidentity(); glulookat( ); glrotatef( ); gltranslatef( ); glbegin(gl_points); glvertex3f(v); glend();
glulookat glulookat( float eyex, float eyey, float eyez, float px, float py, float pz, float upx, float upy, float upz ) e p u e p e p z = e x e z e y e e e e z u z u x = e e e e e x z x z y =. Give eye location e 2. Give target position p 3. Give upward direction u = T T T e z y x M e e e v
glulookat
glfrustum glfrustum(double left, double right, double bottom, double top, double near, double far) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) + + + + = = > 2 2 2 nf f n n n f n f n f n b t b t b t l r l r l r P O canonical view M M M
gluperspective gluperspective(double fovy, double aspect, double znear, double zfar)
gluperspective
Orthographic Projection glortho(double left, double right, double bottom, double top, double near, double far);
Viewport Transformation glviewport(int x, int y, int width, int height); glfrustum(double left, double right, double bottom, double top, double near, double far) gluperspective(double fovy, double aspect, double znear, double zfar)
Revisit cube.cpp int main(int argc, char** argv) { glutinit(&argc, argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); glutinitwindowsize (5, 5); glutinitwindowposition (, ); glutcreatewindow (argv[]); init (); glutdisplayfunc(display); glutreshapefunc(reshape); glutkeyboardfunc(keyboard); glutmainloop(); return ; void display(void) { glclear(gl_color_buffer_bit); glcolor3f(.,.,.); glmatrixmode(gl_modelview); glloadidentity(); /* clear the matrix */ /* viewing transformation */ glulookat(.,., 5.,.,.,.,.,.,.); glscalef(., 2.,.); /* modeling transformation */ glutwirecube(.); glflush(); void reshape (int w, int h) { glviewport(,, w, h); glmatrixmode(gl_projection); glloadidentity(); glfrustum(.,.,.,.,.5, 2.);