Professional.WebGL.Programming-Chapter 2(高级WebGL编程——第二章)

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

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

 

 

建立一个基本的WebGL应用须要如下的步骤:java

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

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

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.ide

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.webgl

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值,使用数组来存放这两个值,而后进行遍历,获得如下代码:

 1 var names = ["webgl", "experimental-webgl"];
 2 
 3 var context = null;
 4 
 5 for (var i=0; i < names.length; i++) {
 6 
 7     try {
 8 
 9         context = canvas.getContext(names[i]);
10 
11     } catch(e) {}
12 
13     if (context) {
14 
15     break;
16 
17     }
18 }

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

 1   var vertexShaderSource = 
 2         "attribute vec3 aVertexPosition;              \n" +
 3         "void main() {                                \n" +
 4         "  gl_Position = vec4(aVertexPosition, 1.0);  \n" +
 5         "}                                            \n";           
 6    
 7     var fragmentShaderSource = 
 8         "precision mediump float;                    \n"+
 9         "void main() {                               \n"+
10         "  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);  \n"+
11         "}                                           \n";
12      
13     var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
14     var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
15   
16     shaderProgram = gl.createProgram();
17     gl.attachShader(shaderProgram, vertexShader);
18     gl.attachShader(shaderProgram, fragmentShader);
19     gl.linkProgram(shaderProgram);
20  
21     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
22       alert("Failed to setup shaders");
23     }
24  
25     gl.useProgram(shaderProgram);
26   
27     shaderProgram.vertexPositionAttribute = 
28     gl.getAttribLocation(shaderProgram, "aVertexPosition");         
 1   var shader = gl.createShader(type);
 2       gl.shaderSource(shader, shaderSource);
 3       gl.compileShader(shader);
 4   
 5   if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
 6       alert("Error compiling shader" + gl.getShaderInfoLog(shader));
 7       gl.deleteShader(shader);   
 8       return null;
 9   }
10   return shader;  

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

 1   vertexBuffer = gl.createBuffer();
 2   gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
 3   var triangleVertices = [
 4          0.0,  0.5,  0.0,
 5         -0.5, -0.5,  0.0,
 6          0.5, -0.5,  0.0
 7   ];
 8   gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices),
 9   gl.STATIC_DRAW);
10   vertexBuffer.itemSize = 3;
11   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。

相关文章
相关标签/搜索