Title: Computer Graphics 7
1Computer Graphics 7
23D 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. - 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.
3Programming 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.
4Procedure 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.
5Normal vector
- A normal vector to 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.)
6Normal vector
- A normal vector to 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
7Normal 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
8Example
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
9Vertices
- const GLint NumberVertices 8
- GLfloat VerticesNumberVertices3
- 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
-
10Faces
- // A face is defined as indexes into the
vertices array. - const GLint NumberFaces 5
- GLint FacesNumberFaces4
- 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
-
11Normals
- GLfloat NormalsNumberFaces3
- 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
-
12DrawMesh
- void DrawMesh(GLfloat vertices3,
- Glfloat normalVectors3,Glint faces4,
Glint nFaces) -
- for (j0 jltnFaces j)
- glBegin(GL_QUADS)
- glNormal3fv(normalVectorsj)
- glVertex3fv(vertices facesj0)
- glVertex3fv(vertices facesj1)
- glVertex3fv(vertices facesj2)
- glVertex3fv(vertices facesj3)
- glEnd()
-
-
13lab13.cpp
include ltmath.hgt include ltstdio.hgt include
ltwindows.hgt include ltgl/glut.hgt typedef float
vec3_t3 float size3. float theta.0 float t
hetaDelta.125 float eyeDelta.125 float scale1
.0 float scaleDelta1.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 windowHe
ight 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 .25
f, .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
14lab13.cpp
const GLint NumberVertices 8 GLfloat
VerticesNumberVertices3 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
NormalsNumberFaces3 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 FacesNumberFaces4 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
vertices3, GLfloat normalVectors3, GLint
faces4, GLint nFaces) int j for(j0
jltnFaces j) glColor3fv(colorj12) glBe
gin(GL_QUADS) glNormal3fv(normalVectorsj)
glVertex3fv(verticesfacesj0) glVertex3fv(
verticesfacesj1) glVertex3fv(verticesfac
esj2) glVertex3fv(verticesfacesj3)
glEnd()
15lab13.cpp
void myDisplay (void) glClear(GL_COLOR_BUFF
ER_BIT GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() if(!projection) gluLookAt(e
ye0, eye1, eye2, center0, center1,
center2, 0, 1, 0) glRotatef(rot0, 1.0f,
0.0f, 0.0f) glRotatef(rot1, 0.0f, 1.0f,
0.0f) glRotatef(rot2, 0.0f, 0.0f,
1.0f) glScalef(scale, scale, scale) drawMesh(V
ertices, Normals, Faces, NumberFaces) glFlush()
glutSwapBuffers()
void myLookAt(int key) if(key GLUT_KEY_UP)
eye2 eye2-cos(theta)eyeDelta eye0
eye0sin(theta)eyeDelta else if(key
GLUT_KEY_DOWN) eye2 eye2cos(theta)eyeD
elta eye0 eye0-sin(theta)eyeDelta c
enter2 eye2-cos(theta) center0
eye0sin(theta)
16lab13.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) eye2 0. else
gluPerspective(60., (float)width/height, .1,
100.) eye2 5. myLookAt(0) glEnable(
GL_DEPTH_TEST) glCullFace(GL_BACK) glPolygonMo
de(GL_BACK, GL_LINE) glPolygonMode(GL_FRONT,
GL_FILL) windowWidthwidth windowHeightheight
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
thetathetaDelta break default
return myLookAt(key) glutPostRedisplay(
)
17lab13.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' scalescaleDelta break case
'x' scale/scaleDelta break glutPostRe
display() void myMouse(int btn, int state,
int x, int y) if(btnGLUT_LEFT_BUTTON
state GLUT_DOWN) glutIdleFunc(NULL) m
ouseStatestate mouseButtonbtn mouseXx
mouseYy
18lab13.cpp
else if(btnGLUT_LEFT_BUTTON state
GLUT_UP) mouseState-1 else
return glutPostRedisplay() void
myMotion(int x, int y) if(mouseButton
GLUT_LEFT_BUTTON mouseState GLUT_DOWN)
rot1 - (mouseX - x)/5. rot0 -
(mouseY - y)/5. glutPostRedisplay() mouseXx
mouseYy
void main (void) glutInitDisplayMode(GLUT_RGB
GLUT_DOUBLE GLUT_DEPTH) glutInitWindowSi
ze(500,500) glutCreateWindow("lab13 by
lbg_at_dongseo.ac.kr") glutDisplayFunc(myDisplay)
glutReshapeFunc(myResize) glutKeyboardFunc(m
yKeyboard) glutSpecialFunc(mySKeyboard) gl
utMouseFunc(myMouse) glutMotionFunc(myMotion)
glutMainLoop()
19glCullFace
- 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.
20glFrontFace
- 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.
21glPolygonMode
- 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.
223D Modeling Software
23Wavefront 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/form
ats/Format_Obj.html - http//www.zenstar.com/dxfobj.html
24Glm.c
- Nate Robins, 1997, 2000
- nate_at_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.
25Lab 14
- Downloading
- GLMmodel pmodel NULL
- if(pmodel) glmDraw(pmodel, GLM_WIREFRAME)
- name "data/mydata.obj"
- pmodel glmReadOBJ(name)
- glmUnitize(pmodel)
- glmTranslate(hmodeli, trans)
- glmScale(hmodeli, .1)
26Exercise
- Make wavefront obj model file