OpenGL Buffers CGT520 Modeling Bedrich Benes, Ph.D. Purdue University Department of Computer Graphics frame buffer consists of pixel (RGB values) alpha buffer pixel’s transparency 0-opaque,255-transparent © Bedrich Benes OpenGL Buffers z-buffer (depth) z is the distance of a pixel from the viewer z-test is used for visibility stencil buffer controls special writing operations • Some values are set explicitly by the user • Some are set by rendering © Bedrich Benes OpenGL Buffers Clearing a buffer 1) specify the value 2) clear the buffer © Bedrich Benes Specifying the Clear Value Clearing the Buffer glClearColor(GLclampf r,GLclampf g, GLclampf b,GLclampf a) void glClear(GLbitfield mask) glClearDepth(GLclampd d) glClearStencil(GLint s) • mask is a logical OR color GL_COLOR_BUFFER_BIT depth GL_DEPTH_BUFFER_BIT stencil GL_STENCIL_BUFFER_BIT • typically: glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); © Bedrich Benes © Bedrich Benes Forcing Completion of Drawing Vertex Array and Vertex Buffer • due to optimizations some command may be stuck • there are two “chimney-sweeper” commands • OpenGL uses a concept of buffers void glFlush() void glFinish() the glFlush() command forces OpenGL to finish all previously executed commands in finite time • So called vertex-array object is a GPU-oriented data structure that allows multiple vertex-buffers to be associated with it the glFinish() command forces the OpenGL to finish all previously executed commands and waits for the result if you think of CPU and OpenGL as a parallel processes what kind of synchronization task is it? © Bedrich Benes © Bedrich Benes Vertex Array and Vertex Buffer Vertex Array • The data is created on the CPU GLuint vaID; • The data is bound to the GPU //allocate single VA glGenVertexArrays(1,&vaID); • The data is rendered //bind it glBindVertexArray(va); © Bedrich Benes Vertex Buffer GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER,buf); glBufferData(GL_ARRAY_BUFFER, size,v,GL_STATIC_DRAW); glVertexAttribPointer((GLuint)0, 3,GL_FLOAT,GL_FALSE,0,0); glEnableVertexAttribArray(0); © Bedrich Benes © Bedrich Benes Data Definition const int points=128; GLfloat* v=new float[3*points]; © Bedrich Benes Creating a Circle GLuint i=0; GLfloat d=2*M_PI/steps; for (GLfloat a=0;a<=2*M_PI;a+=d){ a[i++]=sin(a); a[i++]=cos(a); a[i++]=0;} Rendering OpenGL primitives glDrawArrays(GL_POINTS,0,points); Unit circle © Bedrich Benes © Bedrich Benes OpenGL Primitives points GL_POINTS lines GL_LINES polylines GL_LINE_STRIP closed polylines GL_LINE_LOOP triangles GL_TRIANGLES triangle strips GL_TRIANGLE_STRIP triangle fans GL_TRIANGLE_FAN © Bedrich Benes OpenGL Primitives GL_LINE_STRIP_ADJACENCY, GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY GL_PATCHES © Bedrich Benes OpenGL Primitives Lines in OpenGL 2 • Note: 3 5 GL_LINES 6 4 • GL_QUADS • GL_QUAD_STRIP • GL_POLYGON 1 2 3 5 GL_LINE_STRIP 6 4 1 are deprecated! 2 3 5 GL_LINE_LOOP 6 © Bedrich Benes 4 © Bedrich Benes 1 Triangles Triangle Strips 6 4 GL_TRIANGLES 2 • less than three vertices per ! 5 1 3 6 4 • an ordered vertex list 2 GL_TRIANGLE_STRIP • the i-th triangle 5 1 3 3 4 1 5 1 1 triangles • average # of vertices per triangle 1 © Bedrich Benes 0 • the vertex list includes 2 GL_TRIANGLE_LOOP • a sequential triangle strip is defined by © Bedrich Benes Triangle Strips Triangle Strips vs. Triangle Fans • average # of vertices per triangle • the same stands for triangle fans • where • some providers (NVIDA) suggest using strips is the length of the list → • imagine , • we save of space (wow!) © Bedrich Benes • they are better optimized © Bedrich Benes Generalized Triangle Strips Triangle Fans • the sequence of is not strictly sequential • a general convex polygon can be converted into a single fan or a simple strip • to use them, we need a vertex cache or the swap operation • The vertex must be resend © Bedrich Benes is the same as for strips (the same startup) • any fan can be converted into generalized strip (repeat the center or many swaps), but not vice versa © Bedrich Benes Some Attributes OpenGL Back Face Culling glPointSize(GLfloat size) • each polygon has two sides the front face and the back face glLineWidth(GLfloat width) • back face culling means discarding back faces before rasterization • default OpenGL value: both faces are rendered - time consuming! © Bedrich Benes © Bedrich Benes OpenGL Back Face Culling OpenGL Back Face Culling • front face has the projected vertices on the screen in the counterclockwise order what is culled can be set by void glCullFace(GLenum mode); where mode is GL_FRONT or GL_BACK or GL_FRONT_AND_BACK the face culling is set by glEnable(GL_CULL_FACE); glDisable(GL_CULL_FACE); © Bedrich Benes © Bedrich Benes OpenGL Face Rendering OpenGL Face Rendering Front and Back faces can be rendered in different modes • determining the drawing mode of a face void glPolygonMode(GLenum face, GLenum mode) face =GL_FRONT|GL_BACK|GL_FRONT_AND_BACK mode=GL_POINT |GL_LINE | GL_FILL default: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) © Bedrich Benes GL_POINT GL_LINE GL_FILL © Bedrich Benes OpenGL Face Orientation OpenGL Face Orientation How can we change the face orientation? • Triangle strip has orientation defined by the first triangle • change vertex order • change polygon mode void glFrontFace(GLenum mode) mode is GL_CCW (counterclockwise) or GL_CW (clockwise) © Bedrich Benes © Bedrich Benes Modeling a Cube Modeling a Cube H #define A {-0.5,-0.5,-0.5} #define B {+0.5,-0.5,-0.5} E #define C {+0.5, +0.5,-0.5} G F … D C vector <GLfloat> v; v.push_back(A[0]); v.push_back(A[1]); … A • Using STL vector: glBufferData(GL_ARRAY_BUFFER, v.size()*sizeof(GLfloat),&v[0], GL_STATIC_DRAW); B glDrawArrays(GL_TRIANGLES,0,12); © Bedrich Benes Considerations © Bedrich Benes Tessellation • Keep a list of smallest versatile elements • Usually the best is a list of triangle strips • Avoid T-vertices! • They can crack when transformed • They cause bad illumination artifacts © Bedrich Benes Tessellation is a process of converting a complex object into simpler primitives such as triangles or quadrilaterals Tessellation is the most frequently wrongly spelled word in Computer Graphics © Bedrich Benes Sphere Tessellation (approach 1) Sphere Tessellation (approach 1) Stacks and Slices: Parametric equation of sphere • not a very good approach: • generates very different = • generates long • involves and © Bedrich Benes © Bedrich Benes Sphere Tessellation (approach 1) Sphere Tessellation (approach 1) • Leads to a tessellation: , Δ , mΔ Δ 2Δ , • Implementation: Δ , Δ Δ … … … , Δ Δ , Δ 2Δ , Δ Δ , … , © Bedrich Benes Δ , 2Δ , Δ Vect3d v; Glfloat deltaTheta=2*M_PI/(GLfloat)slices; GLfloat deltaPhi = M_PI/(GLfloat)stacks; for (GLuint i=0;i<stacks;i++){ GLfloat phi=i*deltaPhi; for (GLuint j=0;j<slices;j++){ GLfloat theta=j*deltaTheta; Δ , © Bedrich Benes Sphere Tessellation (approach 1) Sphere Tessellation (approach 1) //the first triangle //the second triangle v.Set(r*cos(theta)*sin(phi), r*sin(theta)*sin(phi), r*cos(phi)); v.Set(r*cos(theta+deltaTheta)*sin(phi), r*sin(theta+deltaTheta)*sin(phi), r*cos(phi)); v.Set(r*cos(theta)*sin(phi+deltaPhi), r*sin(theta)*sin(phi+deltaPhi), r*cos(phi+deltaPhi)); v.Set(r*cos(theta+deltaTheta)*sin(phi), r*sin(theta+deltaTheta)*sin(phi), r*cos(phi)); v.Set(r*cos(theta+deltaTheta)*sin(phi+deltaPhi), r*sin(theta+deltaTheta)*sin(phi+deltaPhi), r*cos(phi+deltaPhi)); v.Set(r*cos(theta+deltaTheta)*sin(phi+deltaPhi), r*sin(theta+deltaTheta)*sin(phi+deltaPhi), r*cos(phi+deltaPhi)); } © Bedrich Benes Sphere Tessellation (approach 1) © Bedrich Benes Sphere Tessellation (approach 1) • Results: • Summary: • • • • © Bedrich Benes © Bedrich Benes Very simple to implement Very simple to control ( Not very efficient – large and ugly triangles Uses trigonometric functions (can be slow) Sphere Tessellation (approach 2) Circle Tessellation (approach 2) Recursive subdivision • Subdivision much better approach Two vertices on the unit circle Find the midpoint Move it on the unit circle Let’s do it for a circle first: Do it for all line segments © Bedrich Benes © Bedrich Benes Circle Tessellation (approach 2) Circle Tessellation (approach 2) • All vertices have unit dist. from the origin • Algorithm: Subdivide(Vert3d , Vert3d , GLuint ) Input: Vertices , , number of steps Output: 2 vertices on the circle 1) if (n==0) return and 2) find © Bedrich Benes 3) Normalize( ); //this will put it on the unit circle 4) Subdivide(a, mid, n-1); 5) Subdivide(mid, b, n-1); © Bedrich Benes Circle Tessellation (approach 2) Sphere Tessellation (approach 2) • Considerations: Now this generalizes to the sphere • The input vertices must already be on the unit circle • It needs to be rendered using GL_LINES as the algorithm does not provide a continuous polyline © Bedrich Benes © Bedrich Benes Sphere Tessellation (approach 2) Sphere Tessellation (approach 2) Implementation: top Each sub-triangle has vertices as given here © Bedrich Benes mid left right void Subdivide(CTriangle *t, int n){ if (n==0){OutputTriangle();return;} Vect3d v12, v23, v31; v12=(t‐>v1+t‐>v2)/2.f;v12.Normalize(); v23=(t‐>v2+t‐>v3)/2.f;v23.Normalize(); v31=(t‐>v3+t‐>v1)/2.f;v31.Normalize(); © Bedrich Benes Sphere Tessellation (approach 2) top=new CTriangle(v31,v23,v‐>v3); Subdivide(a, top, n‐1);delete top; mid=new CTriangle(v12,v23,v31); Subdivide(a, mid, n‐1); delete mid; left=new CTriangle(t‐>v1,v12,v31); Subdivide(a, left, n‐1); delete left; right=new Ctriangle(v12,t‐>v2,v23); Subdivide(a, right, n‐1); delete right; Sphere Tessellation (approach 2) • Initial position of the triangles: two tetrahedra • Top view: 120 120 } © Bedrich Benes Sphere Tessellation (approach 2) © Bedrich Benes Cone Tessellation Circle to point ruled surface • make tessallation of a circle and connect each line with the apex • can be rendered as a triangle fan © Bedrich Benes © Bedrich Benes Cone Tessellation Cone Tessellation • Implementation: AddVertex(a,Vect3d(0,1,0)); //apex of the cone GLfloat delta=2.f*M_PI/(n‐1); for (int i=0;i<=n;i++) AddVertex(a,Vect3d(cos(delta*i),0,sin(delta*i))); • Rendering: glDrawArrays(GL_TRIANGLE_FAN, 0, points); © Bedrich Benes © Bedrich Benes Cylinder Tessellation General Ruled Surface Tessellation • • • • • Cylinder is a special case of ruled surface and • Defined by two curves • Assuming both are parameterized Two circles The same stride Two triangles One triangle strip • The resulting surface is © Bedrich Benes • Note, the connecting curves are line segments © Bedrich Benes General Ruled Surface Tessellation • Example (sin to line): General Ruled Surface Tessellation • Example (sin to line) Gives © Bedrich Benes General Ruled Surface Tessellation • Implementation: If all is nicely overloaded, can be simple… Vect3d P(GLfloat t){return Vect3d(t,0,0);} Vect3d Q(GLfloat t) {return Vect3d(t,sin(2*M_PI*t),1);} Vect3d S(GLfloat u, GLfloat t) {return Vect3d(u*P(t)+(1‐u)*Q(t));} © Bedrich Benes © Bedrich Benes General Ruled Surface Tessellation • Implementation (tessellation) It is the same as stacked and sliced sphere: GLfloat step=1.f/n; for (int i=0;i<n;i++){ for (int j=0;j<n;j++){//lower triangle AddVertex(a,S(i*step,j*step)); AddVertex(a,S((i+1)*step,j*step)); AddVertex(a,S((i+1)*step,(j+1)*step)); //upper triangle similarly } } © Bedrich Benes General Ruled Surface Tessellation • • • • • and can be anything Two lines quadrilateral Circle and circle cylinder Circle and point cone Quad and quad cube etc. © Bedrich Benes General Ruled Surface Tessellation • Can we generalize the connecting curve? © Bedrich Benes Surface of Revolution Surface of Revolution • Surface of revolution is given by a curve rotated around an axis • Assuming • the axis of rotation is • The defined curve is • The surface is a set of co-centric circles around the axis ( © Bedrich Benes © Bedrich Benes modifies the radius of a circle at level ) Surface of Revolution Surface of Revolution • Implementation: If all is nicely overloaded, can be simple… GLfloat P(GLfloat u){//def. func returns a number return 0.2*sin(4*M_PI*u)+1.f; } Vect3d S(GLfloat u, GLfloat v){ return Vect3d(P(u)*sin(2*M_PI*v), u, P(u)*cos(2*M_PI*v)); } © Bedrich Benes Surface of Revolution • • • • can be anything Line parallel to axis of rotation cylinder Line from the origin cone Half circle sphere etc. © Bedrich Benes © Bedrich Benes Surface of Revolution • Sphere as a surface of revolution • We need radius of the sphere as the function of a single parameter We need to reparametrize © Bedrich Benes to be Surface of Revolution Reading GLfloat P(GLfloat u){ u=1‐2*u;//reparametrize to <‐1,1> return (sqrt(1.f‐u*u)); } • Jackie Neider, Tom Davis, Mason Woo OpenGL Programming Guide, Addison-Wesley Publication Company • Edward Engel Interactive Computer Graphics: A Top-Down Approach with Shader-Based OpenGL (6th Edition) © Bedrich Benes © Bedrich Benes
© Copyright 2024 Paperzz