专栏首页图形学与OpenGLWebGL三角形旋转变换

WebGL三角形旋转变换

本程序实现一个三角形的旋转变换任务,最终效果如下图。

整个程序包含两个文件,分别是:

1. RotatedTriangle.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>旋转三角形</title>
    </head>
    <body onload="startup()">
        <canvas id="myGLCanvas" width="600" height="600">
        </canvas>
    </body>
    <script type="text/javascript" src="RotatedTriangle.js">
    </script>
</html>

2. RotatedTriangle.js

var gl;
function startup(){
    var canvas = document.getElementById('myGLCanvas');//获取<canvas>元素
    gl = createGLContext(canvas);
    setupShaders(); 

  // Write the positions of vertices to a vertex shader
  var n = initVertexBuffers(gl);
  if (n < 0) {
    console.log('Failed to set the positions of the vertices');
    return;
  }

  // The rotation angle
  var ANGLE = 90.0;

  // Create a rotation matrix
  var radian = Math.PI * ANGLE / 180.0; // Convert to radians
  var cosB = Math.cos(radian), sinB = Math.sin(radian);

  // Note: WebGL is column major order
  var xformMatrix = new Float32Array([
     cosB, sinB, 0.0, 0.0,
    -sinB, cosB, 0.0, 0.0,
      0.0,  0.0, 1.0, 0.0,
      0.0,  0.0, 0.0, 1.0
  ]);

  // Pass the rotation matrix to the vertex shader
  var u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix');
  if (!u_xformMatrix) {
    console.log('Failed to get the storage location of u_xformMatrix');
    return;
  }
  gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);

  // Specify the color for clearing <canvas>
  gl.clearColor(0, 0, 0, 1);

  // Clear <canvas>
  gl.clear(gl.COLOR_BUFFER_BIT);

  // Draw the rectangle
  gl.drawArrays(gl.TRIANGLES, 0, n);
 }

function createGLContext(canvas) {
  var names = ["webgl", "experimental-webgl"];
  var context = null;
  for (var i=0; i < names.length; i++) {
    try {
      context = canvas.getContext(names[i]); //获取webgl context绘图上下文
    } catch(e) {}
    if (context) {
      break;
    }
  }
  if (context) {
    context.viewportWidth = canvas.width;
    context.viewportHeight = canvas.height;
  } else {
    alert("Failed to create WebGL context!");
  }
  return context;
}

function setupShaders() {
    //顶点着色器程序
    var vertexShaderSource = 
      'attribute vec4 a_Position;\n' +
      'uniform mat4 u_xformMatrix;\n' +
      'void main() {\n' +
      '  gl_Position = u_xformMatrix * a_Position;\n' +
      '}\n';

    //片元着色器程序
    var fragmentShaderSource = 
      'void main(){ \n' +
      '    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n' + //gl_FragColor指定像素的颜色
      '} \n';  

  var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
  var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);

  var shaderProgram = gl.createProgram();
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);
  gl.linkProgram(shaderProgram);

  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    alert("Failed to setup shaders");
  }

  gl.useProgram(shaderProgram);
  gl.program= shaderProgram;
}

function loadShader(type, shaderSource) {
  var shader = gl.createShader(type);
  gl.shaderSource(shader, shaderSource);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      alert("Error compiling shader" + gl.getShaderInfoLog(shader));
      gl.deleteShader(shader);   
      return null;
  }
  return shader;  
}

function initVertexBuffers(gl) {
  var vertices = new Float32Array([
    0, 0.5,   -0.5, -0.5,   0.5, -0.5
  ]);
  var n = 3; // The number of vertices

  // Create a buffer object
  var vertexBuffer = gl.createBuffer();
  if (!vertexBuffer) {
    console.log('Failed to create the buffer object');
    return -1;
  }

  // Bind the buffer object to target
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  // Write date into the buffer object
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var a_PosLocation = gl.getAttribLocation(gl.program, 'a_Position');
  if (a_PosLocation < 0) {
    console.log('Failed to get the storage location of a_Position');
    return -1;
  }
  // Assign the buffer object to a_Position variable
  gl.vertexAttribPointer(a_PosLocation, 2, gl.FLOAT, false, 0, 0);

  // Enable the assignment to a_Position variable
  gl.enableVertexAttribArray(a_PosLocation);

  return n;
}

参考代码

  1. WebGL Programming Guide, https://sites.google.com/site/webglbook/
  2. Professional WebGL Programming: Developing 3D Graphics for the Web,Listing 2-1,http://media.wiley.com/product_ancillary/60/11199688/DOWNLOAD/Listing-2-1.html

转载请注明出处。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WebGL三角形平移变换(矩阵方式)

    步行者08
  • WebGL三角形平移变换

    步行者08
  • WebGL绘制三角形

    步行者08
  • WebGL三角形平移变换(矩阵方式)

    步行者08
  • WebGL三角形平移变换

    步行者08
  • 用Web音频API来做一个音频可视化工具

    如果你曾经想过像MilkDrop这样的音乐可视化工具是怎么做的,那么这篇文章就是为你准备的。我们将从使用Canvas API来做简单的可视化入手,然后慢慢转移到...

    疯狂的技术宅
  • Javascript如何实现GPU加速?

    如果只是通用的计算场景呢?比如处理图片中大量像素信息,我们有办法使用GPU资源吗?这正是本文要讲的,GPU通用计算,简称GPGPU。

    腾讯Bugly
  • HT for Web基于HTML5的图像操作(三)

    HT_hightopo
  • HT for Web基于HTML5的图像操作(三)

    上篇采用了HTML5的Canvas的globalCompositeOperation属性达到了染色效果,其实CSS也提供了一些常规图像变化的设置参数,关于CSS...

    HT for Web
  • WebGL2系列之顶点数组对象

    顶点数组对象( VAO )是这样一种对象: 它封装了与顶点处理器有关的所有数据,它记录了顶点缓存区和索引缓冲区的引用,以及顶点的各种属性的布局而不是实际的数据。

    用户3158888

扫码关注云+社区

领取腾讯云代金券