WebGLRenderingContext GL错误:GL_INVALID_OPERATION:glDrawElements:尝试访问属性2

时间:2015-05-21 13:07:08

标签: javascript canvas 3d webgl

我正在学习如何在Webgl中使用canvas,但我对纹理有一些问题。我想画一个立方体,一个球体,一个轴和一个网格。如果我只添加球体,轴和网格,一切都很完美但是当我将立方体添加到场景时,网格消失并向我显示此错误:

drawElements中的WebGL错误INVALID_OPERATION(TRIANGLES,357,UNSIGNED_SHORT,0) [.WebGLRenderingContext] GL错误:GL_INVALID_OPERATION:glDrawElements:尝试访问属性2中超出范围的顶点。

这是我的渲染类:

define([
  'text!shaders/vertex-shader.glsl',
  'text!shaders/fragment-shader.glsl',
  './Ejes',
  './Mesh',
  'glMatrix',
  'CuonUtils'], function(vsSource, fsSource,Ejes,Mesh,glMatrix, CuonUtils) {


    var canvas = document.getElementById('canvas');
    var gl = CuonUtils.getWebGLContext(canvas);
    if (!gl) {
      console.log('Failed to get the rendering context for WebGL');
      return;
    }

    // Initialize shaders
    if (!CuonUtils.initShaders(gl, vsSource, fsSource)) {
      console.log('Failed to intialize shaders.');
      return;
    }

    var program = gl.program;


    // Cache attribute/uniform location
    var aPostion = gl.getAttribLocation(program, 'aPostion');
    var aNormal = gl.getAttribLocation(program, 'aNormal');
    var aTexCoord = gl.getAttribLocation(program, 'aTexCoord');


    var uModelMatrix = gl.getUniformLocation(program, 'uModelMatrix');
    var uViewMatrix = gl.getUniformLocation(program, 'uViewMatrix');
    var uProjectionMatrix = gl.getUniformLocation(program, 'uProjectionMatrix');
    var uNormalMatrix = gl.getUniformLocation(program, 'uNormalMatrix');
    var uLightColor = gl.getUniformLocation(program, 'uLightColor');
    var uLightPosition = gl.getUniformLocation(program, 'uLightPosition');
    var uAmbientLight = gl.getUniformLocation(program, 'uAmbientLight');
    var uColor = gl.getUniformLocation(program, 'uColor');
    var uSampler = gl.getUniformLocation(program, 'uSampler');
    var uUseLighting = gl.getUniformLocation(program, 'uUseLighting');
    var uUseTexture = gl.getUniformLocation(program, 'uUseTexture');

    function initBuffers(gl, mesh){

      if(mesh._webgl){
        return;
      }

      mesh._webgl = {};


      // Create Vertex Buffer Object
      var VBOData = new Float32Array(
        mesh.geometry.vertices);

      var VBO = mesh._webgl.vbo = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, VBO);
      gl.bufferData(gl.ARRAY_BUFFER, VBOData, gl.STATIC_DRAW);
      gl.bindBuffer(gl.ARRAY_BUFFER, null);

      // Create Index Buffer Object
      var IBOData = new Uint16Array(
        mesh.geometry.faces);

      var IBO = mesh._webgl.ibo = gl.createBuffer();
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, IBO);
      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, IBOData, gl.STATIC_DRAW);
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
      mesh._webgl.ibo.dataSize = IBOData.length;

      // Create Normal Buffer Object
      var NBOData = new Float32Array(
        mesh.geometry.normals);

      var NBO = mesh._webgl.nbo = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, NBO);
      gl.bufferData(gl.ARRAY_BUFFER, NBOData, gl.STATIC_DRAW);
      gl.bindBuffer(gl.ARRAY_BUFFER, null);

      if(mesh.useTexture){
        // Create st Buffer Object
        var STBOData = new Float32Array(
          mesh.geometry.st);

        var STBO = mesh._webgl.stbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, STBO);
        gl.bufferData(gl.ARRAY_BUFFER, STBOData, gl.STATIC_DRAW);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);

        var TBO = mesh._webgl.tbo = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, TBO);
        gl.texImage2D(
          gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
          new Uint8Array([255, 255, 255, 255])
        );
        loadTexture(gl, mesh.imgSrc, mesh._webgl.tbo, function() {
                bindTextureToSampler(gl, mesh._webgl.tbo);
              });
      }
    }

    function render(scene, camera) {

        // Specify the color for clearing <canvas>
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        // seteo las luces
        gl.uniform3fv(uLightColor, scene.pointLight.getLightColor());
        gl.uniform3fv(uLightPosition, scene.pointLight.getLightPosition());
        gl.uniform3fv(uAmbientLight, scene.ambientLight.getLightColor());



        for( var i = 0; i < scene.meshes.length; i++){
          var mesh = scene.meshes[i];

          initBuffers(gl, mesh);

          gl.uniform1i(uUseLighting, mesh.useLight);
          gl.uniform1i(uUseTexture, mesh.useTexture);

          gl.enableVertexAttribArray(aPostion);
          gl.bindBuffer(gl.ARRAY_BUFFER, mesh._webgl.vbo);
          gl.vertexAttribPointer(
            aPostion, 3, gl.FLOAT, false, 0, 0
          );

          gl.enableVertexAttribArray(aNormal);
          gl.bindBuffer(gl.ARRAY_BUFFER, mesh._webgl.nbo);
          gl.vertexAttribPointer(
            aNormal, 3, gl.FLOAT, false, 0, 0
          );

          // Clean up
          gl.bindBuffer(gl.ARRAY_BUFFER, null);

          gl.uniformMatrix4fv(uModelMatrix, false, mesh.getModelMatrix());
          gl.uniformMatrix4fv(uViewMatrix, false, camera.getViewMatrix());
          gl.uniformMatrix4fv(uProjectionMatrix, false, camera.getProjectionMatrix());
          gl.uniformMatrix4fv(uNormalMatrix, false, mesh.getNormalMatrix());
          gl.uniform4fv(uColor, mesh.material.getColor());


          if(mesh.useTexture){
            gl.enableVertexAttribArray(aTexCoord);
            gl.bindBuffer(gl.ARRAY_BUFFER, mesh._webgl.stbo);
            gl.vertexAttribPointer(
              aTexCoord, 2, gl.FLOAT, false, 0, 0
            );
            gl.bindBuffer(gl.ARRAY_BUFFER, null);

            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, mesh._webgl.tbo);
            gl.uniform1i(uSampler, 0);
          }

          draw(gl,mesh);

        }

    }

    function loadTexture(gl, imageSrc, textureBO, callback) {
      var image = new Image();
      image.src = imageSrc;
      image.onload = function () {
        gl.bindTexture(gl.TEXTURE_2D, textureBO);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        setupTexture(image.width, image.height);
        gl.bindTexture(gl.TEXTURE_2D, null);
        callback();
      };
    }

    function bindTextureToSampler(gl, textureBO) {
      gl.bindTexture(gl.TEXTURE_2D, textureBO);
      gl.uniform1i(uSampler, 0);
    }

    function setupTexture(width, height) {
      if (isPowerOf2(width) && isPowerOf2(height) ){
        // the dimensions are power of 2 so generate mips and turn on
        // tri-linear filtering.
        gl.generateMipmap(gl.TEXTURE_2D);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
      } else {
        // at least one of the dimensions is not a power of 2 so set the filtering
        // so WebGL will render it.
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      }

     }

    function isPowerOf2(value) {
      return (value & (value - 1)) === 0;
    }

    function draw(gl, mesh) {

      // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh._webgl.ibo);
      gl.drawElements(mesh.tipe, mesh._webgl.ibo.dataSize, gl.UNSIGNED_SHORT, 0);
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
      gl.bindTexture(gl.TEXTURE_2D, null);
    }

    return {
      render: render
    };
});

这是我的主要课程:

define([
  './WebGLRenderer',
  './Scene',
  './Mesh',
  './Geometry',
  './Material',
  './RegularConvexPolygonGeometry',
  './Cubo',
  './Sphere',
  './Cylinder',
  './PerspectiveCamera',
  './OrthographicCamera',
  './Light',
  './PointLight',
  './Ejes',
  'dat',
  './cuadrado',
  'CuonUtils'
], function(WebGLRenderer, Scene, Mesh, Geometry, Material,
      RegularConvexPolygonGeometry, Cubo, Sphere, Cylinder,
      PerspectiveCamera, OrthographicCamera, Light, PointLight,
      Ejes, dat, Cuadrado, CuonUtils) {

  var canvas = document.getElementById('canvas');
  var gl = CuonUtils.getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  ////////////
  // ESCENA //
  ////////////
  var clearColor = [0.0,0.0,0.0];

  //Ambient Light
  var light = Object.create(Light);
  light.init();
  light.hex = Math.floor( 0xaaaaaa );

  //Point Light
  var pointLight = Object.create(PointLight);
  pointLight.init();

  var scene = Object.create(Scene);
  scene.init(clearColor, light, pointLight);

  //////////
  // EJES //
  //////////

  //GRID
  var GrillaGeometry = Object.create(Ejes);
  GrillaGeometry.getGrillaGeometry();

  var grillaMaterial = Object.create(Material);
  grillaMaterial.init();
  grillaMaterial.hex = Math.floor( 0x0f0f0f );

  var GrillaMesh = Object.create(Mesh);
  GrillaMesh.init(GrillaGeometry,grillaMaterial);
  GrillaMesh.tipe = gl.LINES;
  GrillaMesh.useLight = false;
  GrillaMesh.useTexture = false;

  //X
  var EjeXGeometry = Object.create(Ejes);
  EjeXGeometry.getXGeometry();

  var EjeXMaterial = Object.create(Material);
  EjeXMaterial.init();
  EjeXMaterial.hex = Math.floor( 0xff0000 );

  var EjeXMesh = Object.create(Mesh);
  EjeXMesh.init(EjeXGeometry,EjeXMaterial);
  EjeXMesh.tipe = gl.LINES;
  EjeXMesh.useLight = false;
  EjeXMesh.useTexture = false;

  //Y
  var EjeYGeometry = Object.create(Ejes);
  EjeYGeometry.getYGeometry();

  var EjeYMaterial = Object.create(Material);
  EjeYMaterial.init();
  EjeYMaterial.hex = Math.floor( 0x00ff00 );

  var EjeYMesh = Object.create(Mesh);
  EjeYMesh.init(EjeYGeometry,EjeYMaterial);
  EjeYMesh.tipe = gl.LINES;
  EjeYMesh.useLight = false;
  EjeYMesh.useTexture = false;

  //Z
  var EjeZGeometry = Object.create(Ejes);
  EjeZGeometry.getZGeometry();

  var EjeZMaterial = Object.create(Material);
  EjeZMaterial.init();
  EjeZMaterial.hex = Math.floor( 0x0000ff );

  var EjeZMesh = Object.create(Mesh);
  EjeZMesh.init(EjeZGeometry,EjeZMaterial);
  EjeZMesh.tipe = gl.LINES;
  EjeZMesh.useLight = false;
  EjeZMesh.useTexture = false;

  scene.addMesh(GrillaMesh);
  scene.addMesh(EjeXMesh);
  scene.addMesh(EjeYMesh);
  scene.addMesh(EjeZMesh);

  ////////////////
  //   ESFERA   //
  ////////////////
  var sphereGeometry = Object.create(Sphere);
  sphereGeometry.init();

  var sphereMaterial = Object.create(Material);
  sphereMaterial.init();
  sphereMaterial.hex = Math.floor( 0xffffff );

  var sphereMesh = Object.create(Mesh);
  sphereMesh.init(sphereGeometry,sphereMaterial);
  sphereMesh.tipe = gl.TRIANGLES;
  sphereMesh.tx = 5.0;
  sphereMesh.useLight = true;
  sphereMesh.useTexture = true;
  sphereMesh.imgSrc = 'scripts/texture/earthmap.jpg';
  scene.addMesh(sphereMesh);


  ////////////////
  //    CUBO    //
  ////////////////
  var cubeGeometry = Object.create(Cubo);
  cubeGeometry.init();

  var cubeMaterial = Object.create(Material);
  cubeMaterial.init();
  cubeMaterial.hex = Math.floor( 0xffffff );

  var cubeMesh = Object.create(Mesh);
  cubeMesh.init(cubeGeometry,cubeMaterial);
  cubeMesh.tipe = gl.TRIANGLES;
  cubeMesh.tz = 5.0;
  cubeMesh.useLight = true;
  cubeMesh.useTexture = true;
  cubeMesh.imgSrc = 'scripts/texture/firefox-icon3.png';
  scene.addMesh(cubeMesh);

  //////////////////////////////
  /// PERSPECTIVE PROJECTION ///
  //////////////////////////////
  // var camera = Object.create(PerspectiveCamera);
  // PerspectiveCamera.init(Math.PI / 4,1,0.1,200);

  ///////////////////////////////
  /// ORTHOGRAPHIC PROJECTION ///
  ///////////////////////////////
  var camera = Object.create(OrthographicCamera);
  OrthographicCamera.init(-8,8,-8,8,0.1,1000);


  function tick(){
    WebGLRenderer.render(scene, camera);
    requestAnimationFrame(tick);
  }

  tick();

});

我几乎可以肯定问题是我的渲染类,但万一我也会发布其他类。

立方体:

define(['glMatrix','./Geometry'], function(glMatrix, Geometry) {
  var Cubo = Object.create(Geometry);

  Cubo.init = function(){

    var vertices = new Float32Array([
     1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0, // v0-v1-v2-v3 front
     1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0, // v0-v3-v4-v5 right
     1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0, // v0-v5-v6-v1 up
    -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0, // v1-v6-v7-v2 left
    -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0, // v7-v4-v3-v2 down
     1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0  // v4-v7-v6-v5 back
    ]);

    //Creo las caras
    var indexVertices = new Uint16Array([
      0, 1, 2,   0, 2, 3,     // front
      4, 5, 6,   4, 6, 7,     // right
      8, 9,10,   8,10,11,     // up
      12,13,14,  12,14,15,    // left
      16,17,18,  16,18,19,    // down
      20,21,22,  20,22,23     // back
    ]);

    //Normales
    var normales = new Float32Array([
      0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
      1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
      0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
     -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
      0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,  // v7-v4-v3-v2 down
      0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0   // v4-v7-v6-v5 back
    ]);

    var st = new Float32Array([
      // Front
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Back
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Top
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Bottom
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Right
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Left
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0
    ]);

    Geometry.init.call(this, vertices, indexVertices, normales, st);
  };

  return Cubo;
});

sphere:

define(['./Geometry'], function(Geometry) {
  var Sphere = Object.create(Geometry);

  Sphere.init = function(){

    var SPHERE_DIV = 13;
    var i, ai, si, ci;
    var j, aj, sj, cj;
    var p1, p2;

    var vertices = [];
    var indexVertices = [];
    var st = [];
    
    //Creo los vertices
    for (j = 0; j <= SPHERE_DIV; j++) {
    aj = j * Math.PI / SPHERE_DIV;
    sj = Math.sin(aj);
    cj = Math.cos(aj);
    for (i = 0; i <= SPHERE_DIV; i++) {
      ai = i * 2 * Math.PI / SPHERE_DIV;
      si = Math.sin(ai);
      ci = Math.cos(ai);

      vertices.push(si * sj);  // X
      vertices.push(cj);       // Y
      vertices.push(ci * sj);  // Z
      st.push(1 - (i / SPHERE_DIV) );
      st.push(1 - (j / SPHERE_DIV) );
      }
    }

    //Creo los indices
    for (j = 0; j < SPHERE_DIV; j++) {
    for (i = 0; i < SPHERE_DIV; i++) {
      p1 = j * (SPHERE_DIV+1) + i;
      p2 = p1 + (SPHERE_DIV+1);

      indexVertices.push(p1);
      indexVertices.push(p2);
      indexVertices.push(p1 + 1);

      indexVertices.push(p1 + 1);
      indexVertices.push(p2);
      indexVertices.push(p2 + 1);
    }
  }
    Geometry.init.call(this, vertices, indexVertices, vertices, st);
  };

  return Sphere;
});

网格:

define(['./Geometry'], function(Geometry) {

  var Ejes = Object.create(Geometry);

  Ejes.getXGeometry = function(){
    var vertices = [];
    var indexVertices = [];
    var st = [];

    vertices.push(0.0,0.0,0.0);
    vertices.push(10.0,0.0,0.0);
    indexVertices.push(0,1);

    Geometry.init.call(this,vertices,indexVertices, vertices, st);
  };

  Ejes.getYGeometry = function(){
    var vertices = [];
    var indexVertices = [];
    var st = [];

    vertices.push(0.0,0.0,0.0);
    vertices.push(0.0,10.0,0.0);
    indexVertices.push(0,1);

    Geometry.init.call(this,vertices,indexVertices, vertices, st);
  };

  Ejes.getZGeometry = function(){
    var vertices = [];
    var indexVertices = [];
    var st = [];

    vertices.push(0.0,0.0,0.0);
    vertices.push(0.0,0.0,10.0);
    indexVertices.push(0,1);

    Geometry.init.call(this,vertices,indexVertices,vertices, st);
  };

  Ejes.getGrillaGeometry = function(){
    var vertices = [];
    var indexVertices = [];
    var st = [];

    for(var i=-10; i<0; i+=1)
    {
      // verticales
      vertices.push(i,0,-10);
      vertices.push(i,0,10);

      // horizontales
      vertices.push(-10,0,i);
      vertices.push(10,0,i);
    }

    vertices.push(0,0,-10);
    vertices.push(0,0,0);

    vertices.push(-10,0,0);
    vertices.push(0,0,0);

    for(i=1; i<=10; i+=1)
    {
      // verticales
      vertices.push(i,0,-10);
      vertices.push(i,0,10);

      // horizontales
      vertices.push(-10,0,i);
      vertices.push(10,0,i);
    }

    for(i=0; i<84;i+=1)
    {
      indexVertices.push(i);
    }

    Geometry.init.call(this,vertices,indexVertices,vertices, vertices);
  };

  return Ejes;

});

我真的很感激你能给我的任何帮助。

0 个答案:

没有答案
相关问题