【问题标题】:WebGL creating multiple objects?WebGL 创建多个对象?
【发布时间】:2018-03-17 15:27:54
【问题描述】:

所以我正在尝试使用中点算法创建圆圈。我在如何处理缓冲区和基本上正确设置 WebGL 方面遇到了麻烦。使用控制台,我可以看到该算法运行良好并制作了顶点数组,但我需要帮助了解如何处理 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();
&lt;canvas id="sky"&gt;&lt;/canvas&gt;

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

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

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

【问题讨论】:

标签: graphics webgl graphics2d


【解决方案1】:

代码有不止一个问题

  1. 着色器未编译

    使用gl.shaderSource 设置着色器源后,您需要 用gl.compileShader 编译它们。你还应该 通过调用 gl.getShaderParameter(shader, gl.COMPILE_STATUS) 检查错误 并且您应该通过调用链接后检查错误 gl.getProgramParameter(program, gl.LINK_STATUS)

  2. 在设置属性之前调用gl.drawArrays

  3. 代码启用 2 个属性,但只为 1 个属性提供数据。

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

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

最后你可能应该阅读some tutorials on WebGL

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

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();
&lt;canvas id="sky"&gt;&lt;/canvas&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2017-09-21
    • 1970-01-01
    相关资源
    最近更新 更多