Computer Graphics 5 Lee ByungGook 1222020 Computer Graphics
Computer Graphics 5 Lee Byung-Gook 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 1
3 D Elementary Shapes • The glut library contains several functions for drawing basic 3 D primitives. These are listed below. All of the following objects are centered at the origin • glut. Wire. Cube(GLdouble size); • glut. Solid. Cube(GLdouble size); • glut. Wire. Sphere(GLdouble radius, GLint n. Slices, GLint n. Stacks); • glut. Solid. Sphere(GLdouble radius, GLint n. Slices, GLint n. Stacks); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 2
glut. Wire. Sphere • This approximates a sphere with a set of polygons. The number of polygons determines the "niceness" of the approximation. n. Slices is the number of subdivisions around the z-axis. n. Stacks is the number of bands along the z axis. • Large values for n. Slices and n. Stacks produce more accurate representations (at the cost of slower graphics). • Small values for n. Slices and n. Stacks produce poorer representations (with the benefit of faster graphics). 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 3
3 D Elementary Shapes • • glut. Wire. Tetrahedron(); glut. Solid. Tetrahedron(); glut. Wire. Octahedron(); glut. Solid. Octahedron(); glut. Wire. Dodecahedron(); glut. Solid. Dodecahedron(); glut. Wire. Icosahedron(); glut. Solid. Icosahedron(); 12/2/2020 // 4 faced pyramid // 8 faced solid // 12 faced solid // 20 faced solid Computer Graphics, Lee Byung-Gook, Dongseo Univ. 4
3 D Elementary Shapes • glut. Wire. Torus(GLdouble inner. Radius, GLdouble outer. Radius, GLint n. Slices, GLint rings); • glut. Solid. Torus(GLdouble inner. Radius, GLdouble outer. Radius, GLint n. Slices, GLint rings); • glut. Wire. Teapot(GLdouble size); • glut. Solid. Teapot(GLdouble size); • glut. Wire. Cone(GLdouble base. Radius, GLdouble height, GLint n. Slices, GLint n. Stacks); • glut. Solid. Cone(GLdouble base. Radius, GLdouble height, GLint n. Slices, GLint n. Stacks); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 5
lab 07. cpp #include <math. h> #include <stdio. h> #include <stdlib. h> #include <GL/glut. h> GLint GLint GLfloat N=4; mouse. X = 0; mouse. Y = 0; mouse. State = 0; mouse. Button = 0; shape=1, model=2; size=2. 0; x. Theta=0. , y. Theta=0. , z. Theta=0. , theta. Delta=. 125; scale=1. 0, scale. Delta=1. 01; void my. Axis(void) { int i; gl. Color 3 f(0. 98, . 04, . 70); gl. Begin(GL_LINES); 12/2/2020 for(i=0; i<=N; i++) { gl. Vertex 2 f(-size+2. 0*i*size/N, -size); gl. Vertex 2 f(-size+2. 0*i*size/N, size); gl. Vertex 2 f(-size, -size+2. 0*i*size/N); gl. Vertex 2 f(size, -size+2. 0*i*size/N); } gl. End(); } void my. Draw(void) { gl. Color 3 f(. 98, . 625, . 12); if(model==1) glut. Wire. Cube(1. 0); else if(model==2) glut. Solid. Cube(1. 0); else if(model==3) glut. Wire. Sphere(1. 0, 10); else if(model==4) glut. Solid. Sphere(1. 0, 10); else if(model==5) glut. Wire. Teapot(1. 0); else if(model==6) glut. Solid. Teapot(1. 0); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 6
lab 07. cpp void my. Display(void) { static int i=0; gl. Clear(GL_COLOR_BUFFER_BIT); gl. Load. Identity(); gl. Rotatef(x. Theta, 1. 0, 0. 0); gl. Rotatef(y. Theta, 0. 0, 1. 0, 0. 0); gl. Rotatef(z. Theta, 0. 0, 1. 0); gl. Scalef(scale, scale); my. Draw(); gl. Flush(); glut. Swap. Buffers(); } void my. Reshape(int width, int height) { gl. Clear. Color (. 75, 0. 0); gl. Viewport(0, 0, width, height); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); gl. Ortho(-size, -size, size); gl. Matrix. Mode(GL_MODELVIEW); } 12/2/2020 void glut. Mouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) { mouse. State=state; mouse. Button=btn; mouse. X=x; mouse. Y=y; } else if(btn==GLUT_LEFT_BUTTON && state == GLUT_UP) { mouse. State=-1; } else if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { mouse. State=state; mouse. Button=btn; mouse. X=x; mouse. Y=y; } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 7
lab 07. cpp else if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_UP) { mouse. State=-1; } else return; glut. Post. Redisplay(); } void glut. Motion(int x, int y) { if(mouse. Button == GLUT_LEFT_BUTTON && mouse. State == GLUT_DOWN) { y. Theta -= (mouse. X - x)/10. ; x. Theta -= (mouse. Y - y)/10. ; } else if(mouse. Button == GLUT_MIDDLE_BUTTON && mouse. State == GLUT_DOWN) { if(mouse. Y!=y) scale = scale * pow(scale. Delta, (mouse. Y - y)/10. ); } else return; 12/2/2020 mouse. X = x; mouse. Y = y; glut. Post. Redisplay(); } void my. Menu(int id) { if(id == 7) exit(1); else model = id; glut. Post. Redisplay(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 8
lab 07. cpp void main(int argc, char** argv) { int shape_submenu; glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_DOUBLE | GLUT_RGB); glut. Init. Window. Size(500, 500); glut. Init. Window. Position(0, 0); glut. Create. Window("lab 07"); glut. Reshape. Func(my. Reshape); glut. Display. Func(my. Display); glut. Mouse. Func(glut. Mouse); glut. Motion. Func(glut. Motion); glut. Create. Menu(my. Menu); glut. Add. Menu. Entry("Wire. Cube", 1); glut. Add. Menu. Entry("Solid. Cube", 2); glut. Add. Menu. Entry("Wire. Sphere", 3); glut. Add. Menu. Entry("Solid. Sphere", 4); glut. Add. Menu. Entry("Wire. Teapot", 5); glut. Add. Menu. Entry("Solid. Teapot", 6); glut. Add. Menu. Entry("Quit", 7); glut. Attach. Menu(GLUT_RIGHT_BUTTON); glut. Main. Loop(); } 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 9
glut. Create. Menu • glut. Create. Menu creates a new pop-up menu. • int glut. Create. Menu(void (*func)(int value)); • Parameters func The callback function for the menu that is called when a menu entry from the menu is selected. The value passed to the callback is determined by the value for the selected menu entry. 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 10
glut. Add. Menu. Entry • glut. Add. Menu. Entry adds a menu entry to the bottom of the current menu. • void glut. Add. Menu. Entry(char *name, int value); • Parameters name ASCII character string to display in the menu entry. value Value to return to the menu’s callback function if the menu entry is selected. 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 11
glut. Attach. Menu • glut. Attach. Menu attaches a mouse button for the current window to the identifier of the current menu; • void glut. Attach. Menu(int button); • Parameters button The button to attach a menu 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 12
Projection, Model. View matrix • There are three different 4 x 4 matrices used by Open. GL to produce an image. • Projection matrix - used to "project" a 3 D image onto a 2 D plane to create an image • Model. View matrix - used to transform objects and the camera to create the desired scene and view. • Commands like gl. Translate, gl. Rotate, and gl. Scale modify the active matrix. It is the programmer's responsibility to make sure the appropriate matrix is "active. " The active matrix is determined by calls to gl. Matrix. Mode(). 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 13
gl. Matrix. Mode • The gl. Matrix. Mode function specifies which matrix is the current matrix. • void gl. Matrix. Mode( GLenum mode ); • Parameters mode : The matrix stack that is the target for subsequent matrix operations. The mode parameter can assume one of three values: GL_MODELVIEW : Applies subsequent matrix operations to the modelview matrix stack. GL_PROJECTION : Applies subsequent matrix operations to the projection matrix stack. GL_TEXTURE : Applies subsequent matrix operations to the texture matrix stack. 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 14
Open. GL transformation functions • Open. GL maintains a 4 x 4 transformation matrix that is multiplied by every (x, y, z) value sent to gl. Vertex(). This is sometimes referred to as the CT (current transformation, active matrix). • The CT can be modified by the following functions: gl. Load. Identity(); gl. Translate{fd}(dx, dy, dz); gl. Scale{fd}(sx, sy, sz); gl. Rotate{fd}(angle. In. Degrees, axis. Xvalue, axis. Yvalue, axis. Zvalue); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 15
Specifics • The gl. Load. Identity() function is unique. It replaces the CT with an identity matrix. This has the effect of starting transformations "from unity". • The arguments to these functions can be float or double data types. The last letter of the function name determines the data type of the arguments. For example: gl. Translatef(3. 0, 4. 0, 1. 2); // floating point data gl. Translated(3. 0, 4. 0, 1. 2); // double precision data 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 16
Specifics • To translate along one axis while leaving the other axis values unchanged, use a value of zero for the unaffected axes. For example, the following function call moves along the Y axis 6 units : gl. Translatef(0. 0, 6. 0, 0. 0); • To scale along one axis while leaving the other axis values unchanged, use a value of one for the unaffected axes. For example, the following call scales only along the Z axis by a factor of 3 : gl. Scalef(1. 0, 3. 0); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 17
Specifics • To rotate about one of the coordinate system axes, specify the appropriate vector. For example: gl. Rotatef(20. 0, 1. 0, 0. 0); // rotates about the X axis gl. Rotatef(20. 0, 1. 0, 0. 0); // rotates about the Y axis gl. Rotatef(20. 0, 1. 0); // rotates about the Z axis 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 18
Specifics • For the gl. Translate, gl. Rotate, and gl. Scale functions, each builds a 4 x 4 transformation matrix using the supplied arguments and then multiplies it times the CT (current transform). For example, the gl. Translatef function might look something like the following: void gl. Translatef(float dx, float dy, float dz) { GLfloat m[4][4] = {{ 1. 0, 0. 0, dx }, { 0. 0, 1. 0, 0. 0, dy }, { 0. 0, 1. 0, dz }, { 0. 0, 1. 0}}; CT = CT*m; // pseudocode } 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 19
Facts about transformations • Given a sequence of elementary transformations that together form a single complex transformation, if you change the order of the elementary transformations, you get a different complex transformation • There is typically more than one sequence of transformations that will produce the same effect, but often one sequence is easier to create than the others. • The multiplication of the matrices is always (CT*m), not (m*CT), so the order of the function calls must be in reverse order from the "conceptual" ordering of the transformations. 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 20
Specifics • If you want to: translate a point by (-2, 5, 0), then rotate it by 20 degrees about the Z axis, then scale it by a factor of 2 along the X axis, • the function calls would be: gl. Load. Identity(); gl. Scalef(2. 0, 1. 0); gl. Rotatef(20. 0, 1. 0); gl. Translatef(-2. 0, 5. 0, 0. 0); draw. Object(); 12/2/2020 // always start with the identity matrix // Conceptually, this happens 3 rd // Conceptually, this happens 2 nd // Conceptually, this happens 1 st Computer Graphics, Lee Byung-Gook, Dongseo Univ. 21
Specifics • The transformations caused by gl. Rotate, gl. Translate, and gl. Scale are applied to the CT (current transform). They will accumulate continually unless you reset the matrix back to the Identity matrix. If you want to start a new set of transformations, then call gl. Load. Identity(). • Example: gl. Matrix. Mode(GL_MODELVIEW); gl. Load. Identity(); // start a new sequence of transforms gl. Translatef(-3. 0, -4. 0, 0. 0); gl. Rotatef(90. 0, 1. 0, 0. 0); draw. Object 1(); gl. Load. Identity(); // start a new sequence of transforms gl. Translatef(4. 0, 2. 0, 1. 0); gl. Scalef(2. 0, 1. 0); draw. Object 2(); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 22
Example 1 • Draw a wall of a building containing 5 arched windows, spaced 10 units apart. Assume the arched window is defined around the origin and is 4 units wide 4 12/2/2020 5 8 10 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 23
Example 1 1) reset the matrix 2) draw. Window 3) translate 8 on X, 5 on Y 4) reset the matrix 5) draw. Window 6) translate 18 on X, 5 on Y 7) reset the matrix 8) draw. Window 9) translate 28 on X, 5 on Y 10) reset the matrix 11) draw. Window 12) translate 38 on X, 5 on Y 13) reset the matrix 14) draw. Window 15) translate 48 on X, 5 on Y 12/2/2020 gl. Load. Identity() gl. Translatef(8. 0, 5. 0, 0. 0); draw. Window(); gl. Load. Identity() gl. Translatef(18. 0, 5. 0, 0. 0); draw. Window(); gl. Load. Identity() gl. Translatef(28. 0, 5. 0, 0. 0); draw. Window(); gl. Load. Identity() gl. Translatef(38. 0, 5. 0, 0. 0); draw. Window(); gl. Load. Identity() gl. Translatef(48. 0, 5. 0, 0. 0); draw. Window(); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 24
Example 1 1) reset the matrix 2) draw. Window 3) translate 10 on X, 0 on Y 4) draw. Window 5) translate 10 on X, 0 on Y 6) draw. Window 7) translate 10 on X, 0 on Y 8) draw. Window 9) translate 10 on X, 0 on Y 10) draw. Window 11) translate 8 on X, 5 on Y 12/2/2020 gl. Load. Identity() gl. Translatef(8. 0, 5. 0, 0. 0); draw. Window(); gl. Translatef(10. 0, 0. 0); draw. Window(); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 25
lab 08. cpp #include <math. h> #include <stdio. h> #include <stdlib. h> #include <GL/glut. h> GLint N=12; GLfloat size=60. 0; void my. Axis(void) { int i; gl. Color 3 f(. 98, . 04, . 70); gl. Begin(GL_LINES); for(i=0; i<=N; i++) { gl. Vertex 2 f(-size+2. 0*i*size/N, -size); gl. Vertex 2 f(-size+2. 0*i*size/N, size); gl. Vertex 2 f(-size, -size+2. 0*i*size/N); gl. Vertex 2 f(size, -size+2. 0*i*size/N); } gl. End(); gl. Color 3 f(. 25, . 25); gl. Begin(GL_LINES); gl. Vertex 2 f(0, -size); gl. Vertex 2 f(0, size); 12/2/2020 gl. Vertex 2 f(-size, 0); gl. Vertex 2 f(size, 0); gl. End(); } void draw. Window(void) { gl. Begin(GL_POLYGON); gl. Vertex 3 f(-3. , 0. ); gl. Vertex 3 f(3. , 8. , 0. ); gl. Vertex 3 f(2. 954423, 8. 520945, 0. ); gl. Vertex 3 f(2. 819078, 9. 026060, 0. ); gl. Vertex 3 f(2. 598076, 9. 500000, 0. ); gl. Vertex 3 f(2. 298133, 9. 928363, 0. ); gl. Vertex 3 f(1. 928363, 10. 298133, 0. ); gl. Vertex 3 f(1. 500000, 10. 598076, 0. ); gl. Vertex 3 f(1. 026060, 10. 819078, 0. ); gl. Vertex 3 f(. 520945, 10. 954423, 0. ); gl. Vertex 3 f(0. 000000, 11. 000000, 0. ); gl. Vertex 3 f(-. 520945, 10. 954423, 0. ); gl. Vertex 3 f(-1. 026060, 10. 819078, 0. ); gl. Vertex 3 f(-1. 500000, 10. 598076, 0. ); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 26
lab 08. cpp gl. Vertex 3 f(-1. 928363, 10. 298133, 0. ); gl. Vertex 3 f(-2. 298133, 9. 928363, 0. ); gl. Vertex 3 f(-2. 598076, 9. 500000, 0. ); gl. Vertex 3 f(-2. 819078, 9. 026060, 0. ); gl. Vertex 3 f(-2. 954423, 8. 520945, 0. ); gl. Vertex 3 f(-3. , 8. , 0. ); gl. End(); } void my. Display(void) { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Load. Identity(); my. Axis(); gl. Color 3 f(. 25, . 12); draw. Window(); gl. Color 3 f(. 98, . 625, . 12); for(int j=0; j<5; j++) { gl. Load. Identity(); gl. Translatef(8+10. 0*j, 5. 0, 0. 0); draw. Window(); } gl. Flush(); 12/2/2020 glut. Swap. Buffers(); } void my. Reshape(int width, int height) { gl. Clear. Color (. 75, 0. 0); gl. Viewport(0, 0, width, height); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); gl. Ortho(-size, -size, size); gl. Matrix. Mode(GL_MODELVIEW); } void main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_DOUBLE | GLUT_RGB); glut. Init. Window. Size(500, 500); glut. Init. Window. Position(0, 0); glut. Create. Window("lab 08"); glut. Reshape. Func(my. Reshape); glut. Display. Func(my. Display); glut. Main. Loop(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 27
Exercise 1 • Compare the difference gl. Load. Identity(); gl. Translatef(10. 0, 0. 0); gl. Rotatef(theta, 0. 0, 1. 0); glut. Wire. Sphere(1. 0, 10); 12/2/2020 gl. Load. Identity(); gl. Rotatef(theta, 0. 0, 1. 0); gl. Translatef(10. 0, 0. 0); glut. Wire. Sphere(1. 0, 10); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 28
Example 2 • Transform the triangle from its current location (left) to the new location and orientation shown on right. 10 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 29
Example 2 1) draw. Triangle 2) rotate 90 degrees about Z 2) translate 10 units along Y 12/2/2020 gl. Load. Identity() gl. Translatef(0. 0, 10. 0, 0. 0); gl. Rotatef(90. 0, 1. 0); draw. Triangle(); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 30
Example 2 1) draw. Triangle 2) translate 10 units along X 3) rotate 90 degrees about Z 12/2/2020 gl. Load. Identity() gl. Rotatef(90. 0, 1. 0); gl. Translatef(10. 0, 0. 0); draw. Triangle(); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 31
Example 2 1) draw. Triangle 2) rotate -90 degrees about Z 3) translate -10 along Y 4) rotate 180 degrees about Z 12/2/2020 gl. Load. Identity() gl. Rotatef(180. 0, 1. 0); gl. Translatef(0. 0, -10. 0, 0. 0); gl. Rotatef(-90. 0, 1. 0); draw. Triangle(); Computer Graphics, Lee Byung-Gook, Dongseo Univ. 32
lab 09. cpp #include <math. h> #include <stdio. h> #include <stdlib. h> #include <GL/glut. h> gl. Begin(GL_LINES); gl. Vertex 2 f(0, -size); gl. Vertex 2 f(0, size); gl. Vertex 2 f(-size, 0); gl. Vertex 2 f(size, 0); gl. End(); GLint N=6; GLfloat size=30. 0; } void my. Axis(void) { int i; gl. Color 3 f(. 98, . 04, . 70); gl. Begin(GL_LINES); for(i=0; i<=N; i++) { gl. Vertex 2 f(-size+2. 0*i*size/N, -size); gl. Vertex 2 f(-size+2. 0*i*size/N, size); gl. Vertex 2 f(-size, -size+2. 0*i*size/N); gl. Vertex 2 f(size, -size+2. 0*i*size/N); } gl. End(); gl. Color 3 f(. 25, . 25); 12/2/2020 void draw. Triangle(void) { gl. Begin(GL_POLYGON); gl. Color 3 f(. 0, 1. 0); gl. Vertex 3 f(-5. , 0. ); gl. Color 3 f(. 0, 1. 0); gl. Vertex 3 f(5. , -5. , 0. ); gl. Color 3 f(1. 0, . 0); gl. Vertex 3 f(0. , 5. , 0. ); gl. End(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 33
lab 09. cpp void my. Display(void) { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Load. Identity(); my. Axis(); gl. Load. Identity(); gl. Translatef(0. 0, 10. 0, 0. 0); gl. Rotatef(90. 0, 1. 0); draw. Triangle(); gl. Flush(); glut. Swap. Buffers(); } void main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_DOUBLE | GLUT_RGB); glut. Init. Window. Size(500, 500); glut. Init. Window. Position(0, 0); glut. Create. Window("lab 09"); glut. Reshape. Func(my. Reshape); glut. Display. Func(my. Display); glut. Main. Loop(); } void my. Reshape(int width, int height) { gl. Clear. Color (. 75, 0. 0); gl. Viewport(0, 0, width, height); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); gl. Ortho(-size, -size, size); gl. Matrix. Mode(GL_MODELVIEW); } 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 34
Exercise 2 • From lab 09 • Find another sequence of transformations that will produce the same effect 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 35
Matrix Stack • Problem : Matrix multiplication is computationally expensive. The multiplication of two 4 x 4 matrices requires 64 multiples and 48 additions • Solution : Avoid duplicate matrix multiplication by saving transformations that will be needed again. A stack is a good way to store a series of transformations for later use 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 36
Open. GL implementation • Open. GL maintains a stack that can hold a minimum of 32 matrices. The matrix at the top of the stack is always the CT (Current Transform) • The following two commands manipulate the matrix stack: gl. Push. Matrix(); gl. Pop. Matrix(); 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 37
Open. GL implementation • Assuming that the stack is implemented as an array, these two functions look like the following pseudocode: // The stack begins with an Identity matrix on top int stack. Top = 1; Matrix 4 x 4 Identity = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; Matrix 4 x 4 Matrix. Stack[32] = {Identity, {0}}; void gl. Push. Matrix(void) { Matrix. Stack[stack. Top] = Matrix. Stack[stack. Top-1]; stack. Top++; } void gl. Pop. Matrix(void) { stack. Top--; } // The CT (current transform) is always Matrix. Stack[stacktop-1] 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 38
Matrix Stack Statements stack[0] stack[1] gl. Load. Identity(); gl. Rotatef(x. Theta, 1. 0, 0. 0); gl. Rotatef(y. Theta, 0. 0, 1. 0, 0. 0); gl. Rotatef(z. Theta, 0. 0, 1. 0); gl. Scalef(scale, scale); glut. Wire. Sphere(3. 0, 10); gl. Rotatef(theta, 0. , 1. ); gl. Translatef(20. , 0. ); glut. Wire. Sphere(1. 0, 10); gl. Push. Matrix(); gl. Rotatef(theta, 0. , 1. ); gl. Translatef(5. , 0. ); glut. Wire. Sphere(. 5, 10); gl. Pop. Matrix(); gl. Rotatef(theta, 0. , 1. ); gl. Translatef(-5. , 0. ); glut. Wire. Sphere(. 5, 10); M 0 = I M 0 = M 0*Rx, x. Theta M 0 = M 0*Ry, y. Theta M 0 = M 0*Rz, z. Theta M 0 = M 0*Sscale, scale M 0 = M 0*Rz, theta M 0 = M 0*Tx, 20. M 0 M 0 = M 0*Rz, theta M 0 = M 0*Tx, , 5. M 0 M 1 = M 1*Rz, theta M 1 = M 1*Tx, , 5. M 1 - 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 39
lab 10. cpp #include <math. h> #include <stdio. h> #include <stdlib. h> #include <GL/glut. h> bool GLint GLint GLfloat idle. Flag = 1; N=6; mouse. X = 0; mouse. Y = 0; mouse. State = 0; mouse. Button = 0; size=30. 0, theta=0. 0; x. Theta=0. , y. Theta=0. , z. Theta=0. , theta. Delta=. 125; scale=1. 0, scale. Delta=1. 01; 12/2/2020 void my. Axis(void) { int i; gl. Color 3 f(. 98, . 04, . 70); glut. Wire. Cube(size*2. 0); gl. Begin(GL_LINES); for(i=0; i<=N; i++) { gl. Vertex 2 f(-size+2. 0*i*size/N, -size); gl. Vertex 2 f(-size+2. 0*i*size/N, size); gl. Vertex 2 f(-size, -size+2. 0*i*size/N); gl. Vertex 2 f(size, -size+2. 0*i*size/N); } gl. End(); gl. Color 3 f(. 25, . 25); gl. Begin(GL_LINES); gl. Vertex 2 f(0, -size); gl. Vertex 2 f(0, size); gl. Vertex 2 f(-size, 0); gl. Vertex 2 f(size, 0); gl. End(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 40
lab 10. cpp void my. Display(void) { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Load. Identity(); gl. Rotatef(x. Theta, 1. 0, 0. 0); gl. Rotatef(y. Theta, 0. 0, 1. 0, 0. 0); gl. Rotatef(z. Theta, 0. 0, 1. 0); gl. Scalef(scale, scale); my. Axis(); gl. Color 3 f(. 98, . 625, . 12); glut. Wire. Sphere(3. 0, 10); gl. Rotatef(theta, 0. , 1. ); gl. Translatef(20. , 0. ); glut. Wire. Sphere(1. 0, 10); gl. Push. Matrix(); gl. Rotatef(theta, 0. , 1. ); gl. Translatef(5. , 0. ); glut. Wire. Sphere(. 5, 10); gl. Pop. Matrix(); gl. Rotatef(theta, 0. , 1. ); 12/2/2020 gl. Translatef(-5. , 0. ); glut. Wire. Sphere(. 5, 10); gl. Flush(); glut. Swap. Buffers(); } void my. Reshape(int width, int height) { gl. Clear. Color (. 75, 0. 0); gl. Viewport(0, 0, width, height); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); gl. Ortho(-size, -size, size); gl. Matrix. Mode(GL_MODELVIEW); } void my. Idle(void) { theta+=0. 5; glut. Post. Redisplay(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 41
lab 10. cpp void my. Mouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state ==GLUT_DOWN) { mouse. State=state; mouse. Button=btn; mouse. X=x; mouse. Y=y; } else if(btn==GLUT_LEFT_BUTTON && state == GLUT_UP) { mouse. State=-1; } else if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { mouse. State=state; mouse. Button=btn; mouse. X=x; mouse. Y=y; } 12/2/2020 else if(btn==GLUT_RIGHT_BUTTON && state == GLUT_UP) { mouse. State=-1; } else if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { x. Theta=y. Theta=z. Theta=0. ; scale=1. 0; } else return; if(idle. Flag && state==GLUT_DOWN) glut. Idle. Func(NULL); else if(idle. Flag && state==GLUT_UP) glut. Idle. Func(my. Idle); glut. Post. Redisplay(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 42
lab 10. cpp void my. Motion(int x, int y) { if(mouse. Button == GLUT_LEFT_BUTTON && mouse. State == GLUT_DOWN) { y. Theta -= (mouse. X - x)/1. ; x. Theta -= (mouse. Y - y)/1. ; } else if(mouse. Button == GLUT_RIGHT_BUTTON && mouse. State == GLUT_DOWN) { if(mouse. Y!=y) scale = scale * pow(scale. Delta, (mouse. Y - y)/1. ); } else return; mouse. X = x; mouse. Y = y; glut. Post. Redisplay(); } void my. Keyboard(unsigned char the. Key, int x, int y) { switch (the. Key) { case ' ' : idle. Flag=!idle. Flag; 12/2/2020 if(idle. Flag) glut. Idle. Func(my. Idle); else glut. Idle. Func(NULL); break; case 27: exit(-1); // esc key } glut. Post. Redisplay(); } void main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_DOUBLE | GLUT_RGB); glut. Init. Window. Size(500, 500); glut. Init. Window. Position(0, 0); glut. Create. Window("lab 09"); glut. Reshape. Func(my. Reshape); glut. Display. Func(my. Display); glut. Mouse. Func(my. Mouse); glut. Motion. Func(my. Motion); glut. Keyboard. Func(my. Keyboard); glut. Main. Loop(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ. 43
Homework 4. • In two weeks • Draw a house with more than 2 windows and 2 doors. • Rotate the house depend on the mouse movement while left mouse button are pressed. 12/2/2020 Computer Graphics, Lee Byung-Gook, Dongseo Univ. 44
- Slides: 44