hellol11
hellol11

Reputation: 428

WebGL shader program not working

I was trying to use WebGL for the first time, but I seem to have hit a problem. All the code seems fine, and I have run it through jshint multiple times, but I can't seem to get this program working right. I am running Chrome 54 stable on Chrome OS. Code is below.

"use strict";

//initWebGL function
function initWebGL(canvas){
  //get a webGL context
  var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

  //if we have a context, we're good to go. if not, alert, and return the nothing that is our empty context
  if(!gl){
    alert("Your browser does not support WebGL");
  }
  return gl;
}

//shader creation function
function createShader(gl, type, source){
  //create and compile the shader
  var shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  //if success, then return the shader. if not, log the shader info, and then delete the shader.
  if(gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
    return shader;
  }
  alert(gl.getShaderInfoLog(shader) + "");
  gl.deleteShader(shader);
}

//program creation function
function createProgram(gl, vertexShader, fragmentShader){
  //create the program and attach the shaders
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);

  //if success, return the program. if not, log the program info, and delete it.
  if(gl.getProgramParameter(program, gl.LINK_STATUS)){
    return program;
  }
  alert(gl.getProgramInfoLog(program) + "");
  gl.deleteProgram(program);
}

//main function
function start(){
  //get the canvas
  var canvas = document.getElementById("webgl_canvas");

  //initialize WebGL
  var gl = initWebGL(canvas);

  //keep going if we have a context
  if(!gl){
    return;
  }

  //set the clear color
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  //set up depth testing
  gl.enable(gl.DEPTH_TEST);
  gl.depthFunc(gl.LEQUAL);

  //clear the color and the depth buffer
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.clear(gl.DEPTH_BUFFER_BIT);

  //set up the viewport
  gl.viewport(0, 0, canvas.width, canvas.height);

  //set up shaders
  var vertexShaderSource = "attribute vec2 a_position; void main(){gl_Position = vec4(a_position, 0, 1);}";
  var fragmentShaderSource = "precision mediump float; void main(){gl_FragColor = vec4(1, 1, 1, 1);}";
  var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
  var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

  //set up the program
  var program = createProgram(gl, vertexShader, fragmentShader);

  //get the attribute location
  var positionAttributeLocation = gl.getAttributeLocation(program, "a_position");

  //set up a position buffer
  var positionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bindBufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 0.5, 0.7, 0]));

  //tell webGL to use the program
  gl.useProgram(program);

  //enable the vertex attribute array
  gl.enableVertexAttribArray(positionAttributeLocation);

  //tell webgl how to pull out the data
  gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

  //render
  gl.drawArrays(gl.TRIANGLES, 0, 3);
}
canvas{outline:1px solid red;}
<html>
	<head>
		<title>WebGL demo</title>
	</head>
	<body onload="start();">
		<canvas id="webgl_canvas" width="640" height="480"></canvas>
	</body>
</html>

Upvotes: 1

Views: 2122

Answers (1)

LJᛃ
LJᛃ

Reputation: 8153

It helps looking up the api you're programming against, just following the error messages logged to the console (every browser has a different way to bring up the it's developer console. On Chrome it's View->Developer->JavaScript Console. On Firefox it's Tools->Web Developer->Web Console. For other Safari see here. For Edge see here)

getAttributeLocation does not exist, you want getAttribLocation.

bindBufferData does not exist, you want bufferData which also requires the usage hint(used STATIC_DRAW here) as third argument.

"use strict";

//initWebGL function
function initWebGL(canvas){
  //get a webGL context
  var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

  //if we have a context, we're good to go. if not, alert, and return the nothing that is our empty context
  if(!gl){
    alert("Your browser does not support WebGL");
  }
  return gl;
}

//shader creation function
function createShader(gl, type, source){
  //create and compile the shader
  var shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  //if success, then return the shader. if not, log the shader info, and then delete the shader.
  if(gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
    return shader;
  }
  alert(gl.getShaderInfoLog(shader) + "");
  gl.deleteShader(shader);
}

//program creation function
function createProgram(gl, vertexShader, fragmentShader){
  //create the program and attach the shaders
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);

  //if success, return the program. if not, log the program info, and delete it.
  if(gl.getProgramParameter(program, gl.LINK_STATUS)){
    return program;
  }
  alert(gl.getProgramInfoLog(program) + "");
  gl.deleteProgram(program);
}

//main function
function start(){
  //get the canvas
  var canvas = document.getElementById("webgl_canvas");

  //initialize WebGL
  var gl = initWebGL(canvas);

  //keep going if we have a context
  if(!gl){
    return;
  }

  //set the clear color
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  //set up depth testing
  gl.enable(gl.DEPTH_TEST);
  gl.depthFunc(gl.LEQUAL);

  //clear the color and the depth buffer
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.clear(gl.DEPTH_BUFFER_BIT);

  //set up the viewport
  gl.viewport(0, 0, canvas.width, canvas.height);

  //set up shaders
  var vertexShaderSource = "attribute vec2 a_position; void main(){gl_Position = vec4(a_position, 0, 1);}";
  var fragmentShaderSource = "precision mediump float; void main(){gl_FragColor = vec4(1, 1, 1, 1);}";
  var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
  var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

  //set up the program
  var program = createProgram(gl, vertexShader, fragmentShader);

  //get the attribute location
  var positionAttributeLocation = gl.getAttribLocation(program, "a_position");

  //set up a position buffer
  var positionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 0.5, 0.7, 0]), gl.STATIC_DRAW);

  //tell webGL to use the program
  gl.useProgram(program);

  //enable the vertex attribute array
  gl.enableVertexAttribArray(positionAttributeLocation);

  //tell webgl how to pull out the data
  gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

  //render
  gl.drawArrays(gl.TRIANGLES, 0, 3);
}
canvas{outline:1px solid red;}
<html>
	<head>
		<title>WebGL demo</title>
	</head>
	<body onload="start();">
		<canvas id="webgl_canvas" width="640" height="480"></canvas>
	</body>
</html>

Upvotes: 3

Related Questions