(目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/3508251.html

这一章主要通过创建一个三角形的例子说明WebGL基本的用法,以下是书中例子的效果图:

创建一个基本的WebGL应用需要以下的步骤:

1.Write some basic HTML code that includes a <canvas> tag. The <canvas> tag provides the drawing area for WebGL.

Then you need to write some JavaScript code to create a reference to your canvas so you can create a WebGLRenderingContext.

2.Write the source code for your vertex shader and your fragment shader.

3.Write source code that uses the WebGL API to create a shader object for both the vertex shader and the fragment shader.

You need to load the source code into the shader objects and compile the shader objects.

4.Create a program object and attach the compiled shader objects to this program object.

After this, you can link the program object and then tell WebGL that you want to use this program object for rendering.

5.Set up the WebGL buffer objects and load the vertex data for your geometry (in this case, the triangle) into the buffer.

6.Tell WebGL which buffer you want to connect to which attribute in the shader, and then, finally, draw your geometry (the triangle).

以上是书中的原话,就不翻译了。

首先我们应该先明白在WebGL中是如何定义三维坐标系的,如下图:

X轴:水平从左向右;Y轴:垂直从下到上;Z轴:垂直于屏幕从里向外

OK,那么我们设想一下,如果设置一个三维物体的Z轴坐标为0,这样三维物体就可以理解成平面物体,然后我们按照之前说的创建一个基本的WebGL应用的步骤分析原书中的代码。

1、我们要创建一个基本的html页面,然后在body中加入canvas标签,然后我们需要写一行JS代码获得对canvas标签的引用,为了得到这个canvas的标签,我们给标签加个id属性,按照第一步描述的我们可以得到以下代码:

<html>
<head>
<script type="text/javascript">
var canvas = document.getElementById("myGLCanvas");
</script>
</head>
<body>
<canvas id="myGLCanvas"></canvas>
</body>
</html>

之后要创建一个WebGLRenderingContext,通过canvasgetContext()方法获得一个绘图区域,getContext()方法需要接收一个参数,目前可选择的值为2dwebglexperimental-webgl,当参数为2d时返回一个CanvasRenderingContext2D对象,后两者则返回WebGLRenderingContext对象,不过需要浏览器的支持,否则返回null值。因为我们要分别取尝试webglexperimental-webgl值,使用数组来存放这两个值,然后进行遍历,得到以下代码:

 var names = ["webgl", "experimental-webgl"];

 var context = null;

 for (var i=0; i < names.length; i++) {

     try {

         context = canvas.getContext(names[i]);

     } catch(e) {}

     if (context) {

     break;

     }
}

2、3、4、我们要写vertex shaderfragment shader。这一块暂时比较难理解,我们先pass,后面再慢慢阐述。照抄书上的代码:

   var vertexShaderSource =
"attribute vec3 aVertexPosition; \n" +
"void main() { \n" +
" gl_Position = vec4(aVertexPosition, 1.0); \n" +
"} \n"; var fragmentShaderSource =
"precision mediump float; \n"+
"void main() { \n"+
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"+
"} \n"; var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource); 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); shaderProgram.vertexPositionAttribute =
gl.getAttribLocation(shaderProgram, "aVertexPosition");
   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;

5、创建一个WebGL缓冲对象,把几何图形的顶点数据放到缓冲对象中。(IE11对WebGLRenderingContext提供的API函数http://msdn.microsoft.com/en-us/library/ie/dn302362(v=vs.85).aspx)。

   vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
var triangleVertices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices),
gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numberOfItems = 3;

下面附上完整代码

<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Listing 2-1, A First WebGL Example</title>
<meta charset="utf-8">
<script type="text/javascript">
var gl;
var canvas;
var shaderProgram;
var vertexBuffer; 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]);
} 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 vec3 aVertexPosition; \n" +
"void main() { \n" +
" gl_Position = vec4(aVertexPosition, 1.0); \n" +
"} \n"; var fragmentShaderSource =
"precision mediump float; \n"+
"void main() { \n"+
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"+
"} \n"; var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource); 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); shaderProgram.vertexPositionAttribute =
gl.getAttribLocation(shaderProgram, "aVertexPosition");
} function setupBuffers() {
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
var triangleVertices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices),
gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numberOfItems = 3;
} function draw() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems);
}
function startup() {
canvas = document.getElementById("myGLCanvas");
gl = createGLContext(canvas);
setupShaders();
setupBuffers();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
draw();
}
</script> </head> <body onload="startup();">
<canvas id="myGLCanvas" width="500" height="500"></canvas>
</body> </html> 

我们知道几乎所有语言的都是以Hello World入门的,虽然WebGL不然一门语言,但作为一直新事物,以上就相当于WebGL的Hello World。

Professional.WebGL.Programming-Chapter 2(高级WebGL编程——第二章)的更多相关文章

  1. Java 高级应用编程 第二章 集合

    一.Java 中的集合类 1.集合概述 Java中集合类是用来存放对象的 集合相当于一个容器,里面包容着一组对象 —— 容器类 其中的每个对象作为集合的一个元素出现 Java API提供的集合类位于j ...

  2. 《JavaScript高级程序设计》——第二章在HTML使用JavaScript

    这章讲的是JavaScript在HTML中的使用,也就是<script>元素的属性.书中详细讲了async.defer.src和type四个<script>的属性. 下面是对第 ...

  3. [转]Windows Shell 编程 第二章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987893】

    第二章Shell的结构  “Shell 编程”的大伞之下有大量的API函数和COM接口.这个种类繁多的‘命令’集允许你用不同的方法对Windows Shell进行编程.函数和接口并不是两种提供相同功能 ...

  4. Java 高级应用编程 第一章 工具类

    一.Java API Java API简介 1.API (Application Programming Interface) 应用程序接口 2.Java中的API,就是JDK提供的各种功能的Java ...

  5. 【读书笔记】C#高级编程 第二章 核心C#

    (一)第一个C#程序 创建一个控制台应用程序,然后输入代码,输入完毕后点击F5 Console.WriteLine();这条语句的意思:把括号内的内容输出到界面上: Console.ReadKey() ...

  6. Java面向对象编程 第二章 第一个Java应用

    2.1创建Java源文件 Java应用由一个或多个扩展名为".java"的文件构成,这些文件被称为Java源文件,从编译的角度,则被称为编译单元. 本章包含两个Java源文件:Do ...

  7. windows核心编程---第二章 字符和字符串处理

        使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也 ...

  8. C++ 编程第二章小结

    switch()用法的注意事项 1:switch语句中的表达式只能是整形数据,字符型数据和枚举型数据,case后面的产量表达式的类型必须与switch括号后面的类型相匹配 2:各个case(包括def ...

  9. Windows核心编程第二章,字符串的表示以及宽窄字符的转换

    目录 Windows核心编程,字符串的表示以及宽窄字符的转换 1.字符集 1.1.双字节字符集DBCS 1.2 Unicode字符集 1.3 UTF-8编码 1.4 UTF - 32编码. 1.5 U ...

随机推荐

  1. canvas学习笔记:canvas对图片的像素级处理--ImageData的应用

    学习了canvas的基本绘图功能后,惊喜的发现canvas对图片数据也有相当强大的处理功能,能够从像素级别操作位图,当然[lte ie8]不支持. 主要的函数有三个: ctx.createImageD ...

  2. JavaWeb chapter10 JavaWeb开发模式

    1.  开发模式 (1)开发模式1:JSP+JavaBean (2)开发模式2:Servlet+JSP+JavaBean (MVC) 2.JavaBean 本质上是一个普通的Java类:需要遵循一定的 ...

  3. 浅谈学习掌握linux系统的优势

    Linux系统让我们懂得了共享.开放.自由可以让人类生活的更加美好,开源精神是一种让每个从事Linux行业的技术人员从骨子里自豪的情怀,开源产品的兴盛受益于开源社区的强壮根基.Linux真的给了我很多 ...

  4. React + Redux 入坑指南

    Redux 原理 1. 单一数据源 all states ==>Store 随着组件的复杂度上升(包括交互逻辑和业务逻辑),数据来源逐渐混乱,导致组件内部数据调用十分复杂,会产生数据冗余或者混用 ...

  5. maven添加自己的jar包到本地仓库

     mvn install:install-file -DgroupId=com.esotericsoftware -DartifactId=minlog -Dversion=1.2 -Dpackagi ...

  6. Microsoft Azure Project Oxford 体验

    2015年4月29日,微软在Build 2015大会上发布了一个震撼人心的项目: Project Oxford, 可以帮助直接实现图像理解.人脸识别.语音识别.语音合成等功能.虽然说这是号称研究院的项 ...

  7. The Managed Metadata Service or Connection is currently not available 分类: Sharepoint 2015-07-09 13:28 5人阅读 评论(0) 收藏

    Does the following error message looks familiar to you? (When you go to Site Actions –> Site Sett ...

  8. IE关闭兼容性视图

    不知道什么时候,ie8的“兼容性视图设置”变成了灰色,如图:  今天通过设置组策略,终以解决了这个问题: ie8的兼容性视图设置灰色的解决办法:运行gpedit.msc--用户配置/计算机配置--管理 ...

  9. Android WebView useragent

    今天介绍一下Android WebView UserAgent, User-Agent(简称UA)是HTTP请求头部用来标识客户端信息的字符串, 包括操作系统, 浏览器等信息.为了建立手机客户端的信息 ...

  10. 进程和线程及Linux下的编程

    一.概述 进程和线程网络上有一堆解释,我不喜欢抄袭,也不喜欢套用太教科书的说法.就以我自己的理解来说说进程和线程吧,当然自己的理解肯定不是很严谨,但是理解起来应该会比教科书快一点.进程和线程都可以认为 ...