270 likes | 576 Views
Computer Graphics 7. Lee Byung-Gook. 3D Modeling Data. polygonal mesh - a collection of polygons each polygon is defined by its vertices and its front (vs. back ) face defined by its normal vector .
E N D
Computer Graphics 7 Lee Byung-Gook Computer Graphics, Lee Byung-Gook, Dongseo Univ.
3D Modeling Data • polygonal mesh - a collection of polygonseach polygon is defined by its vertices and its front (vs. back) face defined by its normal vector. • Uses: a polygonal mesh can be used to define any type of object, but it is required when an object cannot be defined as a collection of standard solid primitives, such as cubes, spheres and cylinders. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Programming polygonal meshes • A polygonal mesh is usually interconnected. That is, the polygons share vertices. An efficient representation of a polygonal mesh should not store duplicate data. • Three basic things need to be stored: • the vertices (geometric information) • the face normal vectors (orientation information) • which vertices define a specific face (topological information). • Assuming that all of the polygons have the same number of vertices, the data can efficiently be stored in arrays and processed using simple loops. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Procedure to create a polygonal mesh • Draw a good sketch of the object. • Label each vertex with an index, starting with 0. • Store the vertices in an array consistent with the vertex labels. (That is, store vertex 3 in position 3 of the array.) • Label each face with an index, starting with 0. • Calculate the normal vectors to each face and store them in an array consistent with the face labels. (That is, store the normal vector for face 3 in position 3 of the array.) • Store the indexes of the vertices that make up each face in a "face array" and make them consistent with the face labels. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Normal vector • A normal vectorto a plane is a vector that is at right angles to every vector that lies in the plane. (There are two such vectors for any given plane.) Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Normal vector • A normal vectorto a face is a vector that is at right angles to every vector that lies in the plane and it points away from the "front side". Looking at the back side Looking at the front side Computer Graphics, Lee Byung-Gook, Dongseo Univ.
v1 v2 v3 v2 v0 v3 v0 v1 Normal vector • To calculate the face normal, take the cross product of two consecutive edges of the face. To get the correct normal vector, always specify the vertices of the face in a counter-clockwise direction when looking at the front of the face. counter-clockwise from front counter-clockwise from front Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Example Y 4 (back face) 4 5 3 (left face) Open Side 1 6 7 2 1 X 0 (origin) 2 3 0 (bottom face) Z Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Vertices const GLint NumberVertices = 8; GLfloat Vertices[NumberVertices][3] = { {0.0, 0.0, 0.0}, // vertex 0 {1.0, 0.0, 0.0}, // vertex 1 {1.0, 0.0, 1.0}, // vertex 2 {0.0, 0.0, 1.0}, // vertex 3 {0.0, 1.0, 0.0}, // vertex 4 {1.0, 1.0, 0.0}, // vertex 5 {1.0, 1.0, 1.0}, // vertex 6 {0.0, 1.0, 1.0} // vertex 7 }; Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Faces // A face is defined as indexes into the vertices array. const GLint NumberFaces = 5; GLint Faces[NumberFaces][4] = { {0, 1, 2, 3}, // face 0 {4, 7, 6, 5}, // face 1 {2, 6, 7, 3}, // face 2 {3, 7, 4, 0}, // face 3 {4, 5, 1, 0} // face 4 }; Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Normals GLfloat Normals[NumberFaces][3] = { { 0.0,-1.0, 0.0}, // face 0 { 0.0, 1.0, 0.0}, // face 1 { 0.0, 0.0, 1.0}, // face 2 {-1.0, 0.0, 0.0}, // face 3 { 0.0, 0.0,-1.0} // face 4 }; Computer Graphics, Lee Byung-Gook, Dongseo Univ.
DrawMesh void DrawMesh(GLfloat vertices[][3], Glfloat normalVectors[][3],Glint faces[][4], Glint nFaces) { for (j=0; j<nFaces; j++) { glBegin(GL_QUADS); glNormal3fv(normalVectors[j]); glVertex3fv(vertices[ faces[j][0]]); glVertex3fv(vertices[ faces[j][1]]); glVertex3fv(vertices[ faces[j][2]]); glVertex3fv(vertices[ faces[j][3]]); glEnd(); } } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp #include <math.h> #include <stdio.h> #include <windows.h> #include <gl/glut.h> typedef float vec3_t[3]; float size=3.; float theta=.0; float thetaDelta=.125; float eyeDelta=.125; float scale=1.0; float scaleDelta=1.125; int mouseX = 0; int mouseY = 0; int mouseState = 0; int mouseButton = 0; int projection = 0; int aniOn = 0; int depthOn = 1; int openOn = 0; int fillOn = 1; int frontface = 0; int cullface = 0; int windowWidth; int windowHeight; vec3_t rot = {0.,0.,0.}; vec3_t eye = {0.,0.,-5.}; vec3_t center = {0.,0.,0.}; vec3_t color[] = { {1.0f, 0.0f, 0.0f}, //red {0.0f, 1.0f, 0.0f}, //green {0.0f, 0.0f, 1.0f}, //blue {1.0f, 1.0f, 0.0f}, //yellow {1.0f, 0.0f, 1.0f}, //magenta {0.0f, 1.0f, 1.0f}, //cyan {1.0f, 1.0f, 1.0f}, //white {.25f, .25f, .25f}, //dark gray {.60f, .40f, .70f}, //barney purple {.98f, .625f, .12f}, //pumpkin orange {.98f, .04f, .70f}, //pastel pink {.75f, .75f, .75f}, //light gray {.60f, .40f, .12f} //brown }; Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp const GLint NumberVertices = 8; GLfloat Vertices[NumberVertices][3] = { {0.0, 0.0, 0.0}, // vertex 0 {1.0, 0.0, 0.0}, // vertex 1 {1.0, 0.0, 1.0}, // vertex 2 {0.0, 0.0, 1.0}, // vertex 3 {0.0, 1.0, 0.0}, // vertex 4 {1.0, 1.0, 0.0}, // vertex 5 {1.0, 1.0, 1.0}, // vertex 6 {0.0, 1.0, 1.0} }; // vertex 7 const GLint NumberFaces = 5; GLfloat Normals[NumberFaces][3] = { { 0.0,-1.0, 0.0}, // face 0 { 0.0, 1.0, 0.0}, // face 1 { 0.0, 0.0, 1.0}, // face 2 {-1.0, 0.0, 0.0}, // face 3 { 0.0, 0.0,-1.0} }; // face 4 GLint Faces[NumberFaces][4] = { {0, 1, 2, 3}, // face 0 {4, 7, 6, 5}, // face 1 {2, 6, 7, 3}, // face 2 {3, 7, 4, 0}, // face 3 {4, 5, 1, 0} }; // face 4 void drawMesh(GLfloat vertices[][3], GLfloat normalVectors[][3], GLint faces[][4], GLint nFaces) { int j; for(j=0; j<nFaces; j++) { glColor3fv(color[j%12]); glBegin(GL_QUADS); glNormal3fv(normalVectors[j]); glVertex3fv(vertices[faces[j][0]]); glVertex3fv(vertices[faces[j][1]]); glVertex3fv(vertices[faces[j][2]]); glVertex3fv(vertices[faces[j][3]]); glEnd(); } } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp void myDisplay (void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if(!projection) gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0); glRotatef(rot[0], 1.0f, 0.0f, 0.0f); glRotatef(rot[1], 0.0f, 1.0f, 0.0f); glRotatef(rot[2], 0.0f, 0.0f, 1.0f); glScalef(scale, scale, scale); drawMesh(Vertices, Normals, Faces, NumberFaces); glFlush(); glutSwapBuffers(); } void myLookAt(int key) { if(key == GLUT_KEY_UP) { eye[2] = eye[2]-cos(theta)*eyeDelta; eye[0] = eye[0]+sin(theta)*eyeDelta; } else if(key == GLUT_KEY_DOWN) { eye[2] = eye[2]+cos(theta)*eyeDelta; eye[0] = eye[0]-sin(theta)*eyeDelta; } center[2] = eye[2]-cos(theta); center[0] = eye[0]+sin(theta); } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp void myResize (int width, int height){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(projection) { glOrtho(-size, size, -size, size, -size, size); eye[2] = 0.; } else { gluPerspective(60., (float)width/height, .1, 100.); eye[2] = 5.; myLookAt(0); } glEnable(GL_DEPTH_TEST); glCullFace(GL_BACK); glPolygonMode(GL_BACK, GL_LINE); glPolygonMode(GL_FRONT, GL_FILL); windowWidth=width; windowHeight=height; } void mySKeyboard (int key, int x, int y) { switch (key) { case GLUT_KEY_UP : break; case GLUT_KEY_DOWN : break; case GLUT_KEY_LEFT : theta-=thetaDelta; break; case GLUT_KEY_RIGHT : theta+=thetaDelta; break; default : return; } myLookAt(key); glutPostRedisplay(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp void myKeyboard (unsigned char key, int x, int y) { switch (key) { case 'p': projection = !projection; myResize(windowWidth, windowHeight); break; case 'd': depthOn = !depthOn; if(depthOn) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); break; case 'f': frontface = !frontface; if(frontface) glFrontFace(GL_CW); else glFrontFace(GL_CCW); break; case 'c': cullface = !cullface; if(cullface) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); break; case 'z': scale*=scaleDelta; break; case 'x': scale/=scaleDelta; break; } glutPostRedisplay(); } void myMouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) { glutIdleFunc(NULL); mouseState=state; mouseButton=btn; mouseX=x; mouseY=y; } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
lab13.cpp else if(btn==GLUT_LEFT_BUTTON && state == GLUT_UP) mouseState=-1; else return; glutPostRedisplay(); } void myMotion(int x, int y) { if(mouseButton == GLUT_LEFT_BUTTON && mouseState == GLUT_DOWN) { rot[1] -= (mouseX - x)/5.; rot[0] -= (mouseY - y)/5.; glutPostRedisplay(); mouseX=x; mouseY=y; } } void main (void) { glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500,500); glutCreateWindow("lab13 by lbg@dongseo.ac.kr"); glutDisplayFunc(myDisplay); glutReshapeFunc(myResize); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySKeyboard); glutMouseFunc(myMouse); glutMotionFunc(myMotion); glutMainLoop(); } Computer Graphics, Lee Byung-Gook, Dongseo Univ.
glCullFace • glCullFace - specify whether front- or back-facing facets can be culled • void glCullFace( GLenum mode ) • PARAMETERS mode Specifies whether front- or back-facing facets are candidates for culling. Symbolic constants GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK are accepted. The initial value is GL_BACK. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
glFrontFace • glFrontFace - define front- and back-facing polygons • void glFrontFace( GLenum mode ) • PARAMETERS mode Specifies the orientation of front-facing polygons. GL_CW and GL_CCW are accepted. The initial value is GL_CCW. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
glPolygonMode • glPolygonMode - select a polygon rasterization mode • void glPolygonMode( GLenum face, GLenum mode ) • PARAMETERS face Specifies the polygons that mode applies to. Must be GL_FRONT for front-facing polygons, GL_BACK for back- facing polygons, or GL_FRONT_AND_BACK for front- and back-facing polygons. mode Specifies how polygons will be rasterized. Accepted values are GL_POINT, GL_LINE, and GL_FILL. The initial value is GL_FILL for both front- and back- facing polygons. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
3D Modeling Software Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Wavefront obj file format • http://www.cica.indiana.edu/graphics/object_specs/OBJ.format.txt • http://www.okino.com/conv/exp_wave.htm • http://www-sfb288.math.tu-berlin.de/eg-models/formats/Format_Obj.html • http://www.zenstar.com/dxfobj.html Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Glm.c Nate Robins, 1997, 2000 nate@pobox.com, http://www.pobox.com/~nate Wavefront OBJ model file format reader/writer/manipulator. Includes routines for generating smooth normals with preservation of edges, welding redundant vertices & texture coordinate generation (spheremap and planar projections) + more. Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Lab 14 • Downloading GLMmodel *pmodel = NULL; if(pmodel) glmDraw(pmodel, GLM_WIREFRAME); name = "data/mydata.obj"; pmodel = glmReadOBJ(name); glmUnitize(pmodel); glmTranslate(hmodel[i], trans); glmScale(hmodel[i], .1); Computer Graphics, Lee Byung-Gook, Dongseo Univ.
Exercise • Make wavefront obj model file Computer Graphics, Lee Byung-Gook, Dongseo Univ.