Tpic 4: OpenGL An Example Prgram Objectives Build a cmplete OpenGL prgram Initializatin steps and prgram structure GLUT functins Vertex array bjects and vertex buffer bjects Simple viewing Intrduce the OpenGL camera, rthgraphic viewing, viewprt, varius crdinate systems, transfrmatins CITS 3003 Graphics & Animatin Slides: 1 2 Defining Objects in OpenGL Prgrams In OpenGL prgrams (versin 3.1 nward), we define any bject by 1. putting all its vertices gemetric data in an array, e.g. Recall: retained vec3 pints[3]; mde graphics pints[0] = vec3(0.0, 0.0, 0.0); pints[1] = vec3(0.0, 1.0, 0.0); pints[2] = vec3(0.0, 0.0, 1.0); 2. send the array t GPU 3. tell GPU t render the pints as a triangle (fr this example). 3 simple.cpp revisited main() mre cmplex than befre; mstly calling GLUT functins init() will incrprate clr initshader() details f setting up shaders will be lked at in later lectures Key issue is that we must frm a data array t send t GPU and then render it 4 1
simple.cpp - A mre cmplex versin f main() #include "Angel.h" includes gl.h, glext.h, freeglut.h, int main(int argc, char** argv) { vec.h, mat.h, glutinit(&argc,argv); glutinitdisplaymde(glut_double GLUT_DEPTH); request duble buffering & a depth buffer glutinitwindwsize(500,500); specify windw size and psitin glutinitwindwpsitin(0,0); glutinitcntextversin( 3, 2 ); require OpenGL 3.2 Cre prfile glutinitcntextprfile( GLUT_CORE_PROFILE ); glutcreatewindw("simple"); glutdisplayfunc(mydisplay); glewinit(); init(); set OpenGL state and initialize shaders glutmainlp(); enter event lp return 0; } actually never returns create a windw with the title simple set display callback fn: mydisplay will be called when the windw needs redrawing 5 GLUT functins glutinit initializes the GLUT system allws it t receive cmmand line arguments (always include this line) glutinitdisplaymde requests prperties fr the windw (the rendering cntext) RGBA clr (default) r indexed clur (rare nw) Duble buffering (usually) r Single buffering (redraw flickers) Depth buffer (usually in 3D) stres pixel depths t find clsest surfaces [ usually with glenable(gl_depth_test); ] Others: GLUT_ALPHA, generally fr special additinal windw buffers Prperties are bitwise ORed tgether with (vertical bar) glutwindwsize defines the windw size in pixels glutwindwpsitin psitins the windw (relative t tp-left crner f display) 6 GLUT functins (cnt.) Display Callback glutcreatewindw creates windw with title simple many functins need t be called prir t creating the windw similarly many ther functins can nly be called afterwards glutdisplayfunc sets the display callback glutkeybardfunc sets the keybard callback glutreshapefunc sets the windw resize callback gluttimerfunc sets the timer callback glutidlefunc sets the idle callback glutmainlp enters infinite event lp never returns, but may exit 7 Once we get data t GPU, we can initiate the rendering with a simple display callback functin: vid mydisplay() { glclear(gl_color_buffer_bit); gldrawarrays(gl_triangles, 0, 3); } // glflush(); // Single buffering glutswapbuffers(); // Duble buffering Prir t this, the vertex buffer bjects shuld cntain the vertex data. The display callback functin is called every time the windw needs t be repainted. 8 2
Initializatin All the initializatin cdes can be put inside an init() functin. These include: Setting up the vertex array bjects and vertex buffer bjects Clearing windw s backgrund and ther OpenGL parameters Setting up vertex and fragment shaders Read in the shaders Cmpile them Link them Let s cnsider a few ther issues. 9 Vertex Arrays Vertices can have many attributes Psitin Clr Texture Crdinates Applicatin data A vertex array hlds all f these data See the types declared in vec.h, e.g., pint2 vertices[3] = {pint2(0.0, 0.0), pint2(0.0, 1.0), pint2(1.0, 1.0)}; 10 Vertex Array Objects Vertex Array Object (cnt.) A vertex array bundles all vertex data (psitins, clrs, etc) T define a vertex array bject (VAO): 1. Generate a vertex array bject ID: GLuint va; glgenvertexarrays(1, &va); 2. Bind the vertex array bject ID glbindvertexarray(va); At this pint we have a current vertex array but n cntents yet Use f glbindvertexarray lets us switch between VBOs See later 11 Unfrtunately sme pengl functins are nt cmpletely platfrm independent. On Linux/Windws: GLuint abuffer; glgenvertexarrays(1, &abuffer); glbindvertexarray(abuffer); On Mac: GLuint abuffer; glgenvertexarraysapple(1, &abuffer); glbindvertexarrayapple(abuffer); 12 3
Vertex Buffer Objects Vertex buffers bjects (VBO) allw us t transfer large amunts f data t the GPU Need t create and bind the VBO in a similar way like the vertex array bject and then cpy the vertices t the buffer: Gluint buffer; glgenbuffers(1, &buffer); glbindbuffer(gl_array_buffer, buffer); glbufferdata(gl_array_buffer, sizef(pints), pints); This is hw data in the current vertex array is sent t GPU. 13 Vertex Buffer Object (cnt.) If we have a pints array and a clurs array, then we need t specify a larger buffer fr the VBO and we need t call glbuffersubdata fr each array //need a larger buffer as it needs t hld bth //pints and clrs glbufferdata(gl_array_buffer, sizef(pints) + sizef(clurs), NULL, GL_STATIC_DRAW); //lad data separately ffset glbuffersubdata(gl_array_buffer, 0, sizef(pints), pints); glbuffersubdata(gl_array_buffer, sizef(pints), sizef(clurs), clurs); 14 Vertex Buffer Object (cnt.) Can als specify mre than ne buffer bject, e.g., 2 buffer bjects: GLuint buffer[2]; glgenbuffers(2, buffer); //d the binding and send the data fr the 1 st //t the GPU glbindbuffer(gl_array_buffer, buffer[0]); glbufferdata(gl_array_buffer, sizef(pints), pints); //d the same fr the 2 nd buffer bject glbindbuffer(gl_array_buffer, buffer[1]); glbufferdata(gl_array_buffer, sizef(clurs), clurs); pints is an array f vec2, vec3, r vec4. clurs is an array f vec3 r vec4. buffer Passing vertex crdinates (variable pints) and vertex clurs (variable clurs) t GPU using buffer[0] and buffer[1] 15 Reading, Cmpiling, and Linking Shaders In the init() functin, we als read, cmpile, and link the vertex and fragment shaders t create a prgram bject: GLuint prgram = InitShader("vshader.glsl", "fshader.glsl"); gluseprgram(prgram); The functin InitShader defined in InitShader.cpp carries ut the reading, cmpiling, and linking f the shaders. If there are errrs in any f the glsl file, the prgram will crash at this line. Exercise: study InitShader.cpp. 4
Crdinate Systems The units in the pints array (n slide 14) are determined by the applicatin and we call them the bject, wrld, mdel r prblem crdinates The viewing specificatins are usually als in bject crdinates Eventually pixels will be prduced in windw crdinates (a.k.a. screen crdinates) OpenGL shaders ften use sme internal representatins that are usually nt visible t the applicatin, such as camera crdinates (generally prir t perspective transfrmatin) The OpenGL Camera OpenGL places a camera at the rigin in the bject crdinate space pinting in the negative z directin The default viewing vlume is a bx centred at the rigin with sides f length 2 17 18 Orthgraphic Viewing Viewprts In the default rthgraphic view, pints are prjected frward alng the z axis nt the plane z = 0 z=0 We d nt have t use the entire windw t render the scene, e.g., we can set the viewprt like this: glviewprt(x,y,w,h) Values passed t this functin shuld be in pixels (windw crdinates) z=0 19 20 5
Transfrmatins and Viewing In OpenGL, prjectin is carried ut by a prjectin matrix (transfrmatin) Transfrmatins are als used fr changes in crdinate systems, e.g., vertices can be rtated and translated by transfrmatins. Transfrmatins can be applied in Applicatin cde (C++) Shader (GLSL) 21 References Interactive Cmputer Graphics A Tp-Dwn Apprach with Shader-Based OpenGL by Edward Angel and Dave Shreiner, 6 th Ed, 2012 Secs. 2.1-2.2 The Sierpinski Gasket Sec. 2.6.1 The Orthgraphic View Sec 2.7 Cntrl Functins Sec. 2.8 The Gasket Prgram Sec. 3.4 Frames in OpenGL (up t page 142) App. D.1 Initializatin and Windw Functins App. D.2 Vertex Array and Vertex Buffer Objects Angel and Shreiner: Interactive Cmputer Graphics6E Addisn-Wesley 2012 22 6