javascript - WebGL 着色器程序不工作

标签 javascript debugging webgl shader

我第一次尝试使用 WebGL,但似乎遇到了问题。所有代码看起来都很好,我已经通过 jshint 运行了多次,但我似乎无法让这个程序正常工作。我在 Chrome 操作系统上运行 Chrome 54 稳定版。代码如下。

"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>

最佳答案

它有助于查找 the api you're programming against ,只需跟踪记录到控制台的错误消息(每个浏览器都有不同的方式来调出其开发人员控制台。在 Chrome 上,它是 View->Developer->JavaScript Console 。在 Firefox 上,它是 Tools->Web Developer->Web Console 。对于其他 Safari ,它是 see here 。对于 Edge see here)

getAttributeLocation 不存在,您需要 getAttribLocation

bindBufferData 不存在,您需要 bufferData,它还需要使用提示(此处使用 STATIC_DRAW)作为第三个参数。

"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>

关于javascript - WebGL 着色器程序不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41051063/

相关文章:

javascript - 在一个组件中导入 CSS 就是将 CSS 影响添加到其他组件。如何和为什么?

javascript - WebGL 片段着色器不透明度

java - 如何让 Netbeans 默认为监视变量的十六进制显示?

android - 将 Android 调试器附加到使用我不拥有的 Eclipse 项目构建的进程

javascript - 如何为每个 WebGL 三 Angular 形设置单独的颜色?

glsl - gl_PointCoord 的精确坐标?

javascript - AngularJs 多个同名 Controller 在一个文件中隔离作用域

php - 如何为多个 plupload 制作循环

javascript - Click() 和 then() 不起作用 - Protractor

c++ - 调用 'localtime_s' 时日历功能崩溃