全部。我是webgl的新手,但我检查了有关此错误的资源。我试图在我的圆旁边绘制一个正方形。在此之后,我为square和以此为基础来组织drawArrays。但是我收到此错误:
GL错误:GL_INVALID_OPERATION:glDrawArrays:尝试访问属性0中超出范围的顶点
也检查了我的界限和索引,但是这里的代码没有问题:
var vPosition,angle=10,j=1,xr=0.2,yr=0.2,rad;
var transformationMatrix, transformationMatrixLoc;
window.onload = function init()
{
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
// Load shaders and initialize attribute buffers
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vertices = [
vec2(0,0)
];
for(var i =0 ; i<=360 ; i+=10)
{
vertices.push(vec2(xr*Math.cos(i*(Math.PI/180)),yr*Math.sin(i*
(Math.PI/180))));
}
vertices.push(vec2(0.20,0));
vertices.push(vec2(0.25,-0.05));
vertices.push(vec2(0.3,0));
vertices.push(vec2(0.25,0.05));
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
// Associate out shader variables with our data buffer
vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
transformationMatrixLoc =
gl.getUniformLocation(program,"transformationMatrix" );
render();
}
render(){
gl.clear( gl.COLOR_BUFFER_BIT );
var MStack = [] ;
var transformationMatrix = mat4();
MStack.push(transformationMatrix);
gl.uniformMatrix4fv( transformationMatrixLoc, false,
flatten(transformationMatrix) );
gl.uniform4fv(colorLoc, vec4(red, green, blue, 1.0));
gl.drawArrays( gl.TRIANGLE_FAN, 0, vertices.length-4 );
transformationMatrix = MStack.pop();
MStack.push(transformationMatrix);
gl.uniformMatrix4fv( transformationMatrixLoc, false,
flatten(transformationMatrix) );
gl.drawArrays(gl.TRIANGLE_FAN,vertices.length-4,vertices.length);
gl.uniform4fv(colorLoc, vec4(red, green, blue, 1.0));
window.requestAnimFrame(render);
}
希望你们能帮助我。真的谢谢。
答案 0 :(得分:1)
传递到 .bufferData()
的数据数组必须是ArrayBuffer
。
使用Float32Array
创建一个由32位浮点数组成的数组。这对应于通用顶点属性数据数组的规范中的gl.FLOAT
类型:
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(flatten(vertices)), gl.STATIC_DRAW );
注意,缓冲区对象数据存储区的大小由数组缓冲区的大小确定。
.drawArrays()
的最后一个参数是要渲染的顶点数,而不是最后一个属性的索引:
gl.drawArrays(gl.TRIANGLE_FAN, vertices.length-4, 4);
答案 1 :(得分:0)
这是一个有效的代码段。下次,请发布一个片段来重现您的问题
我需要在您发布的代码中解决的问题
该代码未包含着色器
我猜想一些看起来与代码匹配的着色器
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
uniform mat4 transformationMatrix;
void main()
{
gl_Position = transformationMatrix*vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision highp float;
uniform vec4 color;
void
main()
{
gl_FragColor = color;
}
</script>
代码未定义画布
我添加了一个ID与代码匹配的
<canvas id="gl-canvas" width="200" height="200"></canvas>
该代码未链接到您正在使用的脚本。 JavaScript中使用的vec2
和flatten
之类的内容不属于WebGL。它们是某些库的一部分。没有这些,我们不知道您的代码做什么
我猜是这些:https://github.com/esangel/WebGL,所以我添加了它们
<script src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script src="https://esangel.github.io/WebGL/Common/MV.js"></script>
该代码未定义colorLoc
的统一位置,也没有为其查询color
。
该代码未定义red
,green
和blue
。
假设所有这些都存在于您的实际代码中,那么我猜问题出在这行上
gl.drawArrays(gl.TRIANGLE_FAN,vertices.length-4,vertices.length);
应该是
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.length);
drawArrays
的参数是
gl.drawArrays(primitiveType, offset, count);
其中primitiveType
是要绘制的图元类型。 offset
是要配置的属性中要跳过的顶点数,count
是要处理的顶点数。
var vPosition, angle = 10,
j = 1,
xr = 0.2,
yr = 0.2,
colorLoc,
rad;
var transformationMatrix, transformationMatrixLoc;
function init() {
canvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
if (!gl) {
alert("WebGL isn't available");
}
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Load shaders and initialize attribute buffers
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
vertices = [
vec2(0, 0)
];
for (var i = 0; i <= 360; i += 10) {
vertices.push(vec2(xr * Math.cos(i * (Math.PI / 180)), yr * Math.sin(i *
(Math.PI / 180))));
}
vertices.push(vec2(0.20, 0));
vertices.push(vec2(0.25, -0.05));
vertices.push(vec2(0.3, 0));
vertices.push(vec2(0.25, 0.05));
vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
// Associate out shader variables with our data buffer
vPosition = gl.getAttribLocation(program, "vPosition");
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);
transformationMatrixLoc =
gl.getUniformLocation(program, "transformationMatrix");
colorLoc = gl.getUniformLocation(program, "color");
render();
}
function render() {
gl.clear(gl.COLOR_BUFFER_BIT);
var MStack = [];
const red = 1;
const green = 0.5;
const blue = 0.25;
var transformationMatrix = mat4();
MStack.push(transformationMatrix);
gl.uniformMatrix4fv(transformationMatrixLoc, false,
flatten(transformationMatrix));
gl.uniform4fv(colorLoc, vec4(red, green, blue, 1.0));
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.length - 4);
transformationMatrix = MStack.pop();
MStack.push(transformationMatrix);
gl.uniformMatrix4fv(transformationMatrixLoc, false,
flatten(transformationMatrix));
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.length);
gl.uniform4fv(colorLoc, vec4(red, green, blue, 1.0));
window.requestAnimFrame(render);
}
init();
canvas { border: 1px solid black; }
<script src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<canvas id="gl-canvas" width="200" height="200"></canvas>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
uniform mat4 transformationMatrix;
void main()
{
gl_Position = transformationMatrix*vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision highp float;
uniform vec4 color;
void
main()
{
gl_FragColor = color;
}
</script>
代码做了另一件事,它使用了过时的方式开始使用
window.onload = function init() { ...
一种更现代的方法是将脚本放在页面底部而不是页面顶部,然后直接调用init
。否则请使用window.addEventListener('load', function init() { ...
,因为那样会使页面上的多个脚本初始化。
您可能会发现these articles有用。