Letterkenny Institute of Technology BSc in Computing in Games Development Subject: Computer Graphics for Games Programming 2 Level: 7 Date: January 2008 Examiners: Dr. J.G. Campbell Dr. M.D.J. McNeill Time Allowed: Two hours INSTRUCTIONS Answer three questions from ve. C. Graphics for Games Prog. 2 Page 1 of 26 January 2008
1. Texture mapping. Figures 1 and 2 show parts of a program which draws a pyramid and applies a texture. The result is shown in Figure 3 and the original texture is shown in Figure 4. // white background glclearcolor(1.0f, 1.0f, 1.0f, 1.0f ); // Load texture glpixelstorei(gl_unpack_alignment, 1); pbytes = gltloadtga("tile.tga", &iwidth, &iheight, &icomponents, &eformat); glteximage2d(gl_texture_2d, 0, icomponents, iwidth, iheight, 0, eformat, GL_UNSIGNED_BYTE, pbytes); free(pbytes); gltexparameteri(gl_texture_2d, GL_TEXTURE_MIN_FILTER,GL_LINEAR);//A1 gltexparameteri(gl_texture_2d, GL_TEXTURE_MAG_FILTER,GL_LINEAR);//A2 gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, GL_REPEAT); //B1 gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_T, GL_REPEAT); //B2 gltexenvi(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_MODULATE); glenable(gl_texture_2d); } //C Figure 1: Texture Code, Texture Setup C. Graphics for Games Prog. 2 Page 2 of 26 January 2008
void RenderScene(void){ M3DVector3f vnormal; M3DVector3f vcorners[5] = { { 0.0f,.80f, 0.0f }, // Top 0 { -0.5f, 0.0f, -.50f }, // Back left 1 { 0.5f, 0.0f, -0.50f }, // Back right 2 { 0.5f, 0.0f, 0.5f }, // Front right 3 { -0.5f, 0.0f, 0.5f }}; // Front left 4 glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); //... irrelevant code removed glcolor3f(1.0f, 1.0f, 1.0f); glbegin(gl_triangles); // Bottom section - two triangles glnormal3f(0.0f, -1.0f, 0.0f); gltexcoord2f(1.0f, 0.0f); glvertex3fv(vcorners[2]); gltexcoord2f(0.0f, 1.0f); glvertex3fv(vcorners[4]); gltexcoord2f(0.0f, 0.0f); glvertex3fv(vcorners[1]); gltexcoord2f(1.0f, 0.0f); glvertex3fv(vcorners[2]); gltexcoord2f(1.0f, 1.0f); glvertex3fv(vcorners[3]); gltexcoord2f(0.0f, 1.0f); glvertex3fv(vcorners[4]); // Front Face m3dfindnormal(vnormal, vcorners[0], vcorners[4], vcorners[3]); glnormal3fv(vnormal); gltexcoord2f(0.5f, 1.0f); glvertex3fv(vcorners[0]); gltexcoord2f(0.0f, 0.0f); glvertex3fv(vcorners[4]); gltexcoord2f(1.0f, 0.0f); glvertex3fv(vcorners[3]); // etc. for other faces... glend(); Figure 2: Texture Code, Rendering Pyramid C. Graphics for Games Prog. 2 Page 3 of 26 January 2008
Figure 3: Textured Pyramid. Figure 4: Texture. C. Graphics for Games Prog. 2 Page 4 of 26 January 2008
(a) Using diagrams as necessary, explain in detail how OpenGL texture mapping works and, in particular, the code for the texturing of the bottom section of the pyramid shown in the rst part of Figure 2. Since this question does not involve lighting, you should ignore any reference to normals. [8 marks] (b) (i) Explain the purpose of lines B1 and B2 in Figure 1; a diagram is strongly suggested. [4 marks] (ii) What would be the dierence (in general) if we changed the lines to those below? [2 marks] gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //B1 gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //B2 (c) (i) What is the pupose of the following line? (ii) What would be the dierence if we changed GL_MODULATE to GL_REPLACE? [4 marks] gltexenvi(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_MODULATE); //C (d) (i) What are the lines below specifying? [2 marks] gltexparameteri(gl_texture_2d, GL_TEXTURE_MIN_FILTER,GL_LINEAR);//A1 gltexparameteri(gl_texture_2d, GL_TEXTURE_MAG_FILTER,GL_LINEAR);//A2 (ii) Figure 5 shows a situation in which texture interpolation is needed; we need a texture value for rendering point p; assuming monochrome (grey-level) for ease of working, the texel values are t1 = 10; t2 = 20; t3 = 30; t4 = 40; t5 = 50; t6 = 60; t7 = 70; t8 = 80; t9 = 90. Give an estimate for the grey-level at p, assuming the GL_LiNEAR specication in lines A1, A1; you will obtain full marks for showing good understanding of the principle involved. (iii) Repeat question (ii) for GL_NEAREST specication in lines A1, A1.. [3 marks] [2 marks] C. Graphics for Games Prog. 2 Page 5 of 26 January 2008
Figure 5: Texel interpolation. C. Graphics for Games Prog. 2 Page 6 of 26 January 2008
2. Lighting. Eqn. 1 summarises the version of the Phong lighting model used by OpenGL, N l I total = m e + sa i att i [l i m a a + l i m d d max(n L i ; 0) + l i m s smax((v R i ); 0) s ]: (1) i=1 N is the normal to the surface at the vertex in question; L i is the direction of light i; V is the viewing (eye) direction and R i is the specular reection direction for light i; sa is the spotlight attenuation factor and att distance attenuation; R is given by eqn. 2. (a) Explain how colour enters eqn. 1 R = 2(N L)N L: (2) (b) Based on eqn. 1, explain the following types of lighting, source, and material: (i) Ambient; (ii) Diuse; (iii) Specular ; (iv) Emissive. [4 marks] [10 marks] (There are 4 2 marks for (i) to (iv), plus 2 additional marks for a diagram showing the vectors mentioned in eqn. 1.) (c) Figure 6 shows some OpenGL code involving lighting and Figure 7 shows the resulting graphic. Explain lines //A, //B, and //C. Part 2(d) continued on page 10. [6 marks] C. Graphics for Games Prog. 2 Page 7 of 26 January 2008
void display(void){ glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glloadidentity (); gltranslated(-2.0, -3.0, -12.0); glenable(gl_lighting); glenable(gl_light0); glenable(gl_color_material); //A glcolormaterial(gl_front, GL_AMBIENT_AND_DIFFUSE); //B GLfloat l_amb[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat l_dif[] = { 0.2, 1.0, 0.2, 1.0 }; GLfloat l_spc[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat m_spc[] = { 1.0, 1.0, 1.0, 1.0 }; //GLfloat m_spc[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat m_shn[] = { 5.0 }; gllightmodelfv(gl_light_model_ambient, l_amb); //C GLfloat l_pos[] = { 20.0, 20.0, 20.0, 0.0 }; gllightfv (GL_LIGHT0, GL_POSITION, l_pos); gllightfv (GL_LIGHT0, GL_DIFFUSE, l_dif); gllightfv (GL_LIGHT0, GL_SPECULAR, l_spc); glmaterialfv(gl_front, GL_SPECULAR, m_spc); glmaterialfv(gl_front, GL_SHININESS, m_shn); house(); glpushmatrix(); gltranslated(4.0, 5.0, 0.0); glrotated(50.0, 1.0, 0.0, 0.0); glutsolidteapot(1.0); glpopmatrix(); glpushmatrix(); gltranslated(5.0, 0.0, 0.0); glrotated(30.0, 0.0, 1.0, 0.0); house(); glpopmatrix(); glpushmatrix(); gltranslated(0.0, 5.0, 0.0); glscaled(1.0, 1.0, 1.0); house(); glpopmatrix(); Figure 6: Lighted house code C. Graphics for Games Prog. 2 Page 8 of 26 January 2008
Figure 7: House gures. C. Graphics for Games Prog. 2 Page 9 of 26 January 2008
(d) Given the code fragment below, explain what will be the colour /shade at vertex vf[0]. Assume that material has zero specular reection; consider ambient and diuse only; assume that the light direction is in the direction of the normal; no attenuation. You should carefully explain your calculations. GLfloat l_amb[] = { 0.2, 0.3, 0.8, 1.0 }; GLfloat l_dif[] = { 0.4, 0.5, 0.9, 1.0 }; GLfloat l_spc[] = { 1.0, 1.0, 1.0, 1.0 }; //GLfloat m_spc[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat m_spc[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat m_shn[] = { 5.0 }; GLfloat m_amb[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat m_dif[] = { 0.8, 0.8, 0.8, 1.0 }; [5 marks] GLfloat l_pos[] = { 20.0, 20.0, 20.0, 0.0 }; gllightfv (GL_LIGHT0, GL_POSITION, l_pos); gllightfv (GL_LIGHT0, GL_DIFFUSE, l_dif); gllightfv (GL_LIGHT0, GL_AMBIENT, l_amb); gllightfv (GL_LIGHT0, GL_SPECULAR, l_spc); glmaterialfv(gl_front, GL_SPECULAR, m_spc); glmaterialfv(gl_front, GL_SHININESS, m_shn); glmaterialfv(gl_front, GL_AMBIENT, m_amb); glmaterialfv(gl_front, GL_DIFFUSE, m_dif); glvertex3fv(vf[0]); C. Graphics for Games Prog. 2 Page 10 of 26 January 2008
3. Display Lists and Vertex Arrays. Figure 8 shows some code that uses a display list and Figure 9 shows the resulting display. (a) Using Figure 8 as an example, give a detailed explanation of OpenGL display lists and how they can be used improve performance (frame rate, for example). In your answer, explain why the drawing of the four green larger triangles will require much more overall processing eort than the triangles in the display list. Hints: immediate mode, retained mode; what gets sent to the graphics card and when? [10 marks] (b) Change the code such that the display list contains the ve triangles, i.e. no need for the for (i = 0; i < 5; i++) loop. [5 marks] C. Graphics for Games Prog. 2 Page 11 of 26 January 2008
GLuint listname; static void triangle(float s){ glbegin (GL_TRIANGLES); glvertex2f (0.0, 0.0); glvertex2f (s, 0.0); glvertex2f (0.0, s); glend (); } static void init (void){ listname = glgenlists (1); glnewlist (listname, GL_COMPILE); glcolor3f (1.0, 0.0, 0.0); /* current color red */ triangle(1.0); gltranslatef (1.5, 0.0, 0.0); /* move position */ glendlist (); glshademodel (GL_FLAT); } static void drawline (void){ glbegin (GL_LINES); glvertex2f (0.0, 0.5); glvertex2f (15.0, 0.5); glend (); } void display(void){ GLuint i; } glclear (GL_COLOR_BUFFER_BIT); /* draw five red triangles */ for (i = 0; i < 5; i++){ glcalllist (listname); } glcolor3f (0.0, 1.0, 0.0); /* draw four green larger triangles */ for (i = 0; i < 4; i++){ triangle(1.2); gltranslatef (1.5, 0.0, 0.0); } glflush (); Figure 8: Display list example C. Graphics for Games Prog. 2 Page 12 of 26 January 2008
Figure 9: Output from display list example. C. Graphics for Games Prog. 2 Page 13 of 26 January 2008
(c) Vertex arrays. Examine the code in Figure 10. /* ------------- varray.cpp --------------------------- * varray.cpp, from varray.c j.g.c. 2007-01-04 * This program demonstrates vertex arrays (OpenGL Red Book). *--------------------------------------------------- */ static GLint v[] = {25, 25, 100, 325, 175, 25, 175, 325, 250, 25, 325, 325}; static GLfloat c[] = {1.0, 0.2, 0.2, 0.2, 0.2, 1.0, 0.8, 1.0, 0.2, 0.75, 0.75, 0.75, 0.35, 0.35, 0.35, 0.5, 0.5, 0.5}; glenableclientstate (GL_VERTEX_ARRAY); // A glenableclientstate (GL_COLOR_ARRAY); // B glvertexpointer (2, GL_INT, 0, v); // C glcolorpointer (3, GL_FLOAT, 0, c); // D Figure 10: Vertex-arrays, varray.cpp (i) Explain the purpose of lines // A, // B, // C, and // D. [4 marks] (ii) Assuming the initialisation code in Figure 10 has been executed, the following line will produce the same display as the block of code marked // Two triangles. Why is the vertex array method more ecient? gldrawarrays (GL_TRIANGLES, 0, 6); glbegin(gl_triangles); // Two triangles glvertex2i(25, 25); glcolor3f(1.0, 0.2, 0.2); glvertex2i(100, 325); glcolor3f(0.2, 0.2, 1.0); glvertex2i(175, 25); glcolor3f(0.8, 1.0, 0.2); glvertex2i(175, 325); glcolor3f(0.75, 0.75, 0.75); glvertex2i(250, 25); glcolor3f(0.35, 0.35, 0.35); glvertex2i(325, 325); glcolor3f(0.5, 0.5, 0.5); glend(); (iii) How could interleaved arrays further increase eciency? [4 marks] [2 marks] C. Graphics for Games Prog. 2 Page 14 of 26 January 2008
4. Shaders and OpenGL Shading Language (GLSL). (a) Shaders or shader programs are a recent introduction to graphics and games programming. Give a brief explanation of shaders pitched at someone who has not heard of them, but who is familiar with OpenGL and its graphics pipeline. (b) Distinguish between vertex shader and fragment shader. [5 marks] [4 marks] (c) Using the example function setshader in Figure 11, explain the main steps in getting shader programs to execute; note, the question is worth only four marks, so keep your answer brief. (d) Examine the vertex shader in Figure 12 and answer the following questions. (i) What does line //A do? [4 marks] [2 marks] (ii) What does either line //B1 or //B2 (assuming the comment // was removed) do? [2 marks] (iii) Provide code, with explanation, that will squash x coordinates in the nal display by 0:5; clearly indicate where your code should be inserted in Figure 12. [2 marks] (iv) Provide code, with explanation, that will display negative colours in the nal display; alternatively, provide code, with explanation, that will display the nal display in grey-level; clearly indicate where your code should be inserted in Figure 12. (v) Vertex shaders are executed in a loop. Explain. (vi) Fragment shaders are executed in a loop. Explain. [2 marks] [2 marks] [2 marks] C. Graphics for Games Prog. 2 Page 15 of 26 January 2008
void setshaders() { char *vs = NULL, *fs = NULL; v = glcreateshader(gl_vertex_shader); f = glcreateshader(gl_fragment_shader); //f2 = glcreateshader(gl_fragment_shader); vs = textfileread("color.vert"); fs = textfileread("color.frag"); const char *vv = vs; const char *ff = fs; printf("\nvertex shader... \n %s \n", vv); printf("fragment shader... \n %s \n", ff); glshadersource(v, 1, &vv, NULL); glshadersource(f, 1, &ff, NULL); free(vs); free(fs); glcompileshader(v); glcompileshader(f); //glcompileshader(f2); p = glcreateprogram(); glattachshader(p, f); //glattachshader(p, f2); glattachshader(p, v); gllinkprogram(p); gluseprogram(p); //gluseprogram(0); // revert to fixed-function } loc = glgetuniformlocation(p, "time"); Figure 11: Shader Set Up C. Graphics for Games Prog. 2 Page 16 of 26 January 2008
// diffuse.vs // // Generic vertex transformation, // diffuse lighting based on one white light uniform vec3 lightpos[1]; void main(void){ gl_position = gl_modelviewprojectionmatrix * gl_vertex; //A vec3 N = normalize(gl_normalmatrix * gl_normal); vec4 V = gl_modelviewmatrix * gl_vertex; vec3 L = normalize(lightpos[0] - V.xyz); } float NdotL = dot(n, L); gl_frontcolor = gl_color * vec4(max(0.0, NdotL)); //B1 //gl_frontcolor = vec4(1.0, 1.0, 0.0, 0.0); //B2 Figure 12: Vertex Shader Implementing Diuse Lighting. C. Graphics for Games Prog. 2 Page 17 of 26 January 2008
5. Miscellaneous Questions on projective transformations, GLU quadrics. (a) Compare and contrast orthographic projection with perspective projection. Use of diagram(s) is strongly encouraged. [5 marks] (b) Referring as necessary to eqn. 13 on page 23, compute the the values that will be in projection matrix after the call to glortho at //A. void glortho(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); left = -50.0; right = 25.0; bottom = 0.0; top = 50.0; near = -1.0; far = 5.0; glmatrixmode(gl_projection); glloadidentity(); glortho(left, right, bottom, top, near, far); //A [5 marks] (c) Quadric surfaces, such as those provided by GLU Quadrics are dened by the general quadratic equation, q(x; y ; z) = ax 2 + by 2 + cz 2 + 2dxy + 2ey z + 2f xz + 2gx + 2hy + 2jz + k = 0: (3) (i) What are the values of a; b; c; : : : for the plane through x = 1 parallel to the y- and z- axes, given by eqn. 4? [1 marks] x 1 = 0 (4) (ii) Show that eqn. 3 and the matrix form in eqn. 5 are equivalent. Hint: multiply out eqn. 5 and remember that w = 1. where u = x y z w = 1, and Q = u T Q u = 0; (5) a d f g d b e h : f e c j g h j k (d) The surface normal to the quadric given by eqn. 3 is given by Use this to derive the normal to the plane [4 marks] n = ( @q @x ; @q @y ; @q ): (6) @z x 1 = 0 (7) [5 marks] C. Graphics for Games Prog. 2 Page 18 of 26 January 2008
(e) Explain the purpose of each line, //1, //2, //3, in the following code fragment. GLUquadricObj *s; s = glunewquadric(); //1 gluquadricdrawstyle(s, GLU_LINE); //2 int nlong = 10, nlat = 8; float r = 1.0; glusphere(s, r, nlong, nlat); //3 [3 marks] Give a rough drawing of what the code fragment will draw. [2 marks] C. Graphics for Games Prog. 2 Page 19 of 26 January 2008
Appendix A. 3D Ane Transformations using Homogeneous Coordinates. Translation v x v y v z v w = 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 u x u y u z u w : (8) Rotation about the z-axis Rotation about the x-axis R z (b) = R x (b) = cos b sin b 0 0 sin b cos b 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 cos b sin b 0 0 sin b cos b 0 0 0 0 1 : (9) : (10) Rotation about the y-axis R y (b) = cos b 0 sin b 0 0 1 0 0 sin b 0 cos b 0 0 0 0 1 : (11) C. Graphics for Games Prog. 2 Page 20 of 26 January 2008
Appendix B. 3D Projection Transformations using Homogeneous Coordinates. Perspective Transformation x 0 p z y 0 p z z 0 p z w 0 = 2n 0 r l r +l 0 r l t+b 0 t b 2n 0 t b f +n 0 0 f n 0 0 1 0 2nf f n p x p y p z 1 : (12) void glfrustum(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far). Figure 13 shows what the arguments mean. Figure 13: Perspective view frustum volume dened by glfrustum. gluperspective is more intuitive to use: gluperspective(float fovangley, float aspectratio, float near, float far); // these two are equivalent tanby2 = tan(fovy/2.0); gluperspective(fovy, aspectratio, n, 20.0); // glfrustum (-n*tanby2, n*tanby2, -n*tanby2*aspectratio, n*tanby2*aspectratio, n, 20.0); Figure 14 shows what the arguments mean. Compare with the equivalent glfrustum diagram, Figure 13. C. Graphics for Games Prog. 2 Page 21 of 26 January 2008
Figure 14: gluperspective. C. Graphics for Games Prog. 2 Page 22 of 26 January 2008
Orthographic Transformation 2 0 0 r l 2 0 0 t b 2 0 0 f n 0 0 0 1 r +l r l t+b t b f +n f n : (13) void glortho(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far). C. Graphics for Games Prog. 2 Page 23 of 26 January 2008
Appendix C. Cubic Bezier curves. Bernstein polynomials can be dened as follows: ( ) n B n (u) = i u i (1 u) n i ; (14) i where the value of the binomial coecient ( ) n i is given by ( ) n n! = n C i = i i!(n i)!) : (15) Cubic Bezier curves are based on the four Bernstein polynomial blending functions, B 3 0 ; B3 1 ; B3, 1 and B 3 3 shown in Figure 15. B 3 (u) 0 = u3 ; (16) B 3 (u) 1 = 3u2 (1 u); B 3 (u) 2 = 3u(1 u)2 ; B 3 (u) 3 = (1 u)3 : Figure 15: Blending functions. Linear (left) and cubic Bernstein (Bezier) (right). C. Graphics for Games Prog. 2 Page 24 of 26 January 2008
Appendix D. OpenGL Graphics Primitives. Figure 16 shows the list of possible graphics primitives and possible arguments for glbegin and Figure 17 gives a diagrammatic explanation. GL_POINTS individual points GL_LINES pairs of vertices interpreted as individual line segments GL_POLYGON boundary of a simple, convex polygon GL_TRIANGLES triples of vertices interpreted as triangles GL_QUADS quadruples of vertices interpreted as four-sided polygons GL_LINE_STRIP series of connected line segments GL_LINE_LOOP same as above, with a segment added between last and first vertices GL_TRIANGLE_STRIP linked strip of triangles GL_TRIANGLE_FAN linked fan of triangles GL_QUAD_STRIP linked strip of quadrilaterals Figure 16: Geometric Primitive Names and Meanings. C. Graphics for Games Prog. 2 Page 25 of 26 January 2008
Figure 17: Geometric Primitive Types. C. Graphics for Games Prog. 2 Page 26 of 26 January 2008