微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebGL INVALID OPERATION 缓冲区大小不足

如何解决WebGL INVALID OPERATION 缓冲区大小不足

我正在尝试用 WebGL 和 javascript 编写一个简单的程序,以从 .obj 文件中绘制一个简单的对象。我正在使用 npm 的 webgl-obj-loader 来加载对象。正如标题所说,我不断收到缓冲区大小不足(边缘)和索引缓冲区太小(FF)的问题。我使用了 gl.geterror 函数,得到了 1282 错误代码,这意味着 INVALID_OPERATION。

window.onload = function () {
            OBJ.downloadMeshes(
            {
                'dragon_vrip': 'models/dragon_vrip.obj','cube2': 'models/cube2.obj'
            },webGLStart);
}

这是我用来加载 obj 文件的方式。

        app.meshes = meshes;

        OBJ.initMeshBuffers(gl,app.meshes.dragon_vrip);
        OBJ.initMeshBuffers(gl,app.meshes.cube2);

        vertArray = app.meshes.cube2.vertices.slice();
        normArray = app.meshes.cube2.vertexnormals.slice();
        indicesArray = app.meshes.cube2.indices.slice();
        texCoord = app.meshes.cube2.textures.slice();
            var myMesh=app.meshes.cube2;

            var pointsBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER,pointsBuffer);
            gl.bufferData(gl.ARRAY_BUFFER,vertArray,gl.STATIC_DRAW);
            gl.vertexAttribPointer(0,3,gl.FLOAT,false,0);
            gl.enabLevertexAttribArray(0);

            var textureBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER,textureBuffer);
            gl.bufferData(gl.ARRAY_BUFFER,texCoord,gl.STATIC_DRAW);
            gl.vertexAttribPointer(1,2,0);
            gl.enabLevertexAttribArray(1);

            var normalBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER,normalBuffer);
            gl.bufferData(gl.ARRAY_BUFFER,normArray,gl.STATIC_DRAW);
            gl.vertexAttribPointer(2,0);
            gl.enabLevertexAttribArray(2);

            var indices = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indices);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indicesArray,gl.STATIC_DRAW);
            console.log(indices.size);

第二步:初始化缓冲区。

                function drawFunc() {
                    rotateAngleX += 0.01;
                    rotateAngleY += 0.02;

                    mat4.fromXRotation(rotateXMatrix,rotateAngleX);
                    mat4.fromYRotation(rotateYMatrix,rotateAngleY);
                    mat4.multiply(modelMatrix,rotateXMatrix,rotateYMatrix);

                    gl.uniformMatrix4fv(modelMatrixLocation,modelMatrix);

                    gl.clear(gl.COLOR_BUFFER_BIT);
                    gl.drawElements(gl.TRIANGLES,indicesArray.length,gl.UNSIGNED_SHORT,0);

                    requestAnimationFrame(drawFunc);

                }
                requestAnimationFrame(drawFunc);

这里我想画一个简单的立方体。

数组大小为:顶点:72 索引:36 texCoords:48 法线:72

考虑到顶点是 x,y,z 点的三元组,顶点缓冲区包含 24 个点(顶点 [0]=x,顶点 [1]=y,顶点 [2]=z,...)和索引数组不包含大于 23 的数字,所以我不明白错误发生在哪里。还有什么方法可以调试缓冲区?我尝试了spector.js,但没有太大帮助,因为绘制调用由于错误而什么也不做。

解决方法

好吧,出于某种原因,我不得不在 bufferdata 函数中添加新类型的数组,就像这样。

var indices = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indices);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint32Array(indicesArray),gl.STATIC_DRAW);

其余缓冲区也是如此。

,

在此处查看完整示例

https://jsfiddle.net/greggman/8djzyjL3/

   <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-helper.js"></script>
<script src="https://webglfundamentals.org/webgl/lessons/resources/3d-math.js"></script>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position;
uniform mat4 u_worldViewProjection;

void main() {
   gl_Position = u_worldViewProjection * a_position;
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
void main() {
   gl_FragColor = vec4(0,1);
}
</script>
<canvas id="c"></canvas>

JS:

"use strict";

var m = ThreeDMath;

function main() {
  var cubeVertices = [
    -1,-1,1,];
  var indices = [
    0,2,3,4,5,6,7,];

  var canvas = document.getElementById("c");
  var gl = canvas.getContext("webgl");
  if (!gl) {
    alert("no webgl");
    return;
  }

  var program = webglUtils.createProgramFromScripts(
      gl,["2d-vertex-shader","2d-fragment-shader"]);
  gl.useProgram(program);

  var positionLoc = gl.getAttribLocation(program,"a_position");
  var worldViewProjectionLoc =
      gl.getUniformLocation(program,"u_worldViewProjection");

  var buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
  gl.bufferData(
      gl.ARRAY_BUFFER,new Float32Array(cubeVertices),gl.STATIC_DRAW);
  gl.enableVertexAttribArray(positionLoc);
  gl.vertexAttribPointer(positionLoc,gl.FLOAT,false,0);

  var buffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,buffer);
  gl.bufferData(
      gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indices),gl.STATIC_DRAW);

  function render(clock) {
    clock *= 0.001;

    var scale = 4;

    webglUtils.resizeCanvasToDisplaySize(gl.canvas,window.devicePixelRatio);

    gl.viewport(0,gl.canvas.width,gl.canvas.height);

    gl.clear(gl.COLOR_BUFFER_BIT);

    var fieldOfView = Math.PI * 0.25;
    var aspect = canvas.clientWidth / canvas.clientHeight;
    var projection = m.perspective(fieldOfView,aspect,0.0001,500);
    var radius = 5;
    var eye = [
        Math.sin(clock) * radius,Math.cos(clock) * radius,];
    var target = [0,0];
    var up = [0,0];
    var view = m.lookAt(eye,target,up);

    var worldViewProjection = m.multiplyMatrix(view,projection);
    gl.uniformMatrix4fv(worldViewProjectionLoc,worldViewProjection);

    gl.drawElements(gl.LINES,indices.length,gl.UNSIGNED_SHORT,0);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}

main();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?