CSE 5542 Real Time Rendering Week 3 The

  • Slides: 51
Download presentation
CSE 5542 - Real Time Rendering Week 3

CSE 5542 - Real Time Rendering Week 3

The Anatomy of *GL* Program http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDI TION/CODE/CHAPTER 02/

The Anatomy of *GL* Program http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDI TION/CODE/CHAPTER 02/

The Sierpinski Gasket

The Sierpinski Gasket

The Sierpinski Gasket

The Sierpinski Gasket

Pseudo-code Immediate Mode Retained Mode

Pseudo-code Immediate Mode Retained Mode

Sierpinski in GLSL thru GLUT int main( int argc, char **argv ) { glut.

Sierpinski in GLSL thru GLUT int main( int argc, char **argv ) { glut. Init( &argc, argv ); glut. Init. Display. Mode( GLUT_RGBA ); glut. Init. Window. Size( 512, 512 ); glut. Create. Window( "Sierpinski Gasket" ); init(); glut. Display. Func( display ); glut. Keyboard. Func( keyboard ); glut. Main. Loop(); return 0; }

Callbacks – Event-based . . glut. Display. Func( display ); glut. Keyboard. Func( keyboard

Callbacks – Event-based . . glut. Display. Func( display ); glut. Keyboard. Func( keyboard ); … void keyboard( unsigned char key, int x, int y ) { switch ( key ) { case 033: exit( EXIT_SUCCESS ); break; } } void display( void ) { gl. Clear( GL_COLOR_BUFFER_BIT ); // clear the window gl. Draw. Arrays( GL_POINTS, 0, Num. Points ); // draw the points gl. Flush(); }

*GL* 8 E. Angel and D. Shreiner: Interactive Computer Graphics 6 E © Addison-Wesley

*GL* 8 E. Angel and D. Shreiner: Interactive Computer Graphics 6 E © Addison-Wesley 2012

Sierpinski in GLSL void init( void ) { vec 2 points[Num. Points]; // Specifiy

Sierpinski in GLSL void init( void ) { vec 2 points[Num. Points]; // Specifiy the vertices for a triangle vec 2 vertices[3] = { vec 2( -1. 0, -1. 0 ), vec 2( 0. 0, 1. 0 ), vec 2( 1. 0, -1. 0 ) }; // Select an arbitrary initial point inside of the triangle points[0] = vec 2( 0. 25, 0. 50 ); // compute and store N-1 new points for ( int i = 1; i < Num. Points; ++i ) { int j = rand() % 3; // pick a vertex at random // Compute the point halfway between the selected vertex // and the previous points[i] = ( points[i - 1] + vertices[j] ) / 2. 0; } // Create a vertex array object GLuint vao[1]; gl. Gen. Vertex. Arrays( 1, vao ); gl. Bind. Vertex. Array( vao[0] ); // Create and initialize a buffer object GLuint buffer; gl. Gen. Buffers( 1, &buffer ); gl. Bind. Buffer( GL_ARRAY_BUFFER, buffer ); gl. Buffer. Data( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

Sierpinski in GLSL // Load shaders and use the resulting shader program GLuint program

Sierpinski in GLSL // Load shaders and use the resulting shader program GLuint program = Init. Shader( "vshader 21. glsl", "fshader 21. glsl" ); gl. Use. Program( program ); // Initialize the vertex position attribute from the vertex shader GLuint loc = gl. Get. Attrib. Location( program, "v. Position" ); gl. Enable. Vertex. Attrib. Array( loc ); gl. Vertex. Attrib. Pointer( loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); gl. Clear. Color( 1. 0, 1. 0 ); // white background }

Sierpinski Vertex Shader … // Load shaders and use the resulting shader program GLuint

Sierpinski Vertex Shader … // Load shaders and use the resulting shader program GLuint program = Init. Shader( "vshader 21. glsl", "fshader 21. glsl" ); gl. Use. Program( program ); . . attribute vec 4 v. Position; void main() { gl_Position = v. Position; }

Sierpinski Fragment Shader … // Load shaders and use the resulting shader program GLuint

Sierpinski Fragment Shader … // Load shaders and use the resulting shader program GLuint program = Init. Shader( "vshader 21. glsl", "fshader 21. glsl" ); gl. Use. Program( program ); . . void main() { gl_Frag. Color = vec 4( 1. 0, 0. 0, 1. 0 ); }

Compiling Code

Compiling Code

Mac. Os http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITIO N/apple 14

Mac. Os http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITIO N/apple 14

Windows/VC++ http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/ vc

Windows/VC++ http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/ vc

Linux http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/li nux 16

Linux http: //www. cs. unm. edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/li nux 16

Another Example

Another Example

Triangles. cpp void #include <iostream> init(void) using namespace std; { #include "vgl. h” gl.

Triangles. cpp void #include <iostream> init(void) using namespace std; { #include "vgl. h” gl. Gen. Vertex. Arrays(Num. VAOs, VAOs); #include "Load. Shader. h” gl. Bind. Vertex. Array(VAOs[Triangles]); enum VAO_IDs { Triangles, Num. VAOs }; enum Buffer_IDs { Array. Buffer, Num. Buffers }; GLfloat vertices[Num. Vertices][2] = { { -0. 90, -0. 90 }, // Triangle 1 enum Attrib_IDs { v. Position = 0 }; { 0. 85, -0. 90 }, { -0. 90, 0. 85 }, GLuint VAOs[Num. VAOs]; { 0. 90, -0. 85 }, // Triangle 2 GLuint Buffers[Num. Buffers]; { 0. 90, 0. 90 }, { -0. 85, 0. 90 } const GLuint Num. Vertices = 6; }; gl. Gen. Buffers(Num. Buffers, Buffers); gl. Bind. Buffer(GL_ARRAY_BUFFER, Buffers[Array. Buffer]); gl. Buffer. Data(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

Shader. Info shaders[] = { { GL_VERTEX_SHADER, "triangles. vert" }, { GL_FRAGMENT_SHADER, "triangles. frag"

Shader. Info shaders[] = { { GL_VERTEX_SHADER, "triangles. vert" }, { GL_FRAGMENT_SHADER, "triangles. frag" }, { GL_NONE, NULL } }; GLuint program = Load. Shaders(*shaders); gl. Use. Program(program); gl. Vertex. Attrib. Pointer(v. Position, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); gl. Enable. Vertex. Attrib. Array(v. Position); } void display(void) { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Bind. Vertex. Array(VAOs[Triangles]); gl. Draw. Arrays(GL_TRIANGLES, 0, Num. Vertices); gl. Flush(); }

Main() Int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode(GLUT_RGBA);

Main() Int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode(GLUT_RGBA); glut. Init. Window. Size(512, 512); glut. Init. Context. Version(4, 3); glut. Init. Context. Profile(GLUT_CORE_PROFILE); glut. Create. Window(argv[0]); glew. Experimental = GL_TRUE; if (glew. Init()) { cerr << "Unable to initialize GLEW. . . exiting" << endl; exit(EXIT_FAILURE); } init(); glut. Display. Func(display); glut. Main. Loop(); }

// Create a vertex array object GLuint vao[1]; gl. Gen. Vertex. Arrays( 1, vao

// Create a vertex array object GLuint vao[1]; gl. Gen. Vertex. Arrays( 1, vao ); gl. Bind. Vertex. Array( vao[0] );

Vertex Arrays • Vertices can have many attributes – Position – Color – Texture

Vertex Arrays • Vertices can have many attributes – Position – Color – Texture Coordinates – Application data • A vertex array holds these data • Using types in vec. h point 2 vertices[3] = {point 2(0. 0, 0. 0), point 2( 0. 0, 1. 0), point 2(1. 0, 1. 0)}; 23

Vertex Array Object • Bundles all vertex data (positions, colors, . . , )

Vertex Array Object • Bundles all vertex data (positions, colors, . . , ) Glunit abuffer; • Get name for buffer then bind gl. Gen. Vertex. Arrays(1, &abuffer); gl. Bind. Vertex. Array(abuffer); • At this point we have a current vertex array but no contents • Use of gl. Bind. Vertex. Array lets us switch between VBOs 24

// Create and initialize a buffer object GLuint buffer; gl. Gen. Buffers( 1, &buffer

// Create and initialize a buffer object GLuint buffer; gl. Gen. Buffers( 1, &buffer ); gl. Bind. Buffer( GL_ARRAY_BUFFER, buffer ); gl. Buffer. Data( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

Buffer Object • Buffers objects allow us to transfer large amounts of data to

Buffer Object • Buffers objects allow us to transfer large amounts of data to the GPU • Need to create, bind and identify data Gluint buffer; gl. Gen. Buffers(1, &buffer); gl. Bind. Buffer(GL_ARRAY_BUFFER, buffer); gl. Buffer. Data(GL_ARRAY_BUFFER, sizeof(points), points); • Data in current vertex array is sent to GPU 26

http: //www. khronos. org/files/opengl-quickreference-card. pdf

http: //www. khronos. org/files/opengl-quickreference-card. pdf

Open. GL Recipes

Open. GL Recipes

Sierpinski Again void main(int argc, char** argv) { /* Standard GLUT initialization */ glut.

Sierpinski Again void main(int argc, char** argv) { /* Standard GLUT initialization */ glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glut. Init. Window. Size(500, 500); /* 500 x 500 pixel window */ glut. Init. Window. Position(0, 0); /* place window top left on display */ glut. Create. Window("Sierpinski Gasket"); /* window title */ glut. Display. Func(display); /* display callback invoked when window opened */ myinit(); /* set attributes */ glut. Main. Loop(); /* enter event loop */ }

Sierpinski World /* Two-Dimensional Sierpinski Gasket */ /* Generated Using Randomly Selected Vertices */

Sierpinski World /* Two-Dimensional Sierpinski Gasket */ /* Generated Using Randomly Selected Vertices */ /* And Bisection */ void myinit() { /* attributes */ gl. Clear. Color(1. 0, 1. 0); /* white background */ gl. Color 3 f(1. 0, 0. 0); /* draw in red */ /* set up viewing */ /* 500 x 500 window with origin lower left */ gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); glu. Ortho 2 D(0. 0, 50. 0); gl. Matrix. Mode(GL_MODELVIEW); }

No Shaders Here void display( void ) { GLfloat vertices[3][2]={{0. 0, 0. 0}, {25.

No Shaders Here void display( void ) { GLfloat vertices[3][2]={{0. 0, 0. 0}, {25. 0, 50. 0}, {50. 0, 0. 0}}; /* A triangle */ int j, k; int rand(); /* standard random number generator */ GLfloat p[2] ={7. 5, 5. 0}; /* An arbitrary initial point inside traingle */ gl. Clear(GL_COLOR_BUFFER_BIT); /*clear the window */ /* compute and plots 5000 new points */ gl. Begin(GL_POINTS); for( k=0; k<5000; k++){ j=rand()%3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0]+vertices[j][0])/2. 0; p[1] = (p[1]+vertices[j][1])/2. 0; /* plot new point */ gl. Vertex 2 fv(p); } gl. End(); gl. Flush(); /* clear buffers */ }

A Recursive Open. GL Example

A Recursive Open. GL Example

The Basic Shape * initial triangle */ GLfloat v[3][2]={{-1. 0, -0. 58}, {0. 0,

The Basic Shape * initial triangle */ GLfloat v[3][2]={{-1. 0, -0. 58}, {0. 0, 1. 15}}; int n; void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* specify one triangle */ { gl. Vertex 2 fv(a); gl. Vertex 2 fv(b); gl. Vertex 2 fv(c); }

The Inductive step void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int m) { /*

The Inductive step void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int m) { /* triangle subdivision using vertex numbers */ GLfloat v 0[2], v 1[2], v 2[2]; int j; if(m>0) { for(j=0; j<2; j++) v 0[j]=(a[j]+b[j])/2; for(j=0; j<2; j++) v 1[j]=(a[j]+c[j])/2; for(j=0; j<2; j++) v 2[j]=(b[j]+c[j])/2; divide_triangle(a, v 0, v 1, m-1); divide_triangle(c, v 1, v 2, m-1); divide_triangle(b, v 2, v 0, m-1); } else triangle(a, b, c); /* draw triangle at end of recursion */ }

Callbacks – same as before void display() { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Begin(GL_TRIANGLES); divide_triangle(v[0], v[1],

Callbacks – same as before void display() { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Begin(GL_TRIANGLES); divide_triangle(v[0], v[1], v[2], n); gl. End(); gl. Flush(); } void myinit() { gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); glu. Ortho 2 D(-2. 0, 2. 0); gl. Matrix. Mode(GL_MODELVIEW); gl. Clear. Color (1. 0, 1. 0); gl. Color 3 f(0. 0, 0. 0); }

The main() – same as before int main(int argc, char **argv) { n=atoi(argv[1]); /*

The main() – same as before int main(int argc, char **argv) { n=atoi(argv[1]); /* or set number of subdivision steps here */ glut. Init(&argc, argv); glut. Init. Display. Mode(GLUT_SINGLE | GLUT_RGB); glut. Init. Window. Size(500, 500); glut. Create. Window("Sierpinski Gasket"); glut. Display. Func(display); myinit(); glut. Main. Loop(); }

Now As Shaders

Now As Shaders

Shading & Subdivision #include "Angel. h” using namespace std; const int Num. Times. To.

Shading & Subdivision #include "Angel. h” using namespace std; const int Num. Times. To. Subdivide = 5; const int Num. Triangles = 243; // 3^5 triangles generated const int Num. Vertices = 3 * Num. Triangles; vec 2 points[Num. Vertices]; int Index = 0; void triangle( const vec 2& a, const vec 2& b, const vec 2& c ) { points[Index++] = a; points[Index++] = b; points[Index++] = c; }

Induction void divide_triangle( const vec 2& a, const vec 2& b, const vec 2&

Induction void divide_triangle( const vec 2& a, const vec 2& b, const vec 2& c, int count ) { if ( count > 0 ) { vec 2 v 0 = ( a + b ) / 2. 0; vec 2 v 1 = ( a + c ) / 2. 0; vec 2 v 2 = ( b + c ) / 2. 0; divide_triangle( a, v 0, v 1, count - 1 ); divide_triangle( c, v 1, v 2, count - 1 ); divide_triangle( b, v 2, v 0, count - 1 ); } else { triangle( a, b, c ); // draw triangle at end of recursion } }

Shader Mechanics // Load shaders and use the resulting shader void init( void )

Shader Mechanics // Load shaders and use the resulting shader void init( void ) program { vec 2 vertices[3] = {vec 2( -1. 0, -1. 0 ), vec 2( 0. 0, 1. 0 ), vec 2( 1. 0, -1. 0 GLuint program = Init. Shader( "vshader 22. glsl", )}; "fshader 22. glsl" ); // Subdivide the original triangle divide_triangle( gl. Use. Program( program ); vertices[0], vertices[1], vertices[2], Num. Times. To. Subdivide ); // Initialize vertex position attribute from vertex shader GLuint loc = gl. Get. Attrib. Location(program, // Create a vertex array object "v. Position" ); GLuint vao; gl. Enable. Vertex. Attrib. Array( loc ); gl. Gen. Vertex. Arrays. APPLE( 1, &vao ); gl. Vertex. Attrib. Pointer( loc, 2, GL_FLOAT, gl. Bind. Vertex. Array. APPLE( vao ); GL_FALSE, 0, BUFFER_OFFSET(0) ); // Create and initialize a buffer object gl. Clear. Color( 1. 0, 1. 0 ); GLuint buffer; /* white background */ gl. Gen. Buffers( 1, &buffer ); gl. Bind. Buffer( GL_ARRAY_BUFFER, buffer ); } gl. Buffer. Data( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );

Same Callbacks void display( void ) { gl. Clear( GL_COLOR_BUFFER_BIT ); gl. Draw. Arrays(

Same Callbacks void display( void ) { gl. Clear( GL_COLOR_BUFFER_BIT ); gl. Draw. Arrays( GL_TRIANGLES, 0, Num. Vertices ); gl. Flush(); } void keyboard( unsigned char key, int x, int y ) { switch ( key ) { case 033: exit( EXIT_SUCCESS ); break; } }

And the same main() int main( int argc, char **argv ) { glut. Init(

And the same main() int main( int argc, char **argv ) { glut. Init( &argc, argv ); glut. Init. Display. Mode( GLUT_RGBA ); glut. Init. Window. Size( 512, 512 ); glut. Create. Window( "Simple GLSL example" ); init(); glut. Display. Func( display ); glut. Keyboard. Func( keyboard ); glut. Main. Loop(); return 0; }

One Last Example

One Last Example

Open. GL 1. x Code Example void Display() { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Color 4

Open. GL 1. x Code Example void Display() { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Color 4 f(1, 1, 0, 1); gl. Begin(GL_POLYGON); gl. Vertex 2 f(-0. 5, -0. 5); gl. Vertex 2 f(-0. 5, 0. 5); gl. Vertex 2 f(0. 5, -0. 5); gl. End(); gl. Flush(); }

Open. GL Functions • Primitives – Points – Line Segments – Triangles • Attributes

Open. GL Functions • Primitives – Points – Line Segments – Triangles • Attributes • Transformations – Viewing – Modeling • Control (GLUT) • Input (GLUT) • Query 45

Open. GL and GLSL

Open. GL and GLSL

Open. GL and GLSL • Shader based Open. GL is based less on a

Open. GL and GLSL • Shader based Open. GL is based less on a state machine model than a data flow model • Most state variables, attributes and related pre 3. 1 Open. GL functions have been deprecated • Action happens in shaders • Job is application is to get data to GPU 47

Open. GL State • Open. GL is a state machine • Open. GL functions

Open. GL State • Open. GL is a state machine • Open. GL functions are of two types – Primitive generating • Can cause output if primitive is visible • How vertices are processed and appearance of primitive are controlled by the state – State changing • Transformation functions • Attribute functions • Under 3. 1 most state variables are defined by the application and sent to the shaders 48

GLSL • Open. GL Shading Language • C-like with – Matrix and vector types

GLSL • Open. GL Shading Language • C-like with – Matrix and vector types (2, 3, 4 dimensional) – Overloaded operators – C++ like constructors • Similar to Nvidia’s Cg and Microsoft HLSL • Code sent to shaders as source code • New Open. GL functions to compile, link 49

Still Maximal Portability • Display device independent • Window system independent • Operating system

Still Maximal Portability • Display device independent • Window system independent • Operating system independent

The End

The End