在webgl中的圆周上绘制点

时间:2016-10-09 17:47:10

标签: javascript webgl

我能画一个圆圈 我想在圆圈上选择一个任意点并绘制一个像三角形或者一样的形状 一个简单的圆周点

现在我理解的是vertexData数组有那个点 所以我可以从vertexData中选择一个点 但是,如何继续将该点绘制到该位置 如果它只是在画布上画一个点 我明白在vertexShader中我可以 宣布 属性vec4 a_Position 然后gl_Position = a_Position

但是在圆周上,我不理解 请在这里指导 感谢

<script>
var vertexShaderText = [
  'uniform vec2 u_resolution;',
  '',
  'attribute vec2 a_position;',
  '',
  'void main()',
  '{',
  '',
  'vec2 clipspace = a_position / u_resolution * 1.0 ;',
  '',
  'gl_Position = vec4(clipspace * vec2(1, -1), 0, 1);',
  '}'
].join("\n");
var fragmentShaderText = [
  'precision mediump float;',
  '',
  'void main(void)',
  '{',
  '',
  'gl_FragColor = vec4(1.0, 0, 0, 0);',
  '',
  '}'

].join("\n");
var uni = function(){
  var canvas = document.getElementById("game-surface");
  var gl = canvas.getContext("webgl",{antialias: true});
  console.log("This is working");

  gl.clearColor(0.412,0.412,0.412,1);
  gl.clear(gl.COLOR_BUFFER_BIT);


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

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

  gl.compileShader(vertextShader);
  gl.compileShader(fragmentShader);

  if(!gl.getShaderParameter(vertextShader,gl.COMPILE_STATUS)){
    console.error("Error with vertexshader",gl.getShaderInfoLog(vertextShader));
    return;
  }
  if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
    console.error("Error with fragmentShader",gl.getShaderInfoLog(fragmentShader));
    return;
  }



  var program =gl.createProgram();
  gl.attachShader(program,vertextShader);
  gl.attachShader(program,fragmentShader);
  gl.linkProgram(program);
  gl.useProgram(program);
  if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
    console.error("Error linking program",gl.getProgramInfoLog(program));
    return;
  }
  gl.validateProgram(program);
  if(!gl.getProgramParameter(program,gl.VALIDATE_STATUS)){
    console.error("Error validating",gl.getProgramInfoLog(program));
  }

  var circle = {x: 0, y:0, r: 500};
  var ATTRIBUTES = 2;
  var numFans = 64;
  var degreePerFan = (2* Math.PI) / numFans;
  var vertexData = [circle.x, circle.y];


//  console.log(gl_Position)
  for(var i = 0; i <= numFans; i++) {
    var index = ATTRIBUTES * i + 2; // there is already 2 items in array
    var angle = degreePerFan * (i+0.1);
    //console.log(angle)
    vertexData[index] = circle.x + Math.cos(angle) * circle.r;
    vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
  }
  //console.log(vertexData);
  var vertexDataTyped = new Float32Array(vertexData);

  var buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);

  var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
  gl.uniform2f(resolutionLocation, canvas.width, canvas.height);

  gl.enableVertexAttribArray(positionLocation);

  var positionLocation = gl.getAttribLocation(program, "a_position");
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
  gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);


};
uni();
</script>

1 个答案:

答案 0 :(得分:0)

您使用三角形风扇绘制此圆圈,因此绘制其他形状需要第二次绘制调用。这不会很好地扩展,因为绘制调用很昂贵,更有可能你想要一些方法在一次绘制调用中绘制多个形状。

也就是说,作为一个简单的例子,您可以将以下代码添加到uni函数的底部,在现有函数结束的第一次绘制调用结束后,放置第二个,使用第二次绘制调用在第一个圆周上的较小圆圈。给定片段着色器,这也将是一个红色圆圈,因此您可能希望修改着色器以使用不同的颜色。

// Insert this code at the end of the uni() function, it will make
// use of variables and GL state already declared earlier in that function.

// Pick a point along circumference, range 1 to 63
var selectedPointIndex = 8;

circle.x = vertexData[selectedPointIndex * 2];
circle.y = vertexData[selectedPointIndex * 2 + 1];
circle.r = 50;

vertexData = [circle.x, circle.y];
for(var i = 0; i <= numFans; i++) {
    var index = ATTRIBUTES * i + 2; // there is already 2 items in array
    var angle = degreePerFan * (i+0.1);
    vertexData[index] = circle.x + Math.cos(angle) * circle.r;
    vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
}
vertexDataTyped = new Float32Array(vertexData);

buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);

gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);