csc461 lecture 7: 3d programming in opengl
DESCRIPTION
CSC461 Lecture 7: 3D Programming in OpenGL. Objectives: Develop 2D and 3D examples -- Sierpinski gasket: a fractal 3D functions Introduce hidden-surface removal Locate the camera. Three-dimensional Applications. - PowerPoint PPT PresentationTRANSCRIPT
11
CSC461 Lecture 7:3D Programming in OpenGL
Objectives:Objectives:
Develop 2D and 3D examples -- Sierpinski Develop 2D and 3D examples -- Sierpinski gasket: a fractalgasket: a fractal
3D functions3D functions Introduce hidden-surface removalIntroduce hidden-surface removal Locate the cameraLocate the camera
22
Three-dimensional ApplicationsThree-dimensional ApplicationsIn OpenGL, two-dimensional applications are a In OpenGL, two-dimensional applications are a
special case of three-dimensional graphicsspecial case of three-dimensional graphics Not much changesNot much changes Use Use glVertex3*( )glVertex3*( ) Have to worry about the order in which polygons Have to worry about the order in which polygons
are drawn or use hidden-surface removalare drawn or use hidden-surface removal Polygons should be simple, convex, flatPolygons should be simple, convex, flat
33
Sierpinski Gasket (2D)Sierpinski Gasket (2D) Start with a triangleStart with a triangle
Connect bisectors of sides and remove central triangleConnect bisectors of sides and remove central triangle
RepeatRepeat
44
ExampleExample
Four subdivisionsFour subdivisions
55
The gasket as a fractalThe gasket as a fractalConsider the filled area (black) and the perimeter Consider the filled area (black) and the perimeter
(the length of all the lines around the filled (the length of all the lines around the filled triangles)triangles)
As we continue subdividingAs we continue subdividing the area goes to zerothe area goes to zero but the perimeter goes to infinitybut the perimeter goes to infinity
This is not an ordinary geometric objectThis is not an ordinary geometric object It is neither two- nor three-dimensionalIt is neither two- nor three-dimensional
It has a It has a fractalfractal (fractional dimension) object (fractional dimension) object
66
Gasket ProgramGasket Program#include <GL/glut.h>#include <GL/glut.h>
/* a point data type/* a point data typetypedef GLfloat point2[2];typedef GLfloat point2[2];
/* initial triangle *//* initial triangle */
point2 v[]={{-1.0, -0.58}, {1.0, -0.58}, point2 v[]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};{0.0, 1.15}};
int n; /* number of recursive steps */int n; /* number of recursive steps */
77
Draw a triangleDraw a trianglevoid triangle( point2 a, point2 b, point2 void triangle( point2 a, point2 b, point2 c)c)
/* display one triangle *//* display one triangle */{{ glBegin(GL_TRIANGLES); glBegin(GL_TRIANGLES); glVertex2fv(a); glVertex2fv(a); glVertex2fv(b); glVertex2fv(b); glVertex2fv(c);glVertex2fv(c); glEnd();glEnd();}}
88
Triangle SubdivisionTriangle Subdivisionvoid divide_triangle(point2 a, point2 b, point2 c, void divide_triangle(point2 a, point2 b, point2 c, int m)int m)
{{/* triangle subdivision using vertex numbers *//* triangle subdivision using vertex numbers */ point2 v0, v1, v2;point2 v0, v1, v2; int j;int j; if(m>0)if(m>0) {{ for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2;for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2; for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2;for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2; for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2; divide_triangle(a, v0, v1, m-1);divide_triangle(a, v0, v1, m-1); divide_triangle(c, v1, v2, m-1);divide_triangle(c, v1, v2, m-1); divide_triangle(b, v2, v0, m-1);divide_triangle(b, v2, v0, m-1); }} else(triangle(a,b,c));else(triangle(a,b,c)); /* draw triangle at end of recursion *//* draw triangle at end of recursion */}}
99
Display and Display and InitInit Functions Functionsvoid display(void)void display(void){{ glClear(GL_COLOR_BUFFER_BIT);glClear(GL_COLOR_BUFFER_BIT); divide_triangle(v[0], v[1], v[2], n);divide_triangle(v[0], v[1], v[2], n); glFlush();glFlush();}}
void myinit()void myinit(){{ glMatrixMode(GL_PROJECTION);glMatrixMode(GL_PROJECTION); glLoadIdentity();glLoadIdentity(); gluOrtho2D(-2.0, 2.0, -2.0, 2.0);gluOrtho2D(-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_MODELVIEW); glClearColor (1.0, 1.0, 1.0,1.0)glClearColor (1.0, 1.0, 1.0,1.0) glColor3f(0.0,0.0,0.0);glColor3f(0.0,0.0,0.0);}}
1010
mainmain Function Functionint main(int argc, char **argv)int main(int argc, char **argv){{ n=4;n=4; glutInit(&argc, argv);glutInit(&argc, argv); glutInitDisplayModeglutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500, 500);glutInitWindowSize(500, 500); glutCreateWindow(“2D Gasket");glutCreateWindow(“2D Gasket"); glutDisplayFunc(display);glutDisplayFunc(display); myinit();myinit(); glutMainLoop();glutMainLoop();} }
1111
Moving to 3DMoving to 3DWe can easily make the program three-We can easily make the program three-
dimensional by using dimensional by using typedef Glfloat point3[3]typedef Glfloat point3[3]glVertex3fglVertex3fglOrthoglOrtho
But that would not be very interestingBut that would not be very interestingInstead, we can start with a tetrahedronInstead, we can start with a tetrahedron
1212
3D Gasket3D GasketWe can subdivide each of the four facesWe can subdivide each of the four faces
Appears as if we remove a solid tetrahedron Appears as if we remove a solid tetrahedron from the center leaving four smaller tetrahedtrafrom the center leaving four smaller tetrahedtra
1313
Example Example
After 4 interations
1414
triangle codetriangle code
void triangle( point a, point b, void triangle( point a, point b, point c)point c){{ // right-hand rule// right-hand rule glBegin(GL_POLYGON);glBegin(GL_POLYGON); glVertex3fv(a);glVertex3fv(a); glVertex3fv(b);glVertex3fv(b); glVertex3fv(c);glVertex3fv(c); glEnd();glEnd();}}
1515
subdivision codesubdivision codevoid divide_triangle(point a, point b, point c, void divide_triangle(point a, point b, point c, int m)int m)
{{ point v1, v2, v3;point v1, v2, v3; int j;int j; if(m>0)if(m>0) {{ for(j=0; j<3; j++) v1[j]=(a[j]+b[j])/2;for(j=0; j<3; j++) v1[j]=(a[j]+b[j])/2; for(j=0; j<3; j++) v2[j]=(a[j]+c[j])/2;for(j=0; j<3; j++) v2[j]=(a[j]+c[j])/2; for(j=0; j<3; j++) v3[j]=(b[j]+c[j])/2;for(j=0; j<3; j++) v3[j]=(b[j]+c[j])/2; divide_triangle(a, v1, v2, m-1);divide_triangle(a, v1, v2, m-1); divide_triangle(c, v2, v3, m-1);divide_triangle(c, v2, v3, m-1); divide_triangle(b, v3, v1, m-1);divide_triangle(b, v3, v1, m-1); }} else(triangle(a,b,c));else(triangle(a,b,c));}}
1616
tetrahedron codetetrahedron codevoid tetrahedron( int m)void tetrahedron( int m){{ glColor3f(1.0,0.0,0.0);glColor3f(1.0,0.0,0.0); divide_triangle(v[0], v[1], v[2], m);divide_triangle(v[0], v[1], v[2], m); glColor3f(0.0,1.0,0.0);glColor3f(0.0,1.0,0.0); divide_triangle(v[3], v[2], v[1], m);divide_triangle(v[3], v[2], v[1], m); glColor3f(0.0,0.0,1.0);glColor3f(0.0,0.0,1.0); divide_triangle(v[0], v[3], v[1], m);divide_triangle(v[0], v[3], v[1], m); glColor3f(0.0,0.0,0.0);glColor3f(0.0,0.0,0.0); divide_triangle(v[0], v[2], v[3], m);divide_triangle(v[0], v[2], v[3], m);}}
1717
ProblemProblem Because the triangles are drawn in the Because the triangles are drawn in the order they are defined in the program, the order they are defined in the program, the front triangles are not always rendered in front triangles are not always rendered in front of triangles behind themfront of triangles behind them
get this
want this
1818
Solution:Solution: Hidden-Surface Removal Hidden-Surface Removal We want to see only those surfaces in front of other We want to see only those surfaces in front of other
surfacessurfaces OpenGL uses a OpenGL uses a hidden-surfacehidden-surface method called the method called the zz--
buffer algorithm that saves depth information as objects buffer algorithm that saves depth information as objects are rendered so that only the front objects appear in the are rendered so that only the front objects appear in the imageimage
1919
Using the Using the zz-buffer algorithm-buffer algorithm The algorithm uses an extra buffer, the z-buffer, to store The algorithm uses an extra buffer, the z-buffer, to store
depth information as geometry travels down the pipelinedepth information as geometry travels down the pipeline It must beIt must be
Requested in Requested in main.cmain.c glutInitDisplayModeglutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
Enabled inEnabled in init.c init.c glEnable(GL_DEPTH_TEST)glEnable(GL_DEPTH_TEST)
Cleared in the display callbackCleared in the display callback glClear(GL_COLOR_BUFFER_BIT | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)GL_DEPTH_BUFFER_BIT)
2020
Default camera settingDefault camera setting With default, camera is located at the origin and With default, camera is located at the origin and
oriented at the negative z-axesoriented at the negative z-axes If place a cube at the origin, only one side of the cube If place a cube at the origin, only one side of the cube
is visibleis visible Look at objects from Look at objects from
different anglesdifferent angles Move the objectsMove the objects Move the cameraMove the camera
Example – a cubeExample – a cube
2121
Locating the cameraLocating the camera Position and orient the camera – three inputsPosition and orient the camera – three inputs
Eye, at, and direction – upEye, at, and direction – up Camera is on Model-View modeCamera is on Model-View mode
2222
Set ViewingSet Viewing Glu functionGlu function
void gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, void gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz)upy, upz)
Set viewing -- exampleSet viewing -- exampleglMatrixMode(GL_MODELVIEW);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glLoadIdentity();gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);0.0, 1.0, 0.0); // Camera located at (1,1,1), oriented to the origin, and // Camera located at (1,1,1), oriented to the origin, and
directed up along y-axisdirected up along y-axis
2323
Code: Display a cubeCode: Display a cubevoid display() void display() {{
glClear(GL_COLOR_BUFFER_BIT);glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glLoadIdentity();gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);0.0);cube();cube();glFlush();glFlush();
}}