我正在尝试开始学习WebGL;我的概念证明没有颜色,但是一旦我尝试通过添加
添加颜色colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
), gl.STATIC_DRAW);
ColorAttribute = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(ColorAttribute);
gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
其中
gl
是WebGLRenderingContext,program
是成功编译的程序,附带顶点和片段着色器colorBuffer
,ColorAttribute
是空变量在主代码中,并更改
gl_FragColor = vec4(0.2, 0.4, 0.6, 1);
到
gl_FragColor = vcolor;
片段着色器源中的(注释着色器主体不会使错误消失);我收到以下错误:
[.Offscreen-For-WebGL-0000000005BB7940] GL错误:GL_INVALID_OPERATION:glDrawArrays:尝试访问属性1中超出范围的顶点
这很奇怪,因为我的颜色缓冲区中有3种颜色,一个用于三角形的每个顶点:
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
), gl.STATIC_DRAW);
我的顶点缓冲区中有3个顶点:
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0, 0,
0, 1, 0,
1, 1, 0
]), gl.STATIC_DRAW);
我确保在调用vertexAttribPointer
时我将颜色缓冲区的项目大小设置为4,顶点缓冲区的项目大小设置为3,所以我不确定什么可能超出范围。
下面是一个有效的代码,其中颜色更改被注释掉,然后是一个无法处理颜色变化的代码。两个示例都通过粘贴到浏览器开发者控制台的任何窗口上工作,但屏幕截图是在“关于:空白”。
两个代码段都是自包含的,但仅在Chrome中进行过测试。
这是工作版本:
(function() {
"use strict";
var hWnd;
var src_vertexShader;
var src_fragmentShader;
var canvas;
var gl;
var program;
var vertexShader;
var fragmentShader;
var vertexBuffer;
var colorBuffer;
var PositionAttribute;
var ColorAttribute;
// | canvas container.
hWnd = document.createElement("div");
hWnd.style.position = "fixed";
hWnd.style.top = "0px";
hWnd.style.left = "0px";
hWnd.style.border = "1px solid #000000";
hWnd.addEventListener("click", function() {
this.outerHTML = '';
});
// | vertex shader source.
src_vertexShader = `
attribute vec3 position;
attribute vec4 color;
varying vec4 vcolor;
void main() {
gl_Position = vec4(position, 1.0);
vcolor = color;
}`;
// | fragment shader source.
src_fragmentShader = `
varying lowp vec4 vcolor;
void main() {
gl_FragColor = vec4(0.2, 0.4, 0.6, 1);
//gl_FragColor = vcolor;
}`;
// | our WebGL canvas.
canvas = document.createElement('canvas');
canvas.width = 320;
canvas.height = 200;
// | our WebGLRenderingContext.
gl = canvas.getContext('webgl', {antialias: false});
// | setting up our program using a Vertex and a Fragment shader.
program = gl.createProgram();
vertexShader = gl.createShader(gl.VERTEX_SHADER);
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, src_vertexShader);
gl.shaderSource(fragmentShader, src_fragmentShader);
gl.compileShader(vertexShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));
gl.compileShader(fragmentShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
// | create and attach a vertex buffer with data for one triangle.
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0, 0,
0, 1, 0,
1, 1, 0
]), gl.STATIC_DRAW);
PositionAttribute = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(PositionAttribute);
gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
/*
// | create and attach a color buffer with color data for our triangle.
colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
), gl.STATIC_DRAW);
ColorAttribute = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(ColorAttribute);
gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
*/
// | clear the screen.
gl.clearColor(0.93, 0.93, 0.93, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// | draw the triangle.
gl.drawArrays(gl.TRIANGLES, 0, 3);
hWnd.appendChild(canvas)
document.body.appendChild(hWnd);
})();
这是抱怨的版本:
(function() {
"use strict";
var hWnd;
var src_vertexShader;
var src_fragmentShader;
var canvas;
var gl;
var program;
var vertexShader;
var fragmentShader;
var vertexBuffer;
var colorBuffer;
var PositionAttribute;
var ColorAttribute;
// | canvas container.
hWnd = document.createElement("div");
hWnd.style.position = "fixed";
hWnd.style.top = "0px";
hWnd.style.left = "0px";
hWnd.style.border = "1px solid #000000";
hWnd.addEventListener("click", function() {
this.outerHTML = '';
});
// | vertex shader source.
src_vertexShader = `
attribute vec3 position;
attribute vec4 color;
varying vec4 vcolor;
void main() {
gl_Position = vec4(position, 1.0);
vcolor = color;
}`;
// | fragment shader source.
src_fragmentShader = `
varying lowp vec4 vcolor;
void main() {
gl_FragColor = vcolor;
}`;
// | our WebGL canvas.
canvas = document.createElement('canvas');
canvas.width = 320;
canvas.height = 200;
// | our WebGLRenderingContext.
gl = canvas.getContext('webgl', {antialias: false});
// | setting up our program using a Vertex and a Fragment shader.
program = gl.createProgram();
vertexShader = gl.createShader(gl.VERTEX_SHADER);
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, src_vertexShader);
gl.shaderSource(fragmentShader, src_fragmentShader);
gl.compileShader(vertexShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));
gl.compileShader(fragmentShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
// | create and attach a vertex buffer with data for one triangle.
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0, 0,
0, 1, 0,
1, 1, 0
]), gl.STATIC_DRAW);
PositionAttribute = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(PositionAttribute);
gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
// | create and attach a color buffer with color data for our triangle.
colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
), gl.STATIC_DRAW);
ColorAttribute = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(ColorAttribute);
gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
// | clear the screen.
gl.clearColor(0.93, 0.93, 0.93, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// | draw the triangle.
gl.drawArrays(gl.TRIANGLES, 0, 3);
hWnd.appendChild(canvas)
document.body.appendChild(hWnd);
})();
提前致谢。
答案 0 :(得分:1)
问题是在定义颜色时代码缺少方括号
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
), gl.STATIC_DRAW);
vs this
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array([
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
]), gl.STATIC_DRAW);
(function() {
"use strict";
var hWnd;
var src_vertexShader;
var src_fragmentShader;
var canvas;
var gl;
var program;
var vertexShader;
var fragmentShader;
var vertexBuffer;
var colorBuffer;
var PositionAttribute;
var ColorAttribute;
// | canvas container.
hWnd = document.createElement("div");
hWnd.style.position = "fixed";
hWnd.style.top = "0px";
hWnd.style.left = "0px";
hWnd.style.border = "1px solid #000000";
hWnd.addEventListener("click", function() {
this.outerHTML = '';
});
// | vertex shader source.
src_vertexShader = `
attribute vec3 position;
attribute vec4 color;
varying vec4 vcolor;
void main() {
gl_Position = vec4(position, 1.0);
vcolor = color;
}`;
// | fragment shader source.
src_fragmentShader = `
varying lowp vec4 vcolor;
void main() {
gl_FragColor = vcolor;
}`;
// | our WebGL canvas.
canvas = document.createElement('canvas');
canvas.width = 320;
canvas.height = 200;
// | our WebGLRenderingContext.
gl = canvas.getContext('webgl', {antialias: false});
// | setting up our program using a Vertex and a Fragment shader.
program = gl.createProgram();
vertexShader = gl.createShader(gl.VERTEX_SHADER);
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, src_vertexShader);
gl.shaderSource(fragmentShader, src_fragmentShader);
gl.compileShader(vertexShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(vertexShader));
gl.compileShader(fragmentShader);
console.log('Shader compiled successfully: ' + gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
console.log('Shader compiler log: ' + gl.getShaderInfoLog(fragmentShader));
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
console.log(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS));
// | create and attach a vertex buffer with data for one triangle.
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0, 0,
0, 1, 0,
1, 1, 0
]), gl.STATIC_DRAW);
PositionAttribute = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(PositionAttribute);
gl.vertexAttribPointer(PositionAttribute, 3, gl.FLOAT, false, 0, 0);
// | create and attach a color buffer with color data for our triangle.
colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array([
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
]), gl.STATIC_DRAW);
ColorAttribute = gl.getAttribLocation(program, 'color');
gl.enableVertexAttribArray(ColorAttribute);
gl.vertexAttribPointer(ColorAttribute, 4, gl.FLOAT, false, 0, 0);
// | clear the screen.
gl.clearColor(0.93, 0.93, 0.93, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// | draw the triangle.
gl.drawArrays(gl.TRIANGLES, 0, 3);
hWnd.appendChild(canvas)
document.body.appendChild(hWnd);
})();