기말고사 담당교수 : 단국대학교멀티미디어공학전공박경신 답은반드시답안지에기술할것. 공간이부족할경우반드시답안지몇쪽의뒤에있다고명기한후기술할것. 그외의경우의답안지뒤쪽이나연습지에기술한내용은답안으로인정안함. 답에는반드시네모를쳐서확실히표시할것. 성적공고시중간고사때제출한암호를사용할것임. 1. 다음문제에답하시오. (50점) 1) 표면의법선벡터 (normal vector) N과표면에서광원으로향하는광원벡터 (light vector) L이주어졌을때, 반사벡터 (reflection vector) R을유도하라. i r R ( N L) N S L ( N L) N S S ( N L) N L R 2( L N) N L 2) OpenGL의 glmatrixmode(glenum mode) 는현재행렬의모드를설정하는함수이다. mode 인자 3가지를간단히설명하시오. glmatrixmode(gl_modelview) 연속되는행렬연산을기하변환행렬 (geometric transformation matrix) 스택에적용한다. 3 차원공간에물체의배치를지정할수있다. glmatrixmode(gl_projection) 연속되는행렬연산을투영행렬 (projection matrix) 스택에적용한다. 3 차원공간에투영함수를적용하는행렬을지정한다. glmatrixmode(gl_texture) 연속되는행렬연산을텍스쳐변환행렬 (texture transformation matrix) 스택에적용한다. 텍스쳐의변환을적용하는행렬을지정한다. 1/10
3) 다음관측함수 glortho(left, right, bottom, top, near, far), glfrustum(left, right, bottom, top, near, far), gluperspective(fovy, aspect, near, far) 함수를간단히설명하고관측공간을그림으로표시하라. glortho(left, right, bottom, top, near, far) 직교투영 (orthogonal projection) 함수로관측공간 (viewing volume) 은직육면체이다. glfrustum(left, right, bottom, top, near, far) 투시투영 (perspective projection) 함수로관측공간 (viewing volume) 은절두체 (frustum 잘려진피라미드형태 ) 이다. gluperspective(fovy, aspect, near, far) 투시투영 (perspective projection) 함수로 fovy 는 y-축방향에서의시야 (field of view) 각도, 종횡비 (aspect ratio), near, far 클리핑면으로이루어져있다. 4) OpenGL 에서제공하는광원 (light source) 의종류 4 가지를간단히설명하시오. 환경광원 (ambient light source) 장면의모든점에균일한광도를제공하는광원 점광원 (point light source) 한점을중심으로주변으로퍼져나가는광원 방향성광원 (directional light source) 빛이물체면을향하여일정한방향으로진행하는광원으로원거리광원또는평행광원이라고불림 점적광원 (spot light source) 점광원의특수한형태로원뿔과같이일정한범위로빛을발하는광원 5) 객체공간기법의은면제거알고리즘을 2 가지를간단히설명하라. 깊이정렬알고리즘 (Depth-sorting algorithm) 폴리곤의각면을깊이에따라정렬한뒤, 먼것부터투영하여그린다. Painter s algorithm라고도불린다. Binary Space Partitioning (BSP) tree BSP tree를사용하여관측방향에따라 front, back을구분하여공간을계속적으로분할한다. 2/10
6) OpenGL 함수 gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, mode) 는텍스쳐좌표값이 (0,1) 범위를넘어선값에대해, mode가 GL_CLAMP는 s,t가 1보다크면 1을 s,t가 0보다작으면 1으로값을강제조정하고, GL_REPEAT는 s,t%1을사용하여텍스쳐를반복한다. 화면출력결과를참고하여빈칸을채우시오. gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, GL_CLAMP ); gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_T, GL_REPEAT ); gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, GL_REPEAT ); gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_T, GL_REPEAT ); 7) 다음은실습예제로제공한텍스쳐환경변수 OpenGL 프로그램의일부를보여주고있다. OpenGL 함수 gltexenvf(gl_texture_env, GL_TEXTURE_ENV_MODE, mode) 는텍스쳐와음영간의상호작용을지정할수있게한다. GL_MODULATE, GL_DECAL, GL_BLEND, GL_REPLACE 모드를사용했을때텍스쳐값이어떻게나타나는지빈칸에간단히설명하시오. C t : 텍스쳐색, C f : 프레임버퍼의색, C b : 블렌딩색 void draw() { //.. 중간생략 initlight(); glenable(gl_texture_2d); glcolor3f(1.0, 1.0, 1.0); glbindtexture(gl_texture_2d, texid); // 1. _GL_MODULATE 텍스쳐색성분과음영색성분이곱함 _C = C t *C f gltexenvf(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_MODULATE); glpushmatrix(); gltranslatef(-1.1, 1.0, 0.0); glrotatef(-90.0, 1.0, 0.0, 0.0); glusphere(quadric, 1.0, 16, 8); glpopmatrix(); 3/10
// 2. _GL_DECAL 텍스쳐색성분이객체의색을완전히결정함 _C = C t gltexenvf(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_DECAL); glpushmatrix(); gltranslatef(1.1, 1.0, 0.0); glrotatef(-90.0, 1.0, 0.0, 0.0); glusphere(quadric, 1.0, 16, 8); glpopmatrix(); // 3. _GL_BLEND 텍스쳐색성분과블렌딩색과합성함 _C = (1 - C t )C f + C t *C b GLfloat blendcolor[] = {0.0, 1.0, 0.0, 0.5; gltexenvf(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_BLEND); gltexenvfv(gl_texture_env, GL_TEXTURE_ENV_COLOR, blendcolor); glpushmatrix(); gltranslatef(-1.1, -1.0, 0.0); glrotatef(-90.0, 1.0, 0.0, 0.0); glusphere(quadric, 1.0, 16, 8); glpopmatrix(); // 4. _GL_REPLACE 텍스쳐색성분이객체의색을완전히결정함 _ C = C t gltexenvf(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_REPLACE); glpushmatrix(); gltranslatef(1.1, -1.0, 0.0); glrotatef(-90.0, 1.0, 0.0, 0.0); glusphere(quadric, 1.0, 16, 8); glpopmatrix(); glbindtexture(gl_texture_2d, 0); gldisable(gl_texture_2d); //.. 중간생략 8) 다음은입방체 (cube) 를그리는 OpenGL 프로그램의일부이다. 빈칸을채우시오. void drawcube() { float vertex[8][3]; vertex[0][0] = -1; vertex[0][1] = -1; vertex[0][2] = -1; vertex[1][0] = 1; vertex[1][1] = -1; vertex[1][2] = -1; vertex[2][0] = 1; vertex[2][1] = 1; vertex[2][2] = -1; vertex[3][0] = -1; vertex[3][1] = 1; vertex[3][2] = -1; vertex[4][0] = -1; vertex[4][1] = -1; vertex[4][2] = 1; vertex[5][0] = 1; vertex[5][1] = -1; vertex[5][2] = 1; vertex[6][0] = 1; vertex[6][1] = 1; vertex[6][2] = 1; vertex[7][0] = -1; vertex[7][1] = 1; vertex[7][2] = 1; p7 p4 p3 p0 p2 p6 p1 p5 float normal[6][3]; normal[0][0] = 1.0; normal[0][1] = 0.0; normal[0][2] = 0.0; normal[1][0] = 0.0; normal[1][1] = 1.0; normal[1][2] = 0.0; normal[2][0] = 0.0; normal[2][1] = 0.0; normal[2][2] = 1.0; normal[3][0] = -1.0; normal[3][1] = 0.0; normal[3][2] = 0.0; normal[4][0] = 0.0; normal[4][1] = -1.0; normal[4][2] = 0.0; normal[5][0] = 0.0; normal[5][1] = 0.0; normal[5][2] = -1.0; 4/10
glbegin( GL_QUADS ); glnormal3fv( normal[0] ); // right ( 오른쪽 ) glvertex3fv( vertex[5] ); glvertex3fv( vertex[1] ); glvertex3fv( vertex[2] ); glvertex3fv( vertex[6] ); glnormal3fv( normal[1] ); // top ( 윗쪽 ) glvertex3fv( vertex[6] ); glvertex3fv( vertex[2] ); glvertex3fv( vertex[3] ); glvertex3fv( vertex[7] );... // 중간생략 glnormal3fv( normal[5] ); //back ( 뒤쪽 ) glvertex3fv( vertex[0] ); glvertex3fv( vertex[3] ); glvertex3fv( vertex[2] ); glvertex3fv( vertex[1] ); 9) 다음은구체 (sphere) 를그리는 OpenGL 프로그램의일부이다. 빈칸을채우시오. void drawsphere(float radius, int stacks, int slices) { float lon, lat, v[3], n[3]; float lonstep = M_PI/stacks; float latstep = M_PI/slices; for (lon = 0.0; lon <= 2*M_PI; lon += (lonstep)) { glbegin(gl_triangle_strip); for (lat = 0.0; lat <= M_PI + latstep; lat += (latstep)) { n[0] = cosf(lon)*sinf(lat); n[1] = sinf(lon)*sinf(lat); n[2] = cosf(lat); v[0] = radius * cosf(lon)*sinf(lat); v[1] = radius * sinf(lon)*sinf(lat); v[2] = radius * cosf(lat); glnormal3fv(n); glvertex3fv(v); n[0] = cosf(lon + lonstep)*sinf(lat); n[1] = sinf(lon + lonstep)*sinf(lat); n[2] = cosf(lat); v[0] = radius * cosf(lon + lonstep)*sinf(lat); v[1] = radius * sinf(lon + lonstep)*sinf(lat); v[2] = radius * cosf(lat); glnormal3fv(n); glvertex3fv(v); 5/10
10) 다음은간단한 OpenGL 프로그램의일부이다. 오른쪽화면출력결과를참고하여빈칸을채우시오. glpolygonmode(gl_front_and_back, GL_FILL); glbegin( GL_TRIANGLES ); for (int i = 0; i<8; i++) glvertex2fv(v[i]); glpolygonmode(gl_front_and_back, GL_FILL); glbegin( GL_TRIANGLE_FAN ); for (int i = 0; i<8; i++) glvertex2fv(v[i]); glpolygonmode(gl_front_and_back, GL_FILL); glbegin( GL_TRIANGLE_STRIP ); glvertex2fv(v[0]); glvertex2fv(v[1]); glvertex2fv(v[7]); glvertex2fv(v[2]); glvertex2fv(v[6]); glvertex2fv(v[3]); glvertex2fv(v[5]); glvertex2fv(v[4]); 2. 래스터화과정에서선분을그리는 Bresenham s Line Drawing 알고리즘을간단히설명하라. 그리고 DDA (Digital Differential Analyzer) 알고리즘과의차이점을비교하라. (10점) DDA: y += (float) dy/dx 로계산하고 round(y) 를이용하여선분의점을그린다. 선분을그리는데일반직선의공식 (y = mx + h) 을사용했을때보다부동소수곱셈을부동소수덧셈으로변환하여계산을향상시켰으나정수연산에비해느린단점이있다. 또한 round 함수를실행하는시간이더걸린다. Bresenham s algorithm: 일명 Midpoint line drawing algorithm 으로불린다. 모든부동소수점 (float) 계산을피하고정수 (int) 계산만을이용한다. 화소 A(x,y) 에서중점 M(x+1, y+½) 이선분의아래에있으면동쪽화소 B (x+1, y) 를선택하고아니면동북쪽화소 C(x+1, y+1) 을선택하는방식이다. 6/10
(x+1,y+1) (x+1,y+½) (x,y) (x+1,y) Puedo code 는아래와같다. 결정변수 D = 2dy dx if (D < 0) D += 2dy else D += 2dy 2dx y++ 3. 다음은초록색배경에빨간색삼각형과그위에파란색사각형을블렌딩하여그리는간단한 OPENGL 프로그램의일부를보여주고있다. 아래와같이여러가지방법으로블렌딩함수를사용했을때그림에서 1( 삼각형부분만 ), 2( 삼각형과사각형이겹치는부분 ), 3( 사각형부분만 ), 4( 나머지배경만 ) 의화면에출력되는최종 RGBA 색을계산하여표의빈칸에넣으시오. (20점) 블렌딩공식 : C = SourceFactor*C s + DestinationFactor*C d void drawobject() { glcolor4f(1, 0, 0, 1); glbegin(gl_triangles); glvertex3f(0.0, 1.0, -3.0); glvertex3f(-1.0, -1.0, -3.0); glvertex3f(1.0, -1.0, -3.0); glcolor4f(0, 0, 1, 0.5); glbegin(gl_quads); glvertex3f(0.0, -1.0, -2.0); glvertex3f(1.0, -1.0, -2.0); glvertex3f(1.0, 0.0, -2.0); glvertex3f(0.0, 0.0, -2.0); 7/10
void draw() { glclearcolor(0, 1, 0, 1); glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glenable(gl_blend); if (filter == 0) glblendfunc(gl_one, GL_ZERO); else if (filter == 1) glblendfunc(gl_zero, GL_ONE); else if (filter == 2) glblendfunc(gl_one, GL_ONE); else if (filter == 3) glblendfunc(gl_src_alpha, GL_ONE_MINUS_SRC_ALPHA); else if (filter == 4) glblendfunc(gl_src_alpha, GL_ONE); else if (filter == 5) glblendfunc(gl_zero, GL_SRC_COLOR); else if (filter == 6) glblendfunc(gl_one_minus_dst_color, GL_ZERO); drawobject(); gldisable(gl_blend); 4 1 2 3 Blending Func 1 2 3 4 GL_ONE (1,0,0,1) (0,0,1,1) (0,0,1,1) (0,1,0,1) GL_ZERO GL_ZERO (0,1,0,1) (0,1,0,1) (0,1,0,1) (0,1,0,1) GL_ONE GL_ONE (1,1,0,1) (1,1,1,1) (0,1,1,1) (0,1,0,1) GL_ONE GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA (1,0,0,1) (0.5,0,0.5,0.75) (0,0.5,0.5,0.75) (0,1,0,1) 8/10
4. 다음은 Cohen-Sutherland 알고리즘으로 2차원선분을클리핑하려고한다. 아래오른쪽그림은 Cohen-Sutherland 알고리즘의각영역에대한 4-비트외곽부호 (outcode) 를보여주고있다. 아래빈칸을채우시오. (10점). J A F B G I D E H 1001 y = y 1000 max 1010 x = x min 0001 0000 x = x max 0010 C y = y min 0101 0100 0110 선분의각끝점의 4 비트외곽부호 (outcode) 를구하시오. A: 1000 B: 0000 C: 0100 D: 0010 E: 0000 F: 0000 G: 0010 H: 1010 I: 0001 J: 1000 선분클리핑을위해 4 비트외곽부호를이용하여다음 4 가지경우로분류하는판정기준을적으시오. 선분의양끝점이클리핑윈도우내부에있는경우 (accept): E s outcode = F s outcode = 0 선분의양끝점이클리핑윈도우의같은변의외부에있는경우 (reject): G s outcode AND H s outcode 0 선분의한끝점은클리핑윈도우내부에있고, 다른하나는외부에있는경우 (1 개교차점을찾는다 subdivision): A s outcode 0, B s outcode = 0 선분의양끝점이모두외부에있고선분의일부가클리핑윈도우내부에있는경우 (subdivision): C s outcode AND D s outcode = 0 I s outcode AND J s outcode = 0 9/10
5. 아래그림을참고하여 glulookat(1,1,0, 0,0,0, 0,1,0) 함수에서뷰잉행렬 (Viewing Matrix) M 을도출하는계산과정을보여라. 아래빈칸을채우시오. (10점) Eye position (eye): (1, 1, 0) Look-at position (at): (0, 0, 0) Up-vector (up): (0, 1, 0) n (camera frame Z) : n = eye at => n = (0.707107, 0.707107, 0) u (camera frame X): u = n x up => u = (0, 0, -1) v (camera frame Y): v = n x u => v = (-0.707107, 0.707107, 0) M (viewing matrix): u[0] v[0] n[0] 0 M = u[1] v[1] n[1] 0 u[2] v[2] n[2] 0 -u eye -v eye -n eye 1 M (viewing matrix): 0-0.70717 0.707107 0 M = 0 0.707107 0.707107 0-1 0 0 0 0 0-1.414214 1 10/10