WebGL创建多个对象?

时间:2018-03-16 23:31:59

标签: graphics webgl graphics2d

所以我尝试使用中点算法创建圆圈。我在如何处理缓冲区方面遇到了麻烦,基本上可以正确设置WebGL。使用控制台我可以看到算法工作正常并使顶点arrray,但我需要帮助了解如何处理use.Program,createBuffers,drawArrays。我应该把它们放在哪里?

另外,每次我在START()函数中调用它时,我应该将圆圈连接起来吗?

喜欢:circle(blah blah).concat(circle(blah blah));



var vertexShaderText = 
[
'precision mediump float;',
'',
'attribute vec2 vertPosition;',
'attribute vec3 vertColor;',
'varying vec3 fragColor;',
'',
'void main()',
'{',
'  fragColor = vertColor;',
'  gl_Position = vec4(vertPosition, 0.0, 1.0);',
'}'
].join('\n');

var fragmentShaderText =
[
'precision mediump float;',
'',
'varying vec3 fragColor;',
'void main()',
'{',
'  gl_FragColor = vec4(fragColor, 1.0);',
'}'
].join('\n');


var START = function () {
  console.log('This is working');

  var canvas = document.getElementById('sky');
  var gl = canvas.getContext('webgl');

  if (!gl) {
    console.log('WebGL not supported, falling back on  experimental-webgl');
    gl = canvas.getContext('experimental-webgl');
  }

  if (!gl) {
    alert('Your browser does not support WebGL');
  }

  gl.clearColor(.3, .3, .7, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);


  // Create shaders

  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  var fragmentShader = 
     gl.createShader(gl.FRAGMENT_SHADER);

  gl.shaderSource(vertexShader, vertexShaderText);
  gl.shaderSource(fragmentShader, fragmentShaderText);

  //create a program for the shaders
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  gl.useProgram(program);

    var circle = function (xmid, ymid, r) {
  var points = [];
  var x = 0;
  var y = r;
  var pk = 5/4 - r;
  while (x < y)
  {
    if (pk < 0)
    {
      x++;
      pk += 2*x + 1;
    }
    else
    {
      x++;
      y--;
      pk += 2 * (x-y) + 1;
    }
    points.push(x+xmid, y+ymid);
    points.push(x+xmid, -y+ymid);
    points.push(-x+xmid, y+ymid);
    points.push(-x+xmid, -y+ymid);
    points.push(y+xmid, x+ymid);
    points.push(y+xmid, -x+ymid);
    points.push(-y+xmid, x+ymid);
    points.push(-y+xmid, -x+ymid);
  }

  var cbuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), 
      gl.STATIC_DRAW);
  gl.drawArrays(gl.POINTS, 0, points.length/2);

  var positionAttribLocation = gl.getAttribLocation(program, 
   'vertPosition');
  var colorAttribLocation = gl.getAttribLocation(program, 
   'vertColor');

  gl.vertexAttribPointer(
    positionAttribLocation, // Attribute location
    2, // Number of elements per attribute
    gl.FLOAT, // Type of elements
    gl.FALSE,
    5 * Float32Array.BYTES_PER_ELEMENT, // Size of an  individual vertex
    0 // Offset from the beginning of a single vertex to this attribute
  );

  gl.enableVertexAttribArray(positionAttribLocation);
  gl.enableVertexAttribArray(colorAttribLocation);

  return points;

  }

  circle(0.6, 0.6, 0.18);

  circle(0.9, 0.6, 0.18);

  circle(0.5, 0.4, 0.18);

  circle(1.0, 0.4, 0.18);

  circle(0.75, 0.4, 0.18);

  circle(0.75, 0.4, 0.18);


}

START();
&#13;
<canvas id="sky"></canvas>
&#13;
&#13;
&#13;

这是我的控制台日志所说的:

 6WebGL: INVALID_OPERATION: useProgram: program not 
 valid
 6WebGL: INVALID_OPERATION: drawArrays: no valid shader 
 program in use
 12WebGL: INVALID_OPERATION: getAttribLocation: program 
 not linked

您可以清楚地看到我在开始时链接和使用该程序。那是什么给出了什么?

1 个答案:

答案 0 :(得分:0)

代码

存在多个问题
  1. 着色器未编译

    使用gl.shaderSource设置着色器源后,您需要 用gl.compileShader编译它们。你也应该 通过致电gl.getShaderParameter(shader, gl.COMPILE_STATUS)来检查错误 你应该在通过电话联系后检查错误 gl.getProgramParameter(program, gl.LINK_STATUS)

  2. 在设置属性

    之前调用
  3. gl.drawArrays

  4. 代码启用了2个属性,但仅为1个属性提供数据。

  5. 代码正在绘制gl.POINTS,但顶点着色器未设置gl_PointSize

  6. 我也不太了解你的圈子代码,但由于我不知道它真正想要做什么,我无法修复它。

    最后你应该阅读some tutorials on WebGL

    我还建议您为着色器使用多行模板文字

    &#13;
    &#13;
    const vertexShaderText = `
    precision mediump float;
    
    attribute vec2 vertPosition;
    attribute vec3 vertColor;
    varying vec3 fragColor;
    
    void main()
    {
      fragColor = vertColor;
      gl_Position = vec4(vertPosition, 0.0, 1.0);
      gl_PointSize = 5.;
    }
    `;
    
    const fragmentShaderText = `
    precision mediump float;
    
    varying vec3 fragColor;
    void main()
    {
      gl_FragColor = vec4(fragColor, 1.0);
    }
    `;
    
    const start = function () {
      console.log('This is working');
    
      const canvas = document.getElementById('sky');
      const gl = canvas.getContext('webgl');
    
      if (!gl) {
        alert('Your browser does not support WebGL');
        return;
      }
    
      gl.clearColor(.3, .3, .7, 1.0);
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    
      //create a shader program 
      const program = createProgram(gl, vertexShaderText, fragmentShaderText);
      gl.useProgram(program);
    
      const circle = function (xmid, ymid, r) {
        const points = [];
        let x = 0;
        let y = r;
        let pk = 5/4 - r;
        while (x < y)
        {
          if (pk < 0)
          {
            x++;
            pk += 2*x + 1;
          }
          else
          {
            x++;
            y--;
            pk += 2 * (x-y) + 1;
          }
          points.push(x+xmid, y+ymid);
          points.push(x+xmid, -y+ymid);
          points.push(-x+xmid, y+ymid);
          points.push(-x+xmid, -y+ymid);
          points.push(y+xmid, x+ymid);
          points.push(y+xmid, -x+ymid);
          points.push(-y+xmid, x+ymid);
          points.push(-y+xmid, -x+ymid);
        }
    
        const cbuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);
    
        const positionAttribLocation = gl.getAttribLocation(program, 'vertPosition');
        const colorAttribLocation = gl.getAttribLocation(program, 'vertColor');
    
        gl.vertexAttribPointer(
          positionAttribLocation, // Attribute location
          2, // Number of elements per attribute
          gl.FLOAT, // Type of elements
          gl.FALSE,
          0, // Size of an  individual vertex
          0 // Offset from the beginning of a single vertex to this attribute
        );
    
        gl.enableVertexAttribArray(positionAttribLocation);
        
        // you probably meant to supply colors for this attribute
        // since if you wanted a constant color you'd have probably
        // used a uniform but since you didn't we'll set a constant
        // color
        gl.vertexAttrib4f(colorAttribLocation, 1, 0, 0, 1);
        
        gl.drawArrays(gl.POINTS, 0, points.length/2);
    
        return points;
    
      }
    
      circle(0.6, 0.6, 0.18);
      circle(0.9, 0.6, 0.18);
      circle(0.5, 0.4, 0.18);
      circle(1.0, 0.4, 0.18);
      circle(0.75, 0.4, 0.18);
      circle(0.75, 0.4, 0.18);
    }
    
    function createProgram(gl, vertexShaderText, fragmentShaderText) {
      // Create shaders
      const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderText);
      const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderText);
    
      const program = gl.createProgram();
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      gl.linkProgram(program);
      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.error(gl.getProgramInfoLog(program));
        gl.deleteProgram(program);
        return null;
      }
      return program;  
    }
    
    function createShader(gl, type, source) {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error(gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
      }
      return shader;
    }
    
    start();
    &#13;
    <canvas id="sky"></canvas>
    &#13;
    &#13;
    &#13;