Download presentation
Presentation is loading. Please wait.
1
Draw the basic Geometry Objects
Hanyang University Jungsik Park
2
VERTEX ATTRIBUTE AND GEOMETRIC PRIMITIVES
3
Vertex Vertex Vertex attributes 3D 공간상의 점, 또는 기본 도형(삼각형, 폴리곤 등)의 꼭지점
Vertex coordinate Composition of primitives Vertex color Normal vector Texture coordinate
4
Vertex coordinate glVertex*() vertex의 3D/2D 좌표를 지정.
vertex 속성 중 가장 중요한 속성으로 glBegin() ~ glEnd() 사이에 위치시킴으로써 frame buffer에 도형을 그리게 된다. 그 외의 속성은 지정하지 않아도 도형을 그릴 수 있으나 vertex 좌표를 지정하지 않으면 도형을 그릴 수 없다. glFlush()를 호출함으로써 frame buffer의 내용을 화면에 출력한다.
5
Vertex coordinate OpenGL coordinate system
3D cartesian coordinate system x, y, z 축 각각 [-1.0, 1.0]의 범위를 갖는 정규화된 직육면체의 view volume 내의 물체를 그린다. 일반적으로 더 큰 view volume, 혹은 원근감을 표현할 수 있는 frustum view volume 내의 물체를 그리기 위해 view volume 변환을 먼저 수행한다. 2D의 경우 z=0인 평면상의 물체를 그린다.
6
Primitives Geometric primitives
vertex들로 구성되며, vertex의 좌표는 glVertex*()로 지정 면을 가지는 도형의 경우 vertex들이 반시계 방향의 순서를 가지도록 지정되어야 한다.
7
Polygon construction rules
폴리곤 구성의 규칙 폴리곤을 구성하는 모든 vertex는 한 평면상에 위치해야 한다. 폴리곤을 이루는 선들은 서로 교차해서는 안 되면, 폴리곤의 전체적인 모양은 볼록해야 한다. 위의 규칙을 항상 만족하는 삼각형을 많이 사용
8
Polygon construction rules
다음 도형을 하나의 폴리곤으로 그리는 경우 잘못된 결과가 나타난다. glBegin(GL_QUADS); glVertex2f(-0.5, -0.5); glVertex2f(0.5, 0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, -0.5); glEnd();
9
Example code #include <GL/glut.h> int primitive[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP , GL_POLYGON, GL_QUADS, GL_TRIANGLES}; int index; void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(primitive[index]); glVertex2f(-0.5, 0.0); glVertex2f( , ); glVertex2f(0.0, 0.5); glVertex2f(0.3536, ); glVertex2f(0.5, 0.0); glVertex2f(0.3536, ); glVertex2f(0.0, -0.5); glVertex2f( , ); glEnd(); glFlush(); } void mykeyboard(unsigned char key, int x, int y) { if (key == 'n' || key == 'N') index++; else if (key == 'p' || key == 'P') index--; if (index < 0) index = 6; if (index > 6) index = 0; glutPostRedisplay(); } int main(int argc, char** argv){ glutCreateWindow(“primitives"); glutDisplayFunc(mydisplay); glutKeyboardFunc(mykeyboard); glutMainLoop();
10
Drawing with fewer vertices
GL_TRIANGLE_STRIP, GL_QUAD_STRIP GL_TRIANGLE_FAN Advantages to using fewer vertices 메모리 공간 절약 연산수 감소 및 그래픽 카드로의 데이터 전송 대역폭 절약 P0 P1 P2 P3 P4 P5 P6
11
Example code - GL_TRIANGLE_STRIP
void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glVertex2f(-0.6, -0.2); // P0 glVertex2f(-0.5, 0.2); // P1 glVertex2f(-0.3, -0.2); // P2 glVertex2f(-0.2, 0.2); // P3 glVertex2f(0.0, -0.2); // P4 glVertex2f(0.1, 0.2); // P5 glVertex2f(0.3, -0.2); // P6 glVertex2f(0.4, 0.2); // P7 glEnd(); glFlush(); } GL_TRIANGLE_STRIP 사용 void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLE_STRIP); glVertex2f(-0.6, -0.2); // P0 glVertex2f(-0.5, 0.2); // P1 glVertex2f(-0.3, -0.2); // P2 glVertex2f(-0.2, 0.2); // P3 glVertex2f(0.0, -0.2); // P4 glVertex2f(0.1, 0.2); // P5 glVertex2f(0.3, -0.2); // P6 glVertex2f(0.4, 0.2); // P7 glEnd(); glFlush(); }
12
Example code – GL_TRIANGLE_FAN
#include <math.h> #include <GL/glut.h> #define PI void mydisplay(){ GLfloat x, y, angle; glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLE_FAN); glVertex2f(0.0f, 0.0f); for(angle = 0.0f; angle < (2.0f*PI); angle += (PI/8.0f)) { x = 0.5f*sin(angle); y = 0.5f*cos(angle); glVertex2f(x, y); } glEnd(); glFlush(); int main(int argc, char** argv){ glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop();
13
Draw 3D object glVertex3*()로 3차원 좌표 지정(z축 추가) 아래 그림은 cube를 그린 예제
입체감을 표현하기 위해선 다음의 요소가 필요 perspective projection lighting & shading
14
Example code - Draw 3D object
void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); glVertex3f(0.3,0.3,0.3); glVertex3f(0.3,-0.3,0.3); glVertex3f(-0.3,-0.3,0.3); glVertex3f(-0.3,0.3,0.3); glVertex3f(0.3,0.3,-0.3); glVertex3f(0.3,-0.3,-0.3); glVertex3f(-0.3,-0.3,-0.3); glVertex3f(-0.3,0.3,-0.3); glEnd(); glPopMatrix(); glFlush(); } void specialkeys(int key, int x, int y) { if(key == GLUT_KEY_UP) xRot-= 5.0f; if(key == GLUT_KEY_DOWN) xRot += 5.0f; if(key == GLUT_KEY_LEFT) yRot -= 5.0f; if(key == GLUT_KEY_RIGHT) yRot += 5.0f; if(key > 356.0f) xRot = 0.0f; if(key < -1.0f) xRot = 355.0f; yRot = 0.0f; yRot = 355.0f; // Refresh the Window glutPostRedisplay(); } int main(int argc, char** argv){ glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutSpecialFunc(specialkeys); glutMainLoop();
15
Vertex color OpenGL에서는 vertex 단위로 색상을 할당. glColor*()
선, 면의 색상은 구성하는 vertex들의 색을 interpolation하여 결정 glColor*() 색상은 인자의 수에 따라 RGBA, RGB로 지정 void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void glColor3f (GLfloat red, GLfloat green, GLfloat blue); 각 채널의 값의 범위 인자가 실수인 경우 [0.0, 1.0] 인자가 정수인 경우 [0, 255]
16
Example code – vertex color
#include <GL/glut.h> int primitive[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP , GL_POLYGON, GL_QUADS, GL_TRIANGLES}; int index; void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT); glBegin(primitive[index]); glColor3f(1.0, 0.0, 0.0); // red glVertex2f(-0.5, 0.0); glColor3f(0.0, 1.0, 0.0); // green glVertex2f( , ); glColor3f(0.0, 0.0, 1.0); // blue glVertex2f(0.0, 0.5); glColor3f(0.5, 0.5, 0.5); // gray glVertex2f(0.3536, ); glColor3f(1.0, 1.0, 0.0); // yellow glVertex2f(0.5, 0.0); glColor3f(1.0, 0.0, 1.0); // magenta glVertex2f(0.3536, ); glColor3f(0.0, 1.0, 1.0); // cyan glVertex2f(0.0, -0.5); glColor3f(1.0, 1.0, 1.0); // white glVertex2f( , ); glEnd(); glFlush(); } void mykeyboard(unsigned char key, int x, int y) { if (key == 'n' || key == 'N') index++; else if (key == 'p' || key == 'P') index--; if (index < 0) index = 6; if (index > 6) index = 0; glutPostRedisplay(); } int main(int argc, char** argv){ glutCreateWindow(“primitives"); glutDisplayFunc(mydisplay); glutKeyboardFunc(mykeyboard); glutMainLoop();
17
Other attributes Normal vector Texture coordinate
폴리곤 앞면의 법선 벡터. 폴리곤 단위가 아닌 vertex 단위로 지정. glNormal*() lighting, backface culling 등에 사용됨 Texture coordinate 폴리곤에 텍스쳐를 매핑할 때 폴리곤의 각 지점과 영상의 픽셀을 대응시키기 위한 좌표 glTexcoord*()
18
MANIPULATION OF THE OPENGL STATES
19
States Point size & line width Winding Backface culling Depth test
Polygon mode Fill face Wireframe Point Shade model
20
States State를 변화시키는 방법 on/off 로 사용되는 state variable
glEnable() / glDisable() depth test, lighting, texture mapping 등 그 외의 값을 가지는 state variable을 변화시키는 경우 glFrontFace(), glLineWidth() 등 해당 state variable 전용 함수
21
Point size & line width Point size Line width 점의 크기를 지정
void glPointSize(GLfloat size); 기본값은 1이고, 사용할 수 있는 값의 범위는 플랫폼에 따라 다르다. Point size로 사용할 수 있는 값의 범위를 알아내는 법 Line width 선의 두께를 지정 void glLineWidth (GLfloat width); Line width로 사용할 수 있는 값의 범위를 알아내는 법 GLfloat sizes[2]; GLfloat step; glGetFloatv(GL_POINT_SIZE_RANGE,sizes); glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step); GLfloat sizes[2]; GLfloat step; glGetFloatv(GL_LINE_WIDTH_RANGE,sizes); glGetFloatv(GL_LINE_WIDTH_GRANULARITY,&step);
22
Example – line width void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); GLfloat y; GLfloat fSizes[2]; GLfloat fCurrSize; glGetFloatv(GL_LINE_WIDTH_RANGE,fSizes); fCurrSize = fSizes[0]; for(y = -0.9f; y < 0.9f; y += 0.2f) { glLineWidth(fCurrSize); glBegin(GL_LINES); glVertex2f(-0.8f, y); glVertex2f(0.8f, y); glEnd(); fCurrSize += 1.0f; } glFlush();
23
Winding 폴리곤을 구성하는 vertex들의 순서를 지정
폴리곤의 앞면과 뒷면을 결정하기 위한 방법 glFrontFace(GL_CCW); 반시계 방향으로 vertex 지정(디폴트) glFrontFace(GL_CW); 시계 방향으로 vertex 지정 앞면과 뒷면을 결정함으로써 보이지 않는 부분을 그리지 않거나, 앞면과 뒷면에 각각 다른 색상,재질을 지정할 수 있다.
24
Backface culling 폴리곤의 보이지 않는 면(뒷면)을 제거하는 옵션 glEnable(GL_CULL_FACE);
glDisable(GL_CULL_FACE); 불필요한 면을 그리지 않음으로써 성능상의 이득을 얻을 수 있다. 종이 같은 얇은 평면, 유리와 같은 투명한 물체는 뒷면도 그려져야 하므로 backface culling을 사용하지 않는다.
25
Depth test 어떤 물체가 다른 물체의 앞에 있는 경우, 뒤의 물체가 그려지지 않도록 한다.
glEnable(GL_DEPTH_TEST); depth buffer를 이용하여 픽셀을 그릴 때마다 z값을 비교하여 높은 z값을 갖는 픽셀로 갱신함으로써 뒤의 물체가 보이지 않도록 한다. glDisable(GL_DEPTH_TEST); z값과 관계없이 나중에 그려지는 물체를 그린다. backface culling과 달리 z값을 비교하여 그려지는지 여부를 결정하기 때문에 depth test로 인한 성능 이득은 없지만 사실적인 표현을 위해 필요한 요소. backface culling : 아예 그리지 않음 depth test : 그렸지만 보이지 않음
26
Polygon mode 폴리곤을 색칠된 면으로 그리거나, wireframe으로 그리는 옵션
void glPolygonMode (GLenum face, GLenum mode); face : GL_FRONT, GL_BACK, GL_FRONT_AND_BACK mode : GL_FILL, GL_LINE, GL_POINT 예 : 물체의 앞면을 wireframe으로 그릴 경우 glPolygonMode(GL_FRONT, GL_LINE);
27
Shade model 폴리곤의 면을 색칠하는 방법 지정 glShadeModel(GL_SMOOTH);
vertex 색상을 interpolation하여 면의 각 부분을 색칠 glShadeModel(GL_FLAT); 폴리곤을 구성하는 vertex 중 마지막 vertex의 색상으로 면을 색칠
28
Example code #include <stdio.h> #include <GL/glut.h> bool bBackfaceCull = false; bool bDepthTest = false; bool bWindCCW = false; bool bShadeSmooth = false; bool bWireFrame = false; static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; void mydisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); if (bBackfaceCull) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (bDepthTest) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (bWindCCW) glFrontFace(GL_CCW); else glFrontFace(GL_CW); if (bShadeSmooth) glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); if (bWireFrame) glPolygonMode(GL_FRONT, GL_LINE); else glPolygonMode(GL_FRONT, GL_FILL); glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f);
29
Example code(cont’d) glBegin(GL_QUADS); // Front Face glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.3,0.3,0.3); // White glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(0.3,-0.3,0.3); // Yellow glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3,-0.3,0.3); // Red glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(-0.3,0.3,0.3); // Magenta // Back Face glColor3f(0.0f, 1.0f, 1.0f); glVertex3f(0.3,0.3,-0.3); // Cyan glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.3,-0.3,-0.3); // Green glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3,-0.3,-0.3); // Black glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-0.3,0.3,-0.3); // Blue // Top Face // Bottom Face
30
Example code(cont’d) // Left face glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.3,0.3,0.3); // White glColor3f(0.0f, 1.0f, 1.0f); glVertex3f(0.3,0.3,-0.3); // Cyan glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.3,-0.3,-0.3); // Green glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(0.3,-0.3,0.3); // Yellow // Right face glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(-0.3,0.3,0.3); // Magenta glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-0.3,0.3,-0.3); // Blue glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3,-0.3,-0.3); // Black glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3,-0.3,0.3); // Red glEnd(); glPopMatrix(); // Show the graphics glFlush(); } void specialkeys(int key, int x, int y) { if(key == GLUT_KEY_UP) xRot-= 5.0f; if(key == GLUT_KEY_DOWN) xRot += 5.0f; if(key == GLUT_KEY_LEFT) yRot -= 5.0f; if(key == GLUT_KEY_RIGHT) yRot += 5.0f; if(key > 356.0f) xRot = 0.0f; if(key < -1.0f) xRot = 355.0f; if(key > 356.0f) yRot = 0.0f; if(key < -1.0f) yRot = 355.0f; glutPostRedisplay();
31
Example code(cont’d) void mykeyboard(unsigned char key, int x, int y) { switch (key) case 'b': case 'B': bBackfaceCull = !bBackfaceCull; if (bBackfaceCull) printf("backface culling : on\n"); else printf("backface culling : off\n"); break; case 'd': case 'D': bDepthTest = !bDepthTest; if (bDepthTest) printf("depth test : on\n"); else printf("depth test : off\n"); case 'w': case 'W': bWireFrame = !bWireFrame; if (bWireFrame) printf("draw wireframe\n"); else printf("fill face\n"); case 's': case 'S': bShadeSmooth = !bShadeSmooth; if (bShadeSmooth) printf("smooth shading\n"); else printf("flat shading\n"); case 'c': case 'C': bWindCCW = !bWindCCW; if (bWindCCW) printf("wind counter-clockwise\n"); else printf("wind clockwise\n"); } glutPostRedisplay(); int main(int argc, char** argv){ glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutKeyboardFunc(mykeyboard); glutSpecialFunc(specialkeys); glutMainLoop();
Similar presentations