Introduction to Opengl/GLSL and Webgl
Total Page:16
File Type:pdf, Size:1020Kb
Introduction to OpenGL/GLSL and WebGL GLSL Objectives n Give you an overview of the software that you will be using this semester n OpenGL, WebGL, and GLSL n What are they? n How do you use them? n What does the code look like? n Evolution n All of them are required to write modern graphics code, although alternatives exist What is OpenGL? n An application programming interface (API) n A (low-level) Graphics rendering API n Generate high-quality images from geometric and image primitives Maximal Portability n Display device independent n Window system independent n Operating system independent Without a standard API (such as OpenGL) - impossible to port (100, 50) Line(100,50,150,80) - device/lib 1 (150, 100) Moveto(100,50) - device/lib 2 Lineto(150,100) Brief History of OpenGL n Originated from a proprietary API called Iris GL from Silicon Graphics, Inc. n Provide access to graphics hardware capabilities at the lowest possible level that still provides hardware independence n The evolution is controlled by OpenGL Architecture Review Board, or ARB. n OpenGL 1.0 API finalized in 1992, first implementation in 1993 n In 2006, OpenGL ARB became a worKgroup of the Khronos Group n 10+ revisions since 1992 OpenGL Evolution n 1.1 (1997): vertex arrays and texture objects n 1.2 (1998): 3D textures n 1.3 (2001): cubemap textures, compressed textures, multitextures n 1.4 (2002): mipmap Generation, shadow map textures, etc n 1.5 (2003): vertex buffer object, shadow comparison functions, occlusion queries, non- power-of-2 textures OpenGL Evolution n 2.0 (2004): vertex and fragment shading (GLSL 1.1), multiple render targets, etc n 2.1 (2006): GLSL 1.2, pixel buffer objects, etc n 3.0 (2008): GLSL 1.3, deprecation model, etc n 3.1 (2009): GLSL 1.4, texture buffer objects, move much of deprecated functions to ARB compatible extension n 3.2 (2009) n 4.X (2012 and on) OpenGL Basics n OpenGL’s primary function – Rendering n Rendering? – converting geometric/mathematical object descriptions into frame buffer values n OpenGL can render: n Geometric primitives n Bitmaps and Images (Raster primitives) OpenGL Example Cube with flat color Cube with lighting Cube with textures WebGL n JavaScript implementation of OpenGL n Run in all modern browsers (Chrome, Safari, Firefox, IE, etc). n Application can be located on a remote server n Rendering is done within browser using local hardware n Uses HTML5 canvas n Integrated with standard Web packages and apps (CSS, jQuery, etc.) What do you need to know n Web Environment and Execution n Modern OpenGL basics n Pipeline architecture n Shaders (vertex and fragment) based OpenGL n OpenGL Shading Language (GLSL) n Javascript OpenGL ES and WebGL n OpenGL ES n A subset of OpenGL 3.1 API (lightweight) n Designed for embedded system (mobile phones etc.) n Shader based n WebGL n Javascript implementation of ES 2.0 n Runs on browswers WebGL Rendering Pipeline WebGL Programming n General Structure: n Set up canvas to render to n Generate data/geometry in application n Create shader programs n Create buffer objects and load data to them n Connect buffer objects and data to shader variables n Set up proper viewing and lighting conditions n Render WebGL Programming n WebGL needs a place to render into n HTML5 canvas element n All the code can be put in a single HTML file n Or you can put setup code in an HTML file and your application code in separate Javascript files n HTML file includes shaders n HTML file reads in application and utilities Example 0 n A very simple example that creates a canvas but display nothing except a yellow background <!DOCTYPE html> <html> <head> <title>hwshen WebGL — code00 </title> WebGL <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> Javascript <script type="text/javascript" src="code00.js"></script> </head> <body onload="webGLStart();”> canvas <canvas id="code00-canvas" style="border: none;" width="700" height="500"></canvas> <br/> </body> </html> code00.js var gl; function webGLStart() { function initGL(canvas) { var canvas = document.getElementById("code00- try { canvas"); gl = canvas.getContext("experimental-webgl"); initGL(canvas); gl.viewportWidth = canvas.width; gl.clearColor(1.0, 1.0, 0.0, 1.0); // yellow gl.viewportHeight = canvas.height; drawScene(); } catch (e) { } } if (!gl) { alert("Could not initialise WebGL, sorry :-("); } viewport } function drawScene() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); } Simple OpenGL commands n HTML will call webGLStart(); n canvas is an HTML5 element for drawing n You need a OpenGL context from the canvas for storing internal states n canvas.getContext(); n All OpenGL commands in WebGL start with ‘gl.’ n gl.viewport(); specify the display area n gl.clearColor(); specify the background color n gl.clear(); clear the foreground and background Output Example 1 n Now let’s draw something (two triangles) on the canvas n You will need to provide vertex and fragment shaders n Github: https://github.com/imindseye/WebGL- tutorial simple-triangles.html <!DOCTYPE html> <html> <head> <title>hwshen WebGL — code01 </title> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> <!-- ************** Fragment Shader ************* --> Fragment <script id="shader-fs" type="x-shader/x-fragment"> Shader void main(void) { gl_FragColor = vec4(1.0, 0, 0, 1.0); } </script> Vertex <!-- ************** Vertex Shader ************* --> Shader <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; void main(void) { gl_Position = vec4(aVertexPosition, 1.0); } </script> simple-triangles.html (cont’d) <script type="text/javascript" src="shaders_setup.js"></script> <script type="text/javascript" src="code01.js"></script> </head> <body onload="webGLStart();”> <canvas id="code00-canvas" style="border: none;" width="700" height="500"></canvas> <br/> </body> </html> simple-triangles.js var gl; function initGL(canvas) { function webGLStart() { // same as before …. var canvas = document.getElementById("code00- canvas"); … initGL(canvas); } initShaders(); function initShaderers() { initBuffers(); // setup shaders gl.clearColor(1.0, 1.0, 0.0, 1.0); // yellow // load the source, compile and link the code drawScene(); // in shaders_setup.js } } function initBuffers() { // set up vertex buffer objects for geometry // I will explain next … function drawScene() } gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); } Output simple-triangles.js n In order to fully understand open-canvas.js, we need to explain n Vertex Buffer Objects – this is how you define your geometry n Shader setup and simple GLSL concepts n How to draw the scene n Below I will start with Shaders setup and then Vertex Buffer Objects (VBO) OpenGL Shading Language (GLSL) n A C-like language and incorporated into OpenGL 2.0 and on n Used to write vertex program and fragment program n No distinction in the syntax between a vertex program and a fragment program n Platform independent Setup of Shader Prgorams n A shader is defined as an array of strings n Steps to set up shaders 1. Create a shader program 2. Create shader objects (vertex and fragment) 3. Send source code to the shader objects 4. Compile the shader 1. Create program object by linking compiled shaders together 2. Use the linked program object shaders_setup.js function initShaders() { shaderProgram = gl.createProgram(); // create a shader program var fragmentShader = getShader(gl, "shader-fs"); // create and compile a vertex shader object var vertexShader = getShader(gl, "shader-vs"); // create and compile a fragment shader object gl.attachShader(shaderProgram, vertexShader); // attach the vertex shader to the shader program gl.attachShader(shaderProgram, fragmentShader); // attach the fragment shader gl.linkProgram(shaderProgram); // link the vertex and fragment shaders if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Could not initialise shaders"); } gl.useProgram(shaderProgram); // use the shader program } shaders_setup.js function getShader(gl, id) { var shaderScript = document.getElementById(id); if (!shaderScript) { return null; } var str = ""; var shader; var k = shaderScript.firstChild; while (k) { if (shaderScript.type == "x-shader/x-fragment") { if (k.nodeType == 3) { shader = gl.createShader(gl.FRAGMENT_SHADER); str += k.textContent; } else if (shaderScript.type == "x-shader/x-vertex") { } shader = gl.createShader(gl.VERTEX_SHADER); k = k.nextSibling; } else { } return null; } gl.shaderSource(shader, str); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } Vertex Buffer Objects n Provide per-vertex input to the GPU n Vertex: a point where the edges of geometry meet n All geometric primitives are composed of vertices, their attributes, and the connectivity n Allow significant increases in vertex throughput between CPU and GPU n The mechanism to provide generic attributes to the shader, and store vertex data in video memory n User’s program is free to define an arbitrary set of per- vertex attributes to the vertex shader Create a VBO n Step 1: generate a new buffer object with gl.createBuffer()