WebGL 创建多个对象



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

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

 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. 着色器未编译

    使用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

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

最后,您可能应该阅读一些有关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();
<canvas id="sky"></canvas>

相关内容

  • 没有找到相关文章

最新更新