1 / 33

Teaching Computer Graphics with Modern OpenGL

Teaching Computer Graphics with Modern OpenGL. Ed Angel University of New Mexico. Overview. Starting teaching a top-down approach using OpenGL about 20 years ago Co-author of Interactive Computer Graphics Sixth edition switched to a fully shader-based approach Successful but ….

vui
Télécharger la présentation

Teaching Computer Graphics with Modern OpenGL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Teaching Computer Graphics with Modern OpenGL Ed AngelUniversity of New Mexico

  2. Overview • Starting teaching a top-down approach using OpenGL about 20 years ago • Co-author of Interactive Computer Graphics • Sixth edition switched to a fully shader-based approach • Successful but …..

  3. In the Beginning … • OpenGL 1.0 was released on July 1st, 1994 • Its pipeline was entirely fixed-function • the only operations available were fixed by the implementation • The pipeline evolved, but remained fixed-function through OpenGL versions 1.1 through 2.0 (Sept. 2004) VertexData Vertex Transform and Lighting Primitive Setup and Rasterization Fragment Coloring and Texturing Blending PixelData TextureStore

  4. Sierpinski Gasket

  5. First Program (old style) #include <GL/glut.h> void myinit() { glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */ glColor3f(1.0, 0.0, 0.0); /* draw in red */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 50.0, 0.0, 50.0); glMatrixMode(GL_MODELVIEW); } void display( void ) { GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; /* A triangle */ intj, k; int rand(); /* standard random number generator */ GLfloat p[2] ={7.5,5.0}; /* An arbitrary initial point inside traingle */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window */ /* compute and plots 5000 new points */ glBegin(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 */ glVertex2fv(p); } glEnd(); glFlush(); /* clear buffers */ } void main(intargc, char** argv) { /* Standard GLUT initialization */ glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glutInitWindowSize(500,500); /* 500 x 500 pixel window */ glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Sierpinski Gasket"); /* window title */ glutDisplayFunc(display); /* display callback invoked when window opened */ myinit(); /* set attributes */ glutMainLoop(); /* enter event loop */ }

  6. void display( void ) { GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0}, {50.0,0.0}}; / intj, k; int rand(); /* standard random number generator */ GLfloat p[2] ={7.5,5.0}; /*point inside triangle */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window */ /* compute and plots 5000 new points */ glBegin(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 */ glVertex2fv(p); } glEnd(); glFlush(); /* clear buffers */ } void main(intargc, char** argv) { /* Standard GLUT initialization */ glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glutInitWindowSize(500,500); /* 500 x 500 pixel window */ glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Sierpinski Gasket"); /* window title */ glutDisplayFunc(display); /* display callback invoked when window opened */ myinit(); /* set attributes */ glutMainLoop(); /* enter event loop */ }

  7. glBegin(GL_POINTS); for( k=0; k<5000; k++) { j=rand()%3; /* pick a vertex at random */ p[0] = (p[0]+vertices[j][0])/2.0; p[1] = (p[1]+vertices[j][1])/2.0; glVertex2fv(p); } glEnd(); glFlush(); /* clear buffers */ } void main(intargc, char** argv) { /* Standard GLUT initialization */ glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glutInitWindowSize(500,500); /* 500 x 500 pixel window */ glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Sierpinski Gasket"); /* window title */ glutDisplayFunc(display); /* display callback invoked when window opened */ myinit(); /* set attributes */ glutMainLoop(); /* enter event loop */ }

  8. void main(intargc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Sierpinski Gasket"); glutDisplayFunc(display); myinit(); glutMainLoop(); /* enter event loop */ }

  9. The Start of the Programmable Pipeline • OpenGL 2.0 (officially) added programmable shaders • vertex shading augmented the fixed-function transform and lighting stage • fragment shading augmented the fragment coloring stage • However, the fixed-function pipeline was still available VertexData Vertex Transform and Lighting Primitive Setup and Rasterization Fragment Coloring and Texturing Blending PixelData TextureStore

  10. An Evolutionary Change • OpenGL 3.0 introduced the deprecation model • the method used to remove features from OpenGL • The pipeline remained the same until OpenGL 3.1 (released March 24th, 2009) • Introduced a change in how OpenGL contexts are used

  11. The Exclusively Programmable Pipeline • OpenGL 3.1 removed the fixed-function pipeline • programs were required to use only shaders • Additionally, almost all data is GPU-resident • all vertex data sent using buffer objects VertexData VertexShader Primitive Setup and Rasterization FragmentShader Blending TextureStore PixelData

  12. More Evolution – Context Profiles • OpenGL 3.2 also introduced context profiles • profiles control which features are exposed • it’s like GL_ARB_compatibility, only not insane  • currently two types of profiles: core and compatible

  13. First Program (old style) #include <GL/glut.h> void myinit() { glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */ glColor3f(1.0, 0.0, 0.0); /* draw in red */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 50.0, 0.0, 50.0); glMatrixMode(GL_MODELVIEW); }

  14. void display( void ) { GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0}, {50.0,0.0}}; / intj, k; int rand(); /* standard random number generator */ GLfloat p[2] ={7.5,5.0}; /*point inside triangle */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window */ /* compute and plots 5000 new points */

  15. glBegin(GL_POINTS); for( k=0; k<5000; k++) { j=rand()%3; /* pick a vertex at random */ p[0] = (p[0]+vertices[j][0])/2.0; p[1] = (p[1]+vertices[j][1])/2.0; glVertex2fv(p); } glEnd(); glFlush(); /* clear buffers */ }

  16. void main(intargc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Sierpinski Gasket"); glutDisplayFunc(display); myinit(); glutMainLoop(); /* enter event loop */ }

  17. Fully Shader-Based Version • Let’s look at same example • Contend not significantly harder • But model is different: retained mode • Still use GLUT (or freeglut) • C++ better • Provide mat.h and vec.h to match GLSL

  18. example.cpp #include "Angel.h” const intNumPoints = 5000; void init( void ) { vec2 points[NumPoints]; vec2 vertices[3] = {vec2(-1.0, -1.0), vec2(0.0, 1.0), vec2(1.0, -1.0 )}; points[0] = vec2( 0.25, 0.50 ); for ( inti = 1; i < NumPoints; ++i ) { intj = rand() % 3; points[i] = ( points[i - 1] + vertices[j] ) / 2.0; }

  19. example.cpp GLuint vao[1]; glGenVertexArrays ( 1, vao ); glBindVertexArray ( vao[0] ); GLuint buffer; glGenBuffers( 1, &buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW ); GLuint program = InitShader( "vshader21.glsl”, "fshader21.glsl" ); glUseProgram( program );

  20. example.cpp GLuint loc = glGetAttribLocation( program, "vPosition" ); glEnableVertexAttribArray( loc ); glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background }

  21. example.cpp void display( ) { glClear( GL_COLOR_BUFFER_BIT ); // clear the window glDrawArrays( GL_POINTS, 0, NumPoints ); // draw the points glFlush(); }

  22. example.cpp int main( intargc, char **argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA ); glutInitWindowSize( 512, 512 ); glutCreateWindow( "Sierpinski Gasket" ); init(); glutDisplayFunc( display ); glutMainLoop(); return 0; }

  23. shaders in vec4 vPosition; void main() { gl_Position = vPosition; } out vec4 FragColor; void main() { gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); }

  24. Issues • Not hard to get students started • Present situation has some problems • No GLU • What to do about GLUT • Interactivity more difficult • System dependencies • Web is what is happening

  25. Observations • We are teaching Computer Graphics • We are not teaching OpenGL as anything but a tool to help • No negative feedback from instructors • Top-down programming approach is still best • Must keep up with advances in hardware • Interactivity a problem • Will WebGL replace desktop OpenGL for teaching?

  26. WebGL version var canvas; vargl; varNumPoints = 5000; window.onload = init; function init() { canvas = document.getElementById( "gl-canvas" ); gl = WebGLUtils.setupWebGL( canvas ); if ( !gl ) { alert( "WebGL isn't available" ); } gl.viewport( 0, 0, canvas.width, canvas.height ); gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

  27. var vertices2 = new Array(3); vertices2[0] = point2.create([-1, -1]); vertices2[1] = point2.create([0, 1]); vertices2[2] = point2.create([1, -1]); // Load shaders and initialize attribute buffers var program = initShaders( gl, "vertex-shader", "fragment-shader" ); gl.useProgram( program );

  28. varpointsArray = new Array(NumPoints); pointsArray[0] = vec2.create([0.25,0.50]); for (i = 1; i < NumPoints; i++) { j = Math.floor(Math.random() * 3); pointsArray[i] = point2.create(); point2.add(pointsArray[i-1], vertices2[j], pointsArray[i]); point2.scale(pointsArray[i], 0.5); }

  29. varbufferId = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, bufferId ); gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW ); varvPos = gl.getAttribLocation( program, "vPosition" ); gl.vertexAttribPointer( vPos, 2, gl.FLOAT, false, 0, 0 ); gl.enableVertexAttribArray( vPos ); render(); }

  30. function render() { gl.clear( gl.COLOR_BUFFER_BIT ); gl.drawArrays( gl.POINTS, 0, NumPoints ); // window.requestAnimFrame( render, canvas ); }

  31. example.html <html> <script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 vPosition; void main() { gl_Position = vPosition; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> void main() { gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); } </script>

  32. example.html <script type="text/javascript" src="../Common/webgl-utils.js”></script> <script type="text/javascript" src="../Common/initShaders.js”></script> <script type="text/javascript" src="chap2ex1.js"></script> <script type="text/javascript" src="../Common/glMatrixEA.js”></script> <body> <canvas id="gl-canvas" width="512” height="512” Oops ... your browser doesn't support the HTML5 canvas element </canvas> </body> </html>

  33. Examples in all forms on my website: www.cs.unm.edu/~angel under book support Fifth edition for old examples Sixth edition for shader-based in C++ and WebGL

More Related