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

本程序通过矩阵运算方式实现一个三角形的平移变换任务,最终效果如下图。

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

1. TranslatedTriangleMatrix.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="TranslatedTriangleMatrix.js">
    </script>
</html>

2. TranslatedTriangleMatrix.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 translation distance for x, y, and z direction
  var Tx = 0.5, Ty = 0.5, Tz = 0.0;
    var xformMatrix = new Float32Array([
      1.0, 0.0, 0.0, 0.0,
      0.0, 1.0, 0.0, 0.0,
      0.0, 0.0, 1.0, 0.0,
        Tx, Ty, Tz, 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 条评论
登录 后参与评论

相关文章

来自专栏田祥的专栏

Scala 强大的精简语法(示例)

Scala 是面向对象与函数编程语言,最终编译成 java 字节码,运行在 jvm 上。

72800
来自专栏青玉伏案

算法与数据结构(十七) 基数排序(Swift 3.0版)

前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关。今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数...

20460
来自专栏积累沉淀

【译】Java 8的新特性—终极版

声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:...

257100
来自专栏jeremy的技术点滴

写py2、py3兼容的代码

95180
来自专栏图形学与OpenGL

WebGL三角形平移变换

15330
来自专栏恰童鞋骚年

C# 中的委托和事件

文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,...

10220
来自专栏强仔仔

freemarker常见的一些用法(一)

今天给大家介绍一下freemarker基本用法,例如:if、 list、 判断是否为空、获取值等等之类的。 在使用之前要先在模板中设置值,这里我使用的是Spri...

35090
来自专栏F_Alex

数据结构与算法(六)-背包、栈和队列

  前言:许多基础数据类型都和对象的集合有关。具体来说,数据类型的值就是一组对象的集合,所有操作都是关于添加、删除或是访问集合中的对象。而且有很多高级数据结构都...

12740
来自专栏技术之路

【转】Go Interface 源码剖析

源网址:http://legendtkl.com/2017/07/01/golang-interface-implement/

18920
来自专栏desperate633

LeetCode 9. Palindrome Number分析代码

最常规的思路是直接将数反转再对比,但实际上,我们只需要反转后半部分跟前半部分对比就可以了。两种情况,一是位数为偶数,直接对比,位数为奇数,大数除以10对比。

9020

扫码关注云+社区

领取腾讯云代金券