0
点赞
收藏
分享

微信扫一扫

WebGL绘制五角星(多边形)

飞空之羽 2022-03-30 阅读 69
前端html5

WebGL绘制五角星(多边形)

1. 初始化WebGL context

/**
 * Initialize the context of WebGL
 */
function initWebGL() {
  const canvas = document.querySelector('#glcanvas');
  const gl = canvas.getContext('webgl');

  // If we don't have WebGL, print tip
  if (!gl) {
    console.log('%c%s', 'color: blue', 'Unable to initialize the WebGL, your browser or machine may not support it.');
    return;
  }

  return gl;
}

2. 初始化WebGLShader着色器对象

/**
 * Initialize the shader
 */
function initShader(gl, type, source) {
  // Create the shader
  const shader = gl.createShader(type);

  // Send the source to shader
  gl.shaderSource(shader, source);

  // Compile the shader
  gl.compileShader(shader);

  // See if compiling shader falied, print tip
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.log('%c%s', 'color: blue', 'An error occurred compiling the shader: ' + gl.getShaderInfoLog(shader));
    return null;
  }

  return shader;
}

3. 初始化WebGLProgram对象

/**
 * Initialize the shader program
 */
function initShaderProgram(gl, vsSource, fsSource) {
  // Create the shader program
  const shaderProgram = gl.createProgram();

  // Get shaders
  const vertexShader = initShader(gl, gl.VERTEX_SHADER, vsSource);
  const fragmentShader = initShader(gl, gl.FRAGMENT_SHADER, fsSource);

  // Attach shaders to shader program
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);

  // Tell WebGL the shader program, that is we use to draw
  gl.linkProgram(shaderProgram);
  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    console.log('%c%s', 'color: blue', 'An error occurred linking program: ' + gl.getProgramInfoLog(shaderProgram));
    return null;
  }

  return shaderProgram;
}

4. 初始化保存顶点数据的WebGLBuffer对象(顶点位置数据作为参数传入)

/**
 * Initialize the buffer
 */
function initBuffer(gl, verticePositions) {
  // Create buffer
  const positionBuffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticePositions), gl.STATIC_DRAW);

  return positionBuffer;
}

5. 绘制图元

/**
 * Draw the scene
 */
function drawScene(gl, programInfo) {
  // Clear to black, fully opaque
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  gl.useProgram(programInfo.shaderProgram);
  gl.bindBuffer(gl.ARRAY_BUFFER, programInfo.positionBuffer);
  gl.enableVertexAttribArray(programInfo.vertexPositionBound);
  gl.vertexAttribPointer(
    programInfo.vertexPositionBound,
    3,
    gl.FLOAT,
    false,
    0,
    0
  );

  gl.drawArrays(gl.LINE_LOOP, 0, 10);       // line
  // gl.drawArrays(gl.TRIANGLE_FAN, 0, 10); // triangle
}

6. 入口函数

main();

/**
 * Sample's entry
 */
function main() {
  // Shader sources
  const vertexShaderSource = `
    attribute vec4 vertexPosition;

    void main(void) {
      gl_Position = vertexPosition;
    }
  `;
  const fragmentShaderSource = `
    void main(void) {
      gl_FragColor = vec4(0.94, 0.61, 0.62, 1.0);
    }
  `;

  const { PI, sin, cos, tan } = Math;

  // Vertices positions
  const verticesPositions = [
    -0.3 * tan(36 / 180 * PI), 0.3, 0.0,
    0.0, 1.0, 0.0,
    0.3 * tan(36 / 180 * PI), 0.3, 0.0,
    cos(18 / 180 * PI), sin(18 / 180 * PI), 0.0,
    0.3 / cos(36 / 180 * PI) * cos(18 / 180 * PI), -0.3 / cos(36 / 180 * PI) * sin(18 / 180 * PI), 0.0,
    cos(54 / 180 * PI), -sin(54 / 180 * PI), 0.0,
    0.0, -0.3 / cos(36 / 180 * PI), 0.0,
    -cos(54 / 180 * PI), -sin(54 / 180 * PI), 0.0,
    -0.3 / cos(36 / 180 * PI) * cos(18 / 180 * PI), -0.3 / cos(36 / 180 * PI) * sin(18 / 180 * PI), 0.0,
    -cos(18 / 180 * PI), sin(18 / 180 * PI), 0.0,
  ];

  // Get context of WebGL
  const gl = initWebGL();

  // Collect info needed to use to draw
  const shaderProgram = initShaderProgram(gl, vertexShaderSource, fragmentShaderSource);
  const positionBuffer = initBuffer(gl, verticesPositions);
  const vertexPositionBound = gl.getAttribLocation(shaderProgram, 'vertexPosition');
  const programInfo = {
    shaderProgram,
    positionBuffer,
    vertexPositionBound
  }

  // Draw scene
  drawScene(gl, programInfo);
}

7. 总结

绘制图元的基本步骤1-6。想画出一个好看的五角星需要精心的计算,重拾了三角函数…后面还会有矩阵计算。今天好奇看了一下,WebGL113个函数,有的函数形参多达9个,没细数有多少个常量…多coding吧…

举报

相关推荐

0 条评论