【问题标题】:How Can I draw multiple figures in WebGL如何在 WebGL 中绘制多个图形
【发布时间】:2020-10-03 10:36:32
【问题描述】:

您好,我曾尝试在 WebGL 中同时绘制不同的图形,但它只绘制第一个图形。我对 WebGL 很陌生。我不知道问题是不是因为我没有使用缓冲区(因为我必须这样做)或着色器。

但我认为我为每个图形使用不同的缓冲区,因为我传入函数“模型”,然后我执行 model.Idbuffer...所以我想我为每个图形创建一个缓冲区。

任何帮助都非常感谢。

这是我的代码。

var gl = null;
var program;

var x = 0;
var y = 0;
var z = 0;
var radi = 0;
var nombre_costats = 100;

var figura = {

  "vertices" : [-0.2, -0.2 , 0.0,
                -0.2, -0.1, 0.0,
                -0.4, -0.1, 0.0,
                -0.4, -0.2, 0.0,
                -0.5, -0.2, 0.0,
                -0.5, 0.0, 0.0,
                -0.2, 0.0, 0.0,
                -0.2, 0.2, 0.0,
                0.3, 0.2, 0.0,
                0.3, 0.0, 0.0,
                0.4, 0.0, 0.0,
                0.4, -0.2, 0.0,
                0.3, -0.2, 0.0,
                0.3, -0.1, 0.0,
                0.1, -0.1, 0.0,
                0.1, -0.2, 0.0,],

  "indices" : [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0]

};

var poligon = {

  "vertices" : [],

  "indices" : []

};

function dibuixar_cercle(x, y, z, radi, nombre_costats, poligon){
  
  var nombre_vertex = nombre_costats + 2;
  poligon.vertices.push(0);
  poligon.vertices.push(0);
  poligon.vertices.push(0);

  for (var i = 1; i<nombre_vertex; i++){
    poligon.vertices.push(x + radi * Math.cos( i * (2 * Math.PI) / nombre_costats));
    poligon.vertices.push(y + radi * Math.sin( i * (2 * Math.PI) / nombre_costats));
    poligon.vertices.push(0);
    if (i>=2){
      poligon.indices.push(0);
      poligon.indices.push(i-1);
      poligon.indices.push(i);
    }
  }

}

function getWebGLContext() {

  var canvas = document.getElementById("myCanvas");

  try {
    return canvas.getContext("webgl2");
  }
  catch(e) {
  }

  return null;

}

function initShaders() {

  // paso 1
  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, document.getElementById('myVertexShader').text);
  gl.compileShader(vertexShader);

  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, document.getElementById('myFragmentShader').text);
  gl.compileShader(fragmentShader);
  
  // paso 2
  program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  
  // paso 3
  gl.linkProgram(program);

  gl.useProgram(program);

  program.vertexPositionAttribute = gl.getAttribLocation( program, "VertexPosition");
  gl.enableVertexAttribArray(program.vertexPositionAttribute);

}

function initRendering() {

  gl.clearColor(0.0,0.0,1.0,1.0);

}
  
function initBuffers(model) {

  model.idBufferVertices = gl.createBuffer ();
  gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
  gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);

  model.idBufferIndices = gl.createBuffer ();
  gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
  gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);

}

function draw(model) {

  gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
  gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
  gl.drawElements(gl.LINE_LOOP, 32, gl.UNSIGNED_SHORT, 0);
  
}

function draw2(model) {

  gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
  gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
  gl.drawElements(gl.TRIANGLE, nombre_costats*3 , gl.UNSIGNED_SHORT, 0);
  
}

function drawScene() {

  gl.clear(gl.COLOR_BUFFER_BIT);

  draw(figura);
  draw2(poligon);
}

function initWebGL() {
      
  var costats = 100;
  var radi = 0.1;
  var x_centre = 0;
  var y_centre = 0;
  var z_centre = 0;

  gl = getWebGLContext();

  if (!gl) {
    alert("WebGL 2.0 no está disponible");
    return;
  }


  initShaders();
  dibuixar_cercle(x_centre, y_centre, z_centre, radi, costats, poligon);
  console.log(figura);
  initBuffers(figura);
  initBuffers(poligon);
  console.log(poligon);
  
  initRendering();
  
  requestAnimationFrame(drawScene);

}

initWebGL();
```

【问题讨论】:

    标签: javascript webgl


    【解决方案1】:

    一般来说,您应该为 WebGL 问题添加着色器。但无论如何,问题在于gl.TRIANGLES 而不是gl.TRIANGLE

    var gl = null;
    var program;
    
    var x = 0;
    var y = 0;
    var z = 0;
    var radi = 0;
    var nombre_costats = 100;
    
    var figura = {
    
      "vertices" : [-0.2, -0.2 , 0.0,
                    -0.2, -0.1, 0.0,
                    -0.4, -0.1, 0.0,
                    -0.4, -0.2, 0.0,
                    -0.5, -0.2, 0.0,
                    -0.5, 0.0, 0.0,
                    -0.2, 0.0, 0.0,
                    -0.2, 0.2, 0.0,
                    0.3, 0.2, 0.0,
                    0.3, 0.0, 0.0,
                    0.4, 0.0, 0.0,
                    0.4, -0.2, 0.0,
                    0.3, -0.2, 0.0,
                    0.3, -0.1, 0.0,
                    0.1, -0.1, 0.0,
                    0.1, -0.2, 0.0,],
    
      "indices" : [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0]
    
    };
    
    var poligon = {
    
      "vertices" : [],
    
      "indices" : []
    
    };
    
    function dibuixar_cercle(x, y, z, radi, nombre_costats, poligon){
      
      var nombre_vertex = nombre_costats + 2;
      poligon.vertices.push(0);
      poligon.vertices.push(0);
      poligon.vertices.push(0);
    
      for (var i = 1; i<nombre_vertex; i++){
        poligon.vertices.push(x + radi * Math.cos( i * (2 * Math.PI) / nombre_costats));
        poligon.vertices.push(y + radi * Math.sin( i * (2 * Math.PI) / nombre_costats));
        poligon.vertices.push(0);
        if (i>=2){
          poligon.indices.push(0);
          poligon.indices.push(i-1);
          poligon.indices.push(i);
        }
      }
    
    }
    
    function getWebGLContext() {
    
      var canvas = document.getElementById("myCanvas");
    
      try {
        return canvas.getContext("webgl2");
      }
      catch(e) {
      }
    
      return null;
    
    }
    
    function initShaders() {
    
      // paso 1
      var vertexShader = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vertexShader, document.getElementById('myVertexShader').text);
      gl.compileShader(vertexShader);
    
      var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fragmentShader, document.getElementById('myFragmentShader').text);
      gl.compileShader(fragmentShader);
      
      // paso 2
      program = gl.createProgram();
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      
      // paso 3
      gl.linkProgram(program);
    
      gl.useProgram(program);
    
      program.vertexPositionAttribute = gl.getAttribLocation( program, "VertexPosition");
      gl.enableVertexAttribArray(program.vertexPositionAttribute);
    
    }
    
    function initRendering() {
    
      gl.clearColor(0.0,0.0,1.0,1.0);
    
    }
      
    function initBuffers(model) {
    
      model.idBufferVertices = gl.createBuffer ();
      gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
      gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);
    
      model.idBufferIndices = gl.createBuffer ();
      gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
      gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);
    
    }
    
    function draw(model) {
    
      gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
      gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
    
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
      gl.drawElements(gl.LINE_LOOP, 32, gl.UNSIGNED_SHORT, 0);
      
    }
    
    function draw2(model) {
    
      gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
      gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
    
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
      gl.drawElements(gl.TRIANGLES, nombre_costats*3 , gl.UNSIGNED_SHORT, 0);
      
    }
    
    function drawScene() {
    
      gl.clear(gl.COLOR_BUFFER_BIT);
    
      draw(figura);
      draw2(poligon);
    }
    
    function initWebGL() {
          
      var costats = 100;
      var radi = 0.1;
      var x_centre = 0;
      var y_centre = 0;
      var z_centre = 0;
    
      gl = getWebGLContext();
    
      if (!gl) {
        alert("WebGL 2.0 no está disponible");
        return;
      }
    
    
      initShaders();
      dibuixar_cercle(x_centre, y_centre, z_centre, radi, costats, poligon);
      //console.log(figura);
      initBuffers(figura);
      initBuffers(poligon);
      //console.log(poligon);
      
      initRendering();
      
      requestAnimationFrame(drawScene);
    
    }
    
    initWebGL();
    <canvas id="myCanvas"></canvas>
    <script id="myVertexShader" type="whatever">
    attribute vec4 VertexPosition;
    void main() {
      gl_Position = VertexPosition;
    }
    </script>
    <script id="myFragmentShader" type="whatever">
    precision highp float;
    void main() {
      gl_FragColor = vec4(1, 1, 0, 1);
    }
    </script>

    几点说明:

    • 没有理由在canvas.getContext 周围使用try/catch。该函数不会抛出异常。它只会在失败时返回null

    • 在初始化时启用顶点属性并不常见。

    • 下次尝试发布工作snippet

    • this script 可能有助于发现错误。它会找到这个的。

      drawElements 中的错误(/UNKNOWN WebGL ENUM/undefined, 300, UNSIGNED_SHORT, 0):参数 0 未定义

      没有错误的原因是因为gl.TRIANGLE 不存在所以它最终将undefined 传递给gl.drawElementsundefined 默默地转换为 00gl.POINTS 的值相同,这是一个有效值。你看不到的原因 任何事情都是因为您必须在顶点着色器中设置gl_PointSize 才能看到点。

      这带来了我经常遵循的提示。永远不要选择 0 作为有效的枚举值。意外通过 0 太容易了,所以如果 0 是一个有效值,那么意外将很难找到。不幸的是,OpenGL 为gl.POINTS 选择了 0,而确切的问题浪费了成千上万的程序员的时间。

    • 您可能会发现these articles 很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      相关资源
      最近更新 更多