iT邦幫忙

DAY 9
1

30 天實戰跨平台行動APP系列 第 9

Day 9 : WebGL初探

  • 分享至 

  • xImage
  •  

截至目前為止,我們已經完成了

  • 用FB登入機制達成的使用者系統
  • 了解了怎麼使用Graph API取得FB資料

現在就是要把這些資料呈現在3D的地球上了! 我們要使用的是OpenGL這套API,

OpenGL是一套c語言的跨平台繪製2D和3D圖形的函式庫,想學習的推薦鼎鼎有名的nehe教學網站

http://nehe.gamedev.net/

或是可以購買 OpenGL SuperBible這本書來看!除了OpenGL本身之外還有OpenGL ES與WebGL

OpenGL ES (embedded system)就是嵌入式系統用的函式庫,是根據OpenGL 2.0發展而來,

WebGL又是基於OpenGL ES而發展的函式庫,所以可以說只要是OpenGL 2.0版本運行ok的程式碼,應該就可以在

OpenGL ES跟WebGL運行無誤!實際上到底可不可以只寫一次就好呢,還是要debug everywhere,可以來試試看。

準備開發環境:支援webGL的瀏覽器

因為今年已經2014了,我想這應該是沒什麼問題,我使用的作業系統是OSX 10.9.5,Safari, Chrome,Firefox都有支援

Hello World

那我們第一步當然是來做個WebGL的Hello World囉, OpenGL的Hello World通常都不是輸出文字,都只是簡單的圖形,

因為其實OpenGL要輸出文字頗麻煩的。WebGL 是 JavaScript API, 內容都寫在HTML5 的 <canvas> 標籤底下

所以第一步就是做一個canvas區域

<canvas id="main_canvas" width="500" height="300" style="background-color:white”>

Your browser does not support the HTML5 canvas element.

</canvas>

為了方便辨識,我們將網頁頁面背景設成黑色,而canvas背景顏色設為白色。

  1. getContext

當我們要在canvas標簽底下繪圖,就要先取得context,canvas context有兩種,

第一是2d,第二就是webgl 或 experimental-webgl,我有用過2d的context來做我們公司系統的文件流程圖也還算熟悉,

function initWebGL(canvas) {

  gl = null;

  try {

    // Try to grab the standard context. If it fails, fallback to experimental.

    gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

  }

  catch(e) {}

  // If we don't have a GL context, give up now

  if (!gl) {

    alert("Unable to initialize WebGL. Your browser may not support it.");

    gl = null;

  }

  return gl;

}
  1. 初始化

得到context後,就可以來進行OpenGL的一些初始設定

function init() {

  var canvas = document.getElementById("main_canvas");

  gl = initWebGL(canvas);     

  if (gl) {

    gl.clearColor(1.0, 0.0, 0.0, 1.0);                      

    gl.enable(gl.DEPTH_TEST);                              

    gl.depthFunc(gl.LEQUAL);                                

    gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);     

  }

}
window.onload = init;

我們將環境初始化為背景紅色,然後讓頁面一讀取就呼叫初始化函式,結果就是

這個樣子!代表我們初始化成功了

  1. shader 程式碼

我們必需要寫shader程式,shader有分成兩種,vertex shader跟fragment shader,

vertex shader是控制vertex的資料,fragment shader 是控制最後pixel的顏色值,先這樣理解就好

<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
void main(void) {
    gl_Position = vec4(aVertexPosition, 1.0);
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
void main(void) {
    gl_FragColor = vec4(1.0,1.0,1.0, 1.0);
}
</script>

稍微解釋一下上面兩段程式,gl_Position跟gl_FragColor是系統變數,就是最後的輸出,

而vec3 與 vec4是GLSL的變數,attribute就是我們可以從gl主程式傳送至shader程式的連結變數,

這邊的vertex shader就是接受我們船進去的vertex值,沒有做什麼變動,fragment shader就是將最後輸出的顏色都指定為白色

  1. 初始化shader

完成了程式碼後就可以初始化shader,初始化的步驟是

創建shader->連結程式碼->編譯-> 與gl程式聯結

function initShaders(){

	vertexShader = gl.createShader(gl.VERTEX_SHADER);
	fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

	var     vs_source = document.getElementById('vertex-shader').html(),
	        fs_source = document.getElementById('fragment-shader').html();

	gl.shaderSource(vertexShader, vs_source);
	gl.shaderSource(fragmentShader, fs_source);

	gl.compileShader(vertexShader);
	gl.compileShader(fragmentShader);

	glProgram = gl.createProgram();
	gl.attachShader(glProgram, vertexShader);
	gl.attachShader(glProgram, fragmentShader);

	gl.linkProgram(glProgram);
	gl.useProgram(glProgram);

}
  1. 繪圖

function drawScene(){

vertexPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
		
}

首先我們先呼叫vertex的aVertexPosition attribute,再將VBO傳送給他,
就可以繪圖了!


上一篇
Day 8 : Facebook Graph API 實作
下一篇
Day 10 Web GL Shader介紹
系列文
30 天實戰跨平台行動APP26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言