테셀레이션과 이차곡면 - suwon

테셀레이션과 이차곡면 - suwon

11 2013-2 1 , ,

2013-2 2 OpenGL , GLU 2013-2

3 gluNewTess() . gluTessCallback() gluTessProperty() . (winding rule). . . gluDeleteTess() .

2013-2 4 gluNewTess() . GLUtesselator* gluNewTess(void); , null 2013-2

5 . GLU , . . gluTessCallback()

void gluTessCallback(GLUtesselator *tessobj, Glenum type, void *(fn)()); fn tessobj , type : GLU_TESS_BEGIN, GLU_TESS_BEGIN_DATA, GLU_TESS_EDGE_FLAG, GLU_TESS_EDGE_FLAG_DATA, GLU_TESS_VERTEX, GLU_TESS_VERTEX_DATA, GLU_TESS_END, GLU_TESS_END_DATA, GLU_TESS_COMBINE, GLU_TESS_COMBINE_DATA, GLU_TESS_ERROR, GLU_TESS_ERROR_DATA 2013-2 6 . OpenGL (glBegin(), glVertex*(), glEdgeFlag*(), glEnd())

. ) tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); GLU_TESS_BEGIN GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, GL_TRIANGLES, GL_LINE_LOOP . GLU_TESS_BOUNDARY_ONLY GL_LINE_LOOP GLU_TESS_EDGE_FLAG GLU_TESS_BEGIN GL_TRIANGLES . 2013-2 7

GLU_TESS_BEGIN GLU_TESS_END_VERTEX , GLU_TESS_EDGE_FLAG GLU_TESS_VERTEX . GLU . 2013-2 8 GLU_TESS_BEGIN

void begin(GLenum type); GLU_TESS_BEGIN_DATA void begin(GLenum type, void *user_data); GLU_TESS_EDGE_FLAG void edgeFlag(GLboolean flag); GLU_TESS_EDGE_FLAG_DATA void edgeFlag(GLboolean flag, void *user_data); GLU_TESS_VERTEX void vertex(void *vertex_data); GLU_TESS_VERTEX_DATA void vertex(void *vertex_data, void *user_data);

GLU_TESS_END void end(void); 2013-2 9 GLU_TESS_END_DATA void end(GLenum type); GLU_TESS_COMBINE void combine(GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData);

GLU_TESS_COMBINE_DATA void combine(GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData, void *user_data); GLU_TESS_ERROR void error(GLenum errno); GLU_TESS_ERROR_DATA void error(GLenum errno, void *user_data); 2013-2 10

: tess.c (1) void CALLBACK beginCallback(GLenum which) { glBegin(which); } void CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf(stderr, "Tessellation Error: %s\n", estring); exit(0); } 2013-2

11 : tess.c (2) void CALLBACK endCallback(void) { glEnd(); } void CALLBACK vertexCallback(GLvoid *vertex) { const GLdouble *pointer; pointer = (GLdouble *) vertex; glColor3dv(pointer+3); glVertex3dv(vertex); } 2013-2 12

: tess.c (3) tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); Microsoft Windows CALLBACK . #ifdef CALLBACK #define CALLBACK #endif void CALLBACK callbackFunction() { } 2013-2

13 : tess.c (1) /* combineCallback is used to create a new vertex when edges * intersect. coordinate location is trivial to calculate, * but weight[4] may be used to average color, normal, or texture * coordinate data. In this program, color is weighted. */ void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut ) { GLdouble *vertex; int i; vertex = (GLdouble *) malloc(6 * sizeof(GLdouble)); 2013-2 14

: tess.c (2) vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; for (i = 3; i < 6; i++) vertex[i] = weight[0] * vertex_data[0][i] + weight[1] * vertex_data[1][i] + weight[2] * vertex_data[2][i] + weight[3] * vertex_data[3][i]; *dataOut = vertex; } , , GLU_TESS_COMBINE

vertex_data[0..3] . weight[0..3] 1.0 2013-2 15 , 12 gluTessBeginPolygon() *DATA , .

GLU_TESS_BEGIN_DATA . user_data , 12 6 . 2013-2 16

gluTessProperty() , . void gluTessProperty(GLUtesselator *tessobj, GLenum property, GLdouble value); tessobj , property value . property: GLU_TESS_BOUNDARY_ONLY, GLU_TESS_TOLERANCE, GLU_TESS_WINDING_RULE property GLU_TESS_BOUNDARY_ONLY value GL_TRUE GL_FALSE GL_TRUE .

. GL_FALSE 2013-2 17 property GLU_TESS_TOLERANCE value GL_TRUE GL_FALSE( ) value GLU_TESS_COMBINE . property GLU_TESS_WINDING , . value GLU_TESS_WINDING_ODD( ), GLU_TESS_WINDING_NONZERO, GLU_TESS_WINDING_POSITIVE, GLU_TESS_WINDING_NEGATIVE, GLU_TESS_WINDING_ABS_GEQ_TWO

2013-2 18 . . .

( , , , 0 , 2 ) . 0 . , , 2 CSG(Computational Solid Geometry) . 2013-2 19 : tesswind.c 1 2 3 1 1

0 -1 1 2 1 2013-2 1 1 20 2013-2

21 : tesswind.c /* * tesswind.c * This program demonstrates the winding rule polygon * tessellation property. Four tessellated objects are drawn, * each with very different contours. When the w key is pressed, * the objects are drawn with a different winding rule. */ #include #include #include #ifndef CALLBACK #define CALLBACK #endif GLdouble currentWinding = GLU_TESS_WINDING_ODD; int currentShape = 0; 2013-2

22 GLUtesselator *tobj; GLuint list; /* Make four display lists, * each with a different tessellated object. */ void makeNewLists (void) { int i; static GLdouble rects[12][3] = {50.0, 50.0, 0.0, 300.0, 50.0, 0.0, 300.0, 300.0, 0.0, 50.0, 300.0, 0.0, 100.0, 100.0, 0.0, 250.0, 100.0, 0.0, 250.0, 250.0, 0.0, 100.0, 250.0, 0.0, 150.0, 150.0, 0.0, 200.0, 150.0, 0.0, 200.0, 200.0, 0.0, 150.0, 200.0, 0.0}; 2013-2

23 static GLdouble spiral[16][3] = {400.0, 250.0, 0.0, 400.0, 50.0, 0.0, 50.0, 50.0, 0.0, 50.0, 400.0, 0.0, 350.0, 400.0, 0.0, 350.0, 100.0, 0.0, 100.0, 100.0, 0.0, 100.0, 350.0, 0.0, 300.0, 350.0, 0.0, 300.0, 150.0, 0.0, 150.0, 150.0, 0.0, 150.0, 300.0, 0.0, 250.0, 300.0, 0.0, 250.0, 200.0, 0.0, 200.0, 200.0, 0.0, 200.0, 250.0, 0.0}; static GLdouble quad1[4][3] = {50.0, 150.0, 0.0, 350.0, 150.0, 0.0, 350.0, 200.0, 0.0, 50.0, 200.0, 0.0}; static GLdouble quad2[4][3] = {100.0, 100.0, 0.0, 300.0, 100.0, 0.0, 300.0, 350.0, 0.0, 100.0, 350.0, 0.0}; static GLdouble tri[3][3] = {200.0, 50.0, 0.0, 250.0, 300.0, 0.0,

150.0, 300.0, 0.0}; 2013-2 24 gluTessProperty(tobj, GLU_TESS_WINDING_RULE, currentWinding); glNewList(list, GL_COMPILE); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); for (i = 0; i < 4; i++) gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj); gluTessBeginContour(tobj); for (i = 4; i < 8; i++) gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj); gluTessBeginContour(tobj); for (i = 8; i < 12; i++)

gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj); gluTessEndPolygon(tobj); glEndList(); 2013-2 25 glNewList(list+1, GL_COMPILE); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); for (i = 0; i < 4; i++) gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj); gluTessBeginContour(tobj); for (i = 7; i >= 4; i--) gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj);

gluTessBeginContour(tobj); for (i = 11; i >= 8; i--) gluTessVertex(tobj, rects[i], rects[i]); gluTessEndContour(tobj); gluTessEndPolygon(tobj); glEndList(); 2013-2 26 glNewList(list+2, GL_COMPILE); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); for (i = 0; i < 16; i++) gluTessVertex(tobj, spiral[i], spiral[i]); gluTessEndContour(tobj); gluTessEndPolygon(tobj); glEndList(); glNewList(list+3, GL_COMPILE);

gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); for (i = 0; i < 4; i++) gluTessVertex(tobj, quad1[i], quad1[i]); gluTessEndContour(tobj); gluTessBeginContour(tobj); for (i = 0; i < 4; i++) gluTessVertex(tobj, quad2[i], quad2[i]); gluTessEndContour(tobj); 2013-2 27 gluTessBeginContour(tobj); for (i = 0; i < 3; i++) gluTessVertex(tobj, tri[i], tri[i]); gluTessEndContour(tobj); gluTessEndPolygon(tobj);

glEndList(); } void display (void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glPushMatrix(); glCallList(list); glTranslatef(0.0, 500.0, 0.0); glCallList(list+1); glTranslatef(500.0, -500.0, 0.0); glCallList(list+2); glTranslatef(0.0, 500.0, 0.0); glCallList(list+3); 2013-2 28 glPopMatrix();

glFlush(); } void CALLBACK beginCallback(GLenum which) { glBegin(which); } void CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf(stderr, "Tessellation Error: %s\n", estring); exit(0); } 2013-2 29 void CALLBACK endCallback(void) {

glEnd(); } /* combineCallback is used to create a new vertex when edges * intersect. coordinate location is trivial to calculate, * but weight[4] may be used to average color, normal, or texture * coordinate data. */ void CALLBACK combineCallback(GLdouble coords[3], GLdouble *data[4], GLfloat weight[4], GLdouble **dataOut ) { GLdouble *vertex; vertex = (GLdouble *) malloc(3 * sizeof(GLdouble)); 2013-2 30 vertex[0] = coords[0]; vertex[1] = coords[1];

vertex[2] = coords[2]; *dataOut = vertex; } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); 2013-2 31 gluTessCallback(tobj, GLU_TESS_ERROR,

errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, combineCallback); list = glGenLists(4); makeNewLists(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) gluOrtho2D(0.0, 1000.0, 0.0, 1000.0 * (GLdouble)h/(GLdouble)w); else 2013-2 32

gluOrtho2D(0.0, 1000.0 * (GLdouble)w/(GLdouble)h, 0.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'w': case 'W': if (currentWinding == GLU_TESS_WINDING_ODD) currentWinding = GLU_TESS_WINDING_NONZERO; else if (currentWinding == GLU_TESS_WINDING_NONZERO) currentWinding = GLU_TESS_WINDING_POSITIVE; else if (currentWinding == GLU_TESS_WINDING_POSITIVE) currentWinding = GLU_TESS_WINDING_NEGATIVE; 2013-2

33 else if (currentWinding == GLU_TESS_WINDING_NEGATIVE) currentWinding = GLU_TESS_WINDING_ABS_GEQ_TWO; else if (currentWinding == GLU_TESS_WINDING_ABS_GEQ_TWO) currentWinding = GLU_TESS_WINDING_ODD; makeNewLists(); glutPostRedisplay(); break; case 27: exit(0); break; default: break; } } 2013-2

34 int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2013-2

35 2013-2 36 CSG(Constructive Solid Geometry) GLU_TESS_WINDING_ODD GLU_TESS_WINDING_NONZERO , . CSG , . 0 , 1

. , . 2013-2 37 CSG GLU_TESS_WINDING_NONZERO GLU_TESS_WINDING_POSITIVE . . GLU_TESS_WINDING_ABS_GEQ_TWO

A (B, C, D ) GLU_TESS_WINDING_POSITIVE 2013-2 38 gluTessProperty() . gluGetTessProperty() gluTessNormal() void gluGetTessProperty(GLUtesselator *tessobj, GLenum property, GLdouble *value);

void gluTessNormal(GLUtesselator *tessobj, GLdouble x, GLdouble y, GLdouble z); 2013-2 39 , , void gluTessBeginPolygon(GLUtesselator *tessobj, void *user_data);

void gluTessEndPolygon(GLUtessellator *tessobj); . gluTessBeginPolygon() gluTessEndPolygon() , 2013-2 40

. void gluTessBeginCountour(GLUtesselator *tessobj); void gluTessEndCountour(GLUesselator *tessobj); void gluTessVertex(GLUtesselator *tessobj, Gldouble coords[3] , void *vertex_data); coords 3 vertex_data GLU_TESS_VERTEX GLU_TESS_VERTEX_DATA , , , 2013-2 41 11-3 : tess.c

#include #include #include #ifndef CALLBACK #define CALLBACK #endif GLuint startList; void display (void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glCallList(startList); glCallList(startList + 1); glFlush(); } 2013-2 42

void CALLBACK beginCallback(GLenum which) { glBegin(which); } void CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf(stderr, "Tessellation Error: %s\n", estring); exit(0); } 2013-2 43 void CALLBACK endCallback(void) { glEnd();

} void CALLBACK vertexCallback(GLvoid *vertex) { const GLdouble *pointer; pointer = (GLdouble *) vertex; glColor3dv(pointer+3); glVertex3dv(vertex); } 2013-2 44 void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut ) { GLdouble *vertex; int i; vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));

vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; 2013-2 45 for (i = 3; i < 6; i++) vertex[i] = weight[0] * vertex_data[0][i] + weight[1] * vertex_data[1][i] + weight[2] * vertex_data[2][i] + weight[3] * vertex_data[3][i]; *dataOut = vertex; } void init (void) { GLUtesselator *tobj;

2013-2 46 GLdouble rect[4][3] = {50.0, 50.0, 0.0, 200.0, 50.0, 0.0, 200.0, 200.0, 0.0, 50.0, 200.0, 0.0}; GLdouble tri[3][3] = {75.0, 75.0, 0.0, 125.0, 175.0, 0.0, 175.0, 75.0, 0.0}; GLdouble star[5][6] = {250.0, 50.0, 0.0, 1.0, 0.0, 1.0, 325.0, 200.0, 0.0, 1.0, 1.0, 0.0, 400.0, 50.0, 0.0, 0.0, 1.0, 1.0, 250.0, 150.0, 0.0, 1.0, 0.0, 0.0, 400.0, 150.0, 0.0, 0.0, 1.0, 0.0}; 2013-2

47 glClearColor(0.0, 0.0, 0.0, 0.0); startList = glGenLists(2); tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); 2013-2 48

glNewList(startList, GL_COMPILE); glShadeModel(GL_FLAT); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); gluTessVertex(tobj, rect[0], rect[0]); gluTessVertex(tobj, rect[1], rect[1]); gluTessVertex(tobj, rect[2], rect[2]); gluTessVertex(tobj, rect[3], rect[3]); gluTessEndContour(tobj); gluTessBeginContour(tobj); gluTessVertex(tobj, tri[0], tri[0]); gluTessVertex(tobj, tri[1], tri[1]); gluTessVertex(tobj, tri[2], tri[2]); gluTessEndContour(tobj); 2013-2 49

gluTessEndPolygon(tobj); glEndList(); gluTessCallback(tobj, GLU_TESS_VERTEX, vertexCallback); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, combineCallback); 2013-2 50 glNewList(startList + 1, GL_COMPILE);

glShadeModel(GL_SMOOTH); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); gluTessVertex(tobj, star[0], star[0]); gluTessVertex(tobj, star[1], star[1]); gluTessVertex(tobj, star[2], star[2]); gluTessVertex(tobj, star[3], star[3]); gluTessVertex(tobj, star[4], star[4]); gluTessEndContour(tobj); 2013-2 51 gluTessEndPolygon(tobj); glEndList(); gluDeleteTess(tobj);

} void reshape (int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); } 2013-2 52 void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break;

} } 2013-2 53 int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;

} 2013-2 54 2013-2 55 . void gluDeleteTess(GLUtesselator *tessobj); tessobj , 2013-2

56 gluTessNormal() 2013-2

57 GLU GLU NURBS quadric , GL 2013-2 58 , , OpenGL ,

, , , 2D, 3D (2 ) GLU gluNewQuadric() , gluQuadricOrientation() , , gluQuadricDrawStyle() 2013-2

59 gluQuadricNormals() . gluQuadricTexture() gluQuadricCallback() - gluSphere(), gluCylinder(), gluDisk(), gluPartialDisk() , gluDeleteQuadric() . 2013-2 60

GLUquadricObj , , . , , , . GLUquadricObj *gluNewQuadric(void); , void gluDeleteQuadric(GLUquadricObj *qobj); qobj void gluQuadricCallback(GLUquadricObj *qobj, GLenum which, void (*fn)()); fn 2013-2

61 . void gluQuadricDrawStyle(GLUquadricObj *qobj, GLenum drawStyle); qobj, drawStyle drawStyle : GLU_POINT, GLU_LINE, GLU_SILHOUETTE, GLU_FILL GLU_SILHOUETTE: , . gluDisk(), gluPartialDisk()

void gluQuadricOrientation(GLUquadricObj *qobj, GLenum orientation); qobj, orientation GLU_OUTSIDE( ) GLU_INSIDE , 2013-2 62 void gluQuadricNormals(GLUquadriObj *qobj, GLenum normals); qobj, normals GLU_NONE( ), GLU_FLAT, GLU_SMOOTH .

void gluQuadricTexture(GLUquadricObj *qobj, GLboolean textureCoords); qobj textureCoords GL_FALSE( ) GL_TRUE . 2013-2 63 void gluSphere(GLUquadricObi *qobj, GLdouble radius, GLint slices, GLint stacks);

(0,0,0) radius . z slices ( ) z stack ( ) . void gluCylinder(GLUquadricObi *qobj, GLdouble baseRadius, GLdouble topRadius, GLdouble height, GLint slices, GLint stacks); Z z = 0 z = height . 2013-2 64 void gluDisk(GLUquadricObj *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint

rings); innerRadius outerRadius z slices z rings void gluPartialDisk(GLuquadricObj *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint rings, GLdouble startAngle, GLdouble sweepAngle); z = 0 . startAngle start + sweepAngle 2013-2 65 11-4 : quadric.c

#include #include #include #ifndef CALLBACK #define CALLBACK #endif GLuint startList; 2013-2 66 void CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf(stderr, "Quadric Error: %s\n", estring); exit(0); }

void init(void) { GLUquadricObj *qobj; GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; 2013-2 67 GLfloat mat_shininess[] = { 50.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; glClearColor(0.0, 0.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,

model_ambient); 2013-2 68 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); startList = glGenLists(4); qobj = gluNewQuadric(); gluQuadricCallback(qobj, GLU_ERROR, errorCallback); gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GLU_SMOOTH); glNewList(startList, GL_COMPILE); gluSphere(qobj, 0.75, 15, 10); glEndList(); 2013-2

69 gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GLU_FLAT); glNewList(startList+1, GL_COMPILE); gluCylinder(qobj, 0.5, 0.3, 1.0, 15, 5); glEndList(); gluQuadricDrawStyle(qobj, GLU_LINE); gluQuadricNormals(qobj, GLU_NONE); glNewList(startList+2, GL_COMPILE); gluDisk(qobj, 0.25, 1.0, 20, 4); glEndList(); 2013-2 70

gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); gluQuadricNormals(qobj, GLU_NONE); glNewList(startList+3, GL_COMPILE); gluPartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0); glEndList(); } void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); 2013-2 71 glEnable(GL_LIGHTING); glShadeModel (GL_SMOOTH); glTranslatef(-1.0, -1.0, 0.0);

glCallList(startList); glShadeModel (GL_FLAT); glTranslatef(0.0, 2.0, 0.0); glPushMatrix(); glRotatef(300.0, 1.0, 0.0, 0.0); glCallList(startList+1); glPopMatrix(); 2013-2 72 glDisable(GL_LIGHTING); glColor3f(0.0, 1.0, 1.0); glTranslatef(2.0, -2.0, 0.0); glCallList(startList+2); glColor3f(1.0, 1.0, 0.0); glTranslatef(0.0, 2.0, 0.0); glCallList(startList+3);

glPopMatrix(); glFlush(); } 2013-2 73 void reshape (int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); else glOrtho(-2.5*(GLfloat)w/(GLfloat)h, 2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);

glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } 2013-2 74 void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } 2013-2

75 int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2013-2

76 2013-2 77

Recently Viewed Presentations

  • Aqueous Chemistry 1 Recap To date, we have

    Aqueous Chemistry 1 Recap To date, we have

    ox (reduction-oxidation) reactions. A . reduction. reaction occurs when the oxidation state (charge) of an element/ion becomes . more negative. the course of a reaction (i.e. the species gains electrons) In an . oxidation.
  • Chapter 5 Strategies in Action

    Chapter 5 Strategies in Action

    Chapter 5 Strategies in Action ... Strategies Vertical Integration Strategies Forward Integration Backward Integration Horizontal Integration Types of Strategies Intensive Strategies Market Penetration Market Development Product Development Types of Strategies Diversification Strategies ...
  • Reviewing Individual Returns OML Conference 2018 Patricia Chittock

    Reviewing Individual Returns OML Conference 2018 Patricia Chittock

    Inspired by CCA's table. Streamlined variation of CCA's table for independent suburbs. Adapted by Lakewood. Informed/Critiqued by Euclid and Cuyahoga Falls. Customizable and fairly straightforward. Resembles Lakewood's prior Schedule table, but greatly expanded.
  • SAFETY CULTURE Bureau of Workers Compensation PA Training

    SAFETY CULTURE Bureau of Workers Compensation PA Training

    Mind not on task (thinking about something else other than the work being done; being distracted; not paying attention) . In the line of fire of potential injuries (a piece of machine or product comes out of/away from the machine...
  • Grammar Unit - Warren County Public Schools

    Grammar Unit - Warren County Public Schools

    Grammar Unit Interjections Let's Review . . . The interjection is the last of the eight parts of speech. Just for the record, here are all eight: Noun Pronoun Adjective Verb Adverb Preposition Conjunction Interjection First, let's start with a...
  • Ideologii Totalitare - BluePink

    Ideologii Totalitare - BluePink

    Aceasta este deseori asociată cu tinerii "skinhead". De asemenea, în multe ţări din Europa vestică s-a observat în ultimul timp o creştere a importanţei partidelor naţionaliste (Austria, Franţa, în Germania unele partide neo-naziste chiar au câştigat alegerile în cateva land-uri),...
  •  =   Tithe Tithe Tithe = Tithe a Tithe

    = Tithe Tithe Tithe = Tithe a Tithe

    [this is a promise from the Mosaic Covenant] Proverbs 3.9-10 NET: Honor the LORD from your wealth and from the first fruits of all your crops; [this is a command from the Mosaic Covenant] then your barns will be filled...
  • California Children Services Provider Training Presentation

    California Children Services Provider Training Presentation

    A key point to remember is that a referral should be made as early as possible, because CCS does not pay for medical care that is provided before the date of referral (unless the client has full-scope, no share of...