I am following a book called professional WebGL, I am hand writing stuff making sure of my understanding, I have this code:
<!DOCTYPE HTML> <html lang="en"> <head> <title>2-1 A first WebGL example</title> <meta charset="utf-8"> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; void main() { gl_Position = vec4(aVertexPosition, 1.0); } </script> <script id="shader-fs" type="x-shader/x-fragment"> precision mediump float; void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } </script> <script type="text/javascript"> var gl; var canvas; var shaderProgram; var vertexBuffer; /*Function to create the webgl context*/ function createGLContext(canvas) { var names = ["webgl", "experimental-webgl"]; var context = null; for(var i = 0; i < names.length; i++) { try { context = canvas.getContext(names[i]); } catch(e) { if(context) { break; } } } if(context) { context.viewportWidth = canvas.width; context.viewportHeight = canvas.height; } else { alert("Failed to create webgl context"); } return context; } function loadShaderFromDOM(id) { var shaderScript = document.getElementById(id); //if we don't find an element with the specified id //we do an early exit if(!shaderScript) { return null; } //loop through the children for the found DOM element and //build up the shader source code as a string. var shaderSource = ""; var currentChild = shaderScript.firstChild; while(currentChild) { if(currentChild.nodeType == 3) { //3 corresponds to TEXT_NODE shaderSource += currentChild.textContent; } currentChild = currentChild.nextSibling; } var shader; if(shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if(shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } gl.shaderSource(shader, shaderSource); gl.compileShader(shader); if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } /*Function to setup the shaders*/ function setupShaders() { var vertexShader = loadShaderFromDOM("shader-vs"); var fragmentShader = loadShaderFromDOM("shader-fs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Failed toe setup shaders"); } gl.useProgram(shaderProgram); shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); } /*Function to setup the buffers*/ function setupBuffers() { vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); var triangleVertices = [ 0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); vertexBuffer.itemSize = 3; vertexBuffer.numberOfItems = 3; } /*Function to draw the triangle*/ function draw() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.celar(gl.COLOR_BUFFER_BIT); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems); } /*Function to kick everything off*/ function startup() { canvas = document.getElementById("myGLCanvas"); gl = createGLContext(canvas); setupShaders(); setupBuffers(); gl.clearColor(0.0, 0.0, 0.0, 0.1); draw(); } </script> </head> <body onload="startup()"> <canvas id="myGLCnvas" width="500" height="300"></canvas> </body> </html>
for some reason, it says that it can’t read property null for createShader
here:
shader = gl.createShader(gl.VERTEX_SHADER);
But it doesn’t complain at all for the same declaration but with the fragment shader.
Advertisement
Answer
Slightly changed version.
gl.celar
was wrong and main loop for getting context.
<!DOCTYPE HTML> <html lang="en"> <head> <title>2-1 A first WebGL example</title> <meta charset="utf-8"> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; void main() { gl_Position = vec4(aVertexPosition, 1.0); } </script> <script id="shader-fs" type="x-shader/x-fragment"> precision mediump float; void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } </script> <script type="text/javascript"> var gl; var canvas; var shaderProgram; var vertexBuffer; /*Function to create the webgl context*/ function createGLContext(canvas) { var names = ["webgl", "experimental-webgl"]; gl = null; for(var i = 0; i < names.length; i++) { gl = canvas.getContext(names[i]); if(gl) break; } if(gl) { gl.viewportWidth = canvas.width; gl.viewportHeight = canvas.height; } else { console.log("Failed to create webgl context"); } } function loadShaderFromDOM(id) { var shaderScript = document.getElementById(id); //if we don't find an element with the specified id //we do an early exit if(!shaderScript) { return null; } //loop through the children for the found DOM element and //build up the shader source code as a string. var shaderSource = ""; var currentChild = shaderScript.firstChild; while(currentChild) { if(currentChild.nodeType == 3) { //3 corresponds to TEXT_NODE shaderSource += currentChild.textContent; } currentChild = currentChild.nextSibling; } var shader; if(shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if(shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } gl.shaderSource(shader, shaderSource); gl.compileShader(shader); if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } /*Function to setup the shaders*/ function setupShaders() { var vertexShader = loadShaderFromDOM("shader-vs"); var fragmentShader = loadShaderFromDOM("shader-fs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Failed toe setup shaders"); } gl.useProgram(shaderProgram); shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); } /*Function to setup the buffers*/ function setupBuffers() { vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); var triangleVertices = [ 0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); vertexBuffer.itemSize = 3; vertexBuffer.numberOfItems = 3; } /*Function to draw the triangle*/ function draw() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems); } /*Function to kick everything off*/ function startup() { canvas = document.getElementById("myGLCnvas"); createGLContext(canvas); setupShaders(); setupBuffers(); gl.clearColor(0.0, 0.0, 0.0, 0.1); draw(); } </script> </head> <body onload="startup()"> <canvas id="myGLCnvas" width="500" height="300"></canvas> </body> </html>