WebGL三角形平移变换

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

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

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

2. TranslatedTriangle.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;

  // Pass the translation distance to the vertex shader
  var u_Translation = gl.getUniformLocation(gl.program, 'u_Translation');
  if (!u_Translation) {
    console.log('Failed to get the storage location of u_Translation');
    return;
  }
  gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);

  // 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 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 setupShaders() {
    //顶点着色器程序
    var vertexShaderSource = 
      'attribute vec4 a_Position;\n' +
      'uniform vec4 u_Translation;\n' +
      'void main() {\n' +
      '  gl_Position = a_Position + u_Translation;\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 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 条评论
登录 后参与评论

相关文章

来自专栏Android 研究

Android跨进程通信IPC之4——AndroidIPC基础2

通过 Parcel的writeStrongBinder方法将Binder对象序列化:

1204
来自专栏张善友的专栏

在Entity Framework 中执行T-sql语句

从Entity Framework  4开始在ObjectContext对象上提供了2个方法可以直接执行SQL语句:ExecuteStoreQuery<T> 和...

22110
来自专栏函数式编程语言及工具

Scalaz(53)- scalaz-stream: 程序运算器-application scenario

    从上面多篇的讨论中我们了解到scalaz-stream代表一串连续无穷的数据或者程序。对这个数据流的处理过程就是一个状态机器(state machine...

1959
来自专栏Golang语言社区

golang中sort包用法

golang中也实现了排序算法的包sort包. sort包中实现了3种基本的排序算法:插入排序.快排和堆排序.和其他语言中一样,这三种方式都是不公开的,他们只在...

7476
来自专栏coder修行路

Go 处理yaml类型的配置文件

5804
来自专栏desperate633

LeetCode 9. Palindrome Number分析代码

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

852
来自专栏偏前端工程师的驿站

JS魔法堂:再识instanceof

一、Breif                                  大家都知道instanceof一般就是用来检查A对象是否为B类或子类的实例。那...

2349
来自专栏HansBug's Lab

1901: Zju2112 Dynamic Rankings

1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Submit: ...

2766
来自专栏小樱的经验随笔

POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)

Brainman Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1057...

4117
来自专栏分布式系统和大数据处理

C#中的委托和事件 - Part.1

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

1033

扫码关注云+社区

领取腾讯云代金券