WebGL Tutorial 繪製第一個三角形

    在三維程序中,繪製第一個三角形就像寫一個“Hello World”一樣代表的寫三維程序的開始,在以往C&C++裏用OpenGL繪製一個三角化很容易,但在WebGL裏從哪裏入手呢?當然,還是先創建VertexBuffer, 然後BindBuffer後Draw一個三角面就可以,但在WebGL裏,採用了OpenGL ES2.0的接口,那又如何呢?那必須先寫好Shader纔可以,怎麼WebGL像DirectX 10&11一樣囉嗦了?但我覺得這是一個進步,用靈活的可編程Shader代替N多的GL API不是好事麼?我比較喜歡簡單的程序,相信每個優秀的程序員都喜歡。


1. 創建Shader的function

WebGL有Vertex shader和Fragment shader兩種,我們創建一個專門創建和編譯Shader的方法:

function buildShader (gl, type, string) {
  var shader;
  if (type === "fragment") {
    shader = gl.createShader(gl.FRAGMENT_SHADER);
  }
  else if (type === "vertex") {
    shader = gl.createShader(gl.VERTEX_SHADER);
  }

  gl.shaderSource(shader, string);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error(gl.getShaderInfoLog(shader));
    console.error(string);
    return null;
  }
  return shader;
}


2. 創建Program的function
有了建好的Shader,我們就可以創建和連接一個Program:

function buildProgram (gl, vertexShader, fragmentShader) {
  var program = gl.createProgram();
  var glVertexShader = buildShader(gl, "vertex", vertexShader);
  var glFragmentShader = buildShader(gl, "fragment", fragmentShader);
  gl.attachShader(program, glVertexShader);
  gl.attachShader(program, glFragmentShader);
  gl.linkProgram(program);

  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
      console.log(fragmentShader);
      console.log(vertexShader);
  }
  
  return program;
}


3. 創建一個簡單的Program對像

我們先只寫一個最簡單的Shader,不用任何頂點變化,基本上是不能再簡單了:

var vertexShader =
  'attribute vec4 vPosition;    \n\
   void main()                  \n\
   {                            \n\
      gl_Position = vPosition;  \n\
   }                            \n';
			    
var fragmentShader =
  'precision mediump float; \n\
   void main()                                  \n\
   {                                            \n\
     gl_FragColor = vec4 ( 1.0, 1.0, 0.0, 1.0 );\n\
   }\n';

然後用之前定義的buildProgram來創建Program對像:

program = buildProgram(gl, vertexShader, fragmentShader);


4. 創建VertexBuffer

 在JavaScript無法直接使用二進制數據比較麻煩,但我們可以用Float32Array來創建定點緩存然後交給WebGL,我們首先創建一個Float3dArray:

var vertices = new Float32Array(
                    [0.0, 0.5, 0.0,
                    -0.5, -0.5, 0.0,
                    0.5, -0.5, 0.0]);


然後創建WebGL VBO對像,並把頂點數據交給VBO:

vb = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);


記得從Program裏獲得"vPosition"屬性的location:

vb.vertexAttribLoc = gl.getAttribLocation(program, "vPosition");

5. 繪製三角形:

剩下的就是繪製三角形了,在之前定義的updateFrame中添加繪製代碼,首先是綁定Program:

gl.useProgram(program);


然後綁定VertexBuffer:

gl.bindBuffer(gl.ARRAY_BUFFER, vb);
gl.vertexAttribPointer(vb.vertexAttribLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vb.vertexAttribLoc);

最後繪製一個三角形:

gl.drawArrays(gl.TRIANGLES, 0, 3);


在Shader裏gl_FragColor被設置成了固定的顏色,你可以隨意改,然後只需要刷新下網頁就可以,這就是腳本語言最大的魅力,如果不要求大數據和高性能的話。


  




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章