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。

相關文章
相關標籤/搜索