1. 程式人生 > >《WebGL程式設計指南》---從示例程式碼中學習WebGL之初識【1】

《WebGL程式設計指南》---從示例程式碼中學習WebGL之初識【1】

寫在前面

  筆者希望學習WebGL很久了,但是鑑於種種的事一直沒有開展,恰好研究生複試過了,在這空檔時間段內想學一門新技術,於是想到了WebGL,經前同事推薦,果斷買了《WebGL程式設計指南》這本書,於是,我的學習之旅就開始了。對於程式設計人員來說,案例程式碼是最好的教科書了。即將與讀者見面的這一系列短文章是我在學習過程中的一些記錄和感想,這一系列的短文章,通過解讀書中的示例程式碼來記錄學習WebGL之旅。文章中用到的程式碼段絕大部分出自《WebGL程式設計指南》這本書,彩色的程式碼段表示下方會有相關的說明,在這期間會引用很多書中的話語,因為是引用,所以難免會有所簡略,想知道更多知識細節的讀者,建議找原書來通讀,你們也可以上書本的幫助網站

https://sites.google.com/site/webglbook/檢視相關的例子。若有讀者對此有疑問,希望你們多多與我交流和指正,我的郵箱:[email protected],謝謝大家。

簡單認識WebGL

  WebGL可以理解為Web版的OpenGL,WebGL程式在螢幕上同時使用HTML和JavaScript來建立和顯示三維圖形,此外還會用到GLSL ES(著色器程式碼)。所以說要入門WebGL,讀者最好是掌握一定的程式語言基礎,不一定是HTML、JavaScript,很多直接從C++轉過來的人也可以學得很好,此外,如果讀者有一定的圖形學基礎,那學習起來會輕鬆很多。WebGL採用HTML5中新引入的<canvas>元素(標籤),它定義了網頁上的繪圖區域。有了WebGL,JavaScript就能在canvas上面繪製三維圖形了,否則就只能繪製二維圖形。WebGL程式使用3種語言進行開發:HTML、JavaScript和GLSL ES,但是著色器程式碼GLSL ES是可以內嵌在JavaScript中的,所以WebGL網頁的檔案結構和傳統網頁一樣,只用到HTML和JavaScript兩種檔案。接下來我們會通過程式碼示例,一步步走向WebGL的殿堂。

1.初識canvas

DrawRectangle.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Draw a blue retangle</title>
</head>
<body onload="main()">
<canvas id="example" width="400" height="400">
    Please use a browser that supports "canvas"
</canvas>
<script src="DrawRectangle.js"> </script> </body> </html>

<body onload="main()"></body>

在這行程式碼中,<body>標籤指定onload屬性,main()函式作為JavaScript程式的入口,然後讓瀏覽器載入JavaScript檔案,而main()函式在JavaScript檔案中定義。使用如下語句來載入js檔案:

<script src="DrawRetangle.js"></script>

HTML檔案中引入了<canvas>標籤,允許JavaScript動態地繪製圖形。<canvas>元素提供一些簡單的繪製函式,用來繪製點、線、矩形、圓等等。

<canvas id="example" width="400" height="400"></canvas>

在這行程式碼中,id屬性為<canvas>指定了唯一的識別符號,在對應的JavaScript檔案中會用到這個id,width和height屬性規定了它的區域,比如,上面表示400x400畫素的區域。預設的<canvas>是透明的,如果不通過JavaScript程式碼畫東西,<canvas>一般不可見。使用<canvas>要求瀏覽器支援<canvas>,但有些老的瀏覽器就不支援,此時會忽略此行程式碼。所以可以在標籤中加入一行程式碼,用於提醒。如下所示:

<canvas id="example" width="400" height="400">

Please use a browser that supports "canvas"

</canvas>

DrawRectangle.js

function main() {
    var canvas=document.getElementById('example');
    if(!canvas){
        console.log('Failed to retrieve the <canvas> element');
        return;
    }

    var ctx=canvas.getContext('2d');
    if(!ctx){
        console.log('Failed to retrieve the <ctx> context');
        return;
    }
    ctx.fillStyle='rgba(0,0,255,1.0)';
    ctx.fillRect(120,10,150,150);
}

在上面的程式碼中,作為HTML檔案中<body>元素中的onload屬性值的main()函式,完成了在<canvas>上繪製藍色矩陣的三步:

<1>獲取<canvas>元素;

var canvas=document.getElementById('example');

if(!canvas){console.log('Failed to retrieve the <canvas> element');return;}

上述程式碼獲取獲取<canvas>元素並做錯誤判斷,在專案中執行此步是一個很好的程式設計習慣,特別是寫一些底層程式碼的時候,這一步很重要,對於排查程式錯誤點很有幫助。

<2>向該元素請求二維“圖形的上下文”;

var ctx=canvas.getContext('2d');

if(!ctx){console.log('Failed to retrieve the <ctx> context');return;}

上述的程式碼向<canvas>元素請求二維“圖形的上下文”,canvas.getContext()方法的引數指定上下文的型別(2d的還是3d的)。

注:若是三維圖形,就要獲取三維“圖形的上下文”。

<3>在圖形的上下文”上呼叫相應的繪圖函式繪製圖形

ctx.fillStyle='rgba(0,0,255,1.0)';

此行程式碼設定了填充顏色為藍色,也可以根據自己的喜好修改rgba()的前3個引數來改變顏色,rbga()指定了r(紅)、g(綠)、b(藍)、a(alpha:透明度),前三者的範圍是0-255,最後一個的範圍是0.0-1.0,這種顏色格式為RGBA格式。

ctx.fillRect(120,10,150,150);

此行程式碼使用ctx.fillRect()函式來繪製矩形,它的引數決定了矩形在<canvas>中的位置和寬高,前兩個引數指定矩形的左上頂點在<canvas>的座標,後兩個引數決定寬和高

注:<canvas>的座標系統原點在螢幕左上方,以橫軸為x軸(正方向朝右),縱軸為y軸(正方向朝下),均以畫素為單位。

執行HTML檔案,我們在網頁上得到如下的顯示:


2.最簡單的WebGL程式

這個程式的功能就是用背景色清空(填充)了<canvas>標籤的繪圖區。在寫這個程式之前,讀者可以到網上先下載好相關的WebGL通用函式庫。

HelloCanvas.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Clear canvas</title>
</head>
<body onload="main()">
<canvas id="webgl" width="400" height="400">
    Please use a browser that supports "canvas"
</canvas>
<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>
<script src="lib/cuon-utils.js"></script>
<script src="HelloCanvas.js"></script>
</body>
</html>

<canvas id="webgl" width="400" height="400">

Please use a browser that supports "canvas"

</canvas>

在上面的程式碼中,<canvas>標籤的id設為了webgl,在對應的JavaScript檔案中可以通過id來獲取到<canvas>。

<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>

<script src="lib/cuon-utils.js"></script>

上面的程式碼引入一些專門為WebGL準備的、事先定義好的函式庫。在示例專案中,將函式庫的資料夾放在了與HTML和JavaScript檔案的同一目錄下src路徑是相對路徑

HelloCanvas.js

function main() {
    var canvas=document.getElementById('webgl');
    if(!canvas){
        console.log('Failed to retrieve the <canvas> element');
        return;
    }

    var gl=getWebGLContext(canvas);
    if(!gl){
        console.log('Failed to get the rendering context for WebGL');
        return;
    }
    gl.clearColor(0.0,0.0,0.0,1.0);

    gl.clear(gl.COLOR_BUFFER_BIT);
}

在這個檔案中,開始真正使用WebGL來繪製三維圖形。它依然遵循著上面示例程式碼的三個步驟:

<1>獲取<canvas>元素;

與HTML 檔案對應,document.getElementById()函式的引數變為了webgl字串。

<2>獲取繪圖上下文;

var gl=getWebGLContext(canvas);
    if(!gl){
        console.log('Failed to get the rendering context for WebGL');
        return;

    }

在上面的程式碼中,一般來說,要用canvas.getContext()函式來獲取繪圖上下文,但是在獲取WebGL的繪圖上下文的時候,canvas.getContext()函式接收的引數在不同的瀏覽器中會有所不同,所以書本的作者寫了一個函式getWebGLContext()來隱藏不同瀏覽器之間的差異,傳入的引數是<canvas>元素。它被定義在cuon-utils.js檔案中,可以通過該js檔案檢視該函式的規範原型。此時,三維的繪圖上下文就儲存在了gl這個變數中。

<3>進行繪圖,包括設定背景色和清空<canvas>;

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

學過OpenGL的讀者可能會對這兩行程式碼感到熟悉,沒錯,它們對應的就是OpenGL或者OpenGL ES 2.0的glClearColor()和glClear()函式。gl.clearColor()負責清空背景色,以RGBA格式來設定背景色,一旦指定背景色後,在下一次呼叫gl.clearColor()方法前背景色都不會改變;gl.clear()負責用之前指定的背景色清空<canvas>,gl.clear()的引數是緩衝區,緩衝區有深度緩衝區DEPTH_BUFFER_BIT(對應gl.clearDepth(),引數預設值為1.0)、顏色緩衝區COLOR_BUFFER_BIT(對應gl.clearColor(),引數預設值為(0.0,0.0,0.0,0.0))和模板緩衝區STENCIL_BUFFER_BIT(對應gl.clearStencil(),引數預設值為0)。在本示例程式碼中是清空背景色,我們可以隨意更改gl.clearColor()的引數來變換<canvas>背景色。

示例程式碼效果如圖所示:


好了,這一節就只有這麼多。Have a good day!

相關推薦

WebGL程式設計指南》---示例程式碼學習WebGL初識1

寫在前面  筆者希望學習WebGL很久了,但是鑑於種種的事一直沒有開展,恰好研究生複試過了,在這空檔時間段內想學一門新技術,於是想到了WebGL,經前同事推薦,果斷買了《WebGL程式設計指南》這本書,於是,我的學習之旅就開始了。對於程式設計人員來說,案例程式碼是最好的教科書

Netty 零到一學習系列初識

由於專案開發中需要用的網路通訊,就研究了一下Netty的使用方法、原理及原始碼。現在總結學習新的及經驗分享給大家。 一、為什麼不選擇Java原生的NIO        在JDK1.4版本中已經引入了NIO,NIO彌補了原來同步阻塞I/O的不足,它在Java程式碼中提供了高

機器學習-常見問題積累1

屬性。 積累 兩種 所在 哪些 異常 缺失值 問題 推導 1、python和R在做數據分析時各有自己得擅長得領域,如python做時域分析得難度就遠遠比R大,因為R有非常成熟得Package! 2、數據處理:如何處理缺失數據?各種處理方法得的利弊? 3、數據處理:如何將類別

Linux學習命令1

active acc 同時 計算機 用戶名 幫助 理解 否則 解釋 Linux學習之命令【1】 一·命令總覽?????? 1.基本簡單命令??????? ?1.0 pwd1.1 echo ?????????1.2 dat

利用 Python學習資料探勘1

覆蓋使用Python進行資料探勘查詢和描述資料結構模式的實踐工具。 第一節 介紹 資料探勘是一個隱式提取以前未知的潛在有用的資料資訊提取方式。它使用廣泛,並且是眾多應用的技術基礎。 本文介紹那些使用Python資料探勘實踐用於發現和描述結構模式資料的工具。近些年來,Python在

openCV學習1---VS2017+openCV3.4.1配置教程

我先安裝“VS2017”,後使用的vs2017自帶了包管理外掛NuGet,安裝的"opencv",而後出現了各種錯誤,再調節後,放棄了, 而後參考(2)安裝“opencv”後,出現了一下這個錯誤: 錯誤LNK1112模組計算機型別“x64”與目標計算機型別“x86

禁止在堆例項化的類1

    設計一個禁止在堆中例項化的類,需要過載operator new和operator delete,並將其設為private。當然,也不是沒有破解的方法,那就是placement new。 // 禁止在堆中例項化物件? // 在堆中例項化物件,需要使用new和dele

Qt學習1:QT顯示中文問題

最近,公司專案的GUI介面使用的是Qt,研究了近兩個月的Qt發現中文顯示確實是一個問題,這個問題中主要存在兩方面的問題: 【1】中文顯示; 【2】中文亂碼; 其中【1】問題出現的情景是:Qt的

ZooKeeper學習配置1基本配置

本文開始陸續的詳細講解所有的配置選項,大部分配置項一般都有一個預設的值,很多都應該根據實際情況進行優化。因為ZooKeeper的設計很容易使用,有一些在不明白具體的配置項就開始使用,一開始工作得還好,但後續很可能會出問題。所以你需要花些時間來深入學習配置項,你會發現你將可以得到更好的效能,並能更容易的診斷問

筆記WebGL程式設計指南學習-第4章高階變換與動畫基礎(1-平移然後旋轉))

目標:實現三角形的 先旋轉再平移 結果: 本節要使用一個專為本書編寫的矩陣函式庫。有了矩陣函式庫,進行如“平移,然後旋轉”這種複合的變換就很簡單了。 矩陣變換庫:cuon-matrix.js 在 OpenGL 中,我們無需手動指定變換矩陣的每

Linux核心程式碼學習獲得結構體成員偏移量的方法

作者:阿波(幾年前的一篇文章,翻出來共享一下。)Content0. 引子1.舉例(1) 程式碼(2) 檢查結果(3) 為什麼從0開始?(4) 從非0地址開始的結果2.小結0. 引子在linux-2.26

別人的程式碼學習golang系列--01

自己最近在思考一個問題,如何讓自己的程式碼質量逐漸提高,於是想到整理這個系列,通過閱讀別人的程式碼,從別人的程式碼中學習,來逐漸提高自己的程式碼質量。本篇是這個系列的第一篇,我也不知道自己會寫多少篇,但是希望自己能堅持下去。 第一個自己學習的原始碼是:https://github.com/LyricTi

別人的程式碼學習golang系列--02

這篇部落格還是整理從https://github.com/LyricTian/gin-admin 這個專案中學習的golang相關知識 作者在專案中使用了https://github.com/google/wire 做依賴注入,這個庫我之前沒有使用過,看了作者程式碼中的使用,至少剛開始是看著優點懵,不知道是

別人的程式碼學習golang系列--03

這篇部落格還是整理從https://github.com/LyricTian/gin-admin 這個專案中學習的golang相關知識。 作者在專案中使用了 `github.com/casbin/casbin` 進行許可權控制的,這個庫自己之前也沒有用過,正好可以通過這個專案學習一下使用。 當然這篇部落格並

實例學習grid布局

{} 簡單 mic 通過 目前 例子 get www. pre 對於Web開發者來說,網頁布局一直是個比較重要的問題。 Web 布局主要經歷了以下四個階段:   1、table表格布局;   2、float浮動及position定位布局;   3、flex彈性盒模型布局,革

貝葉斯網(2)Netica:數據學習CPT

指向 搭建 上一個 劃分 認知 圖劃分 4.0 ont 再次 1. 離散節點 在官方Tutorial中是有詳細的案例的,就是B篇3.3節,你可以動手把天氣預報這個實現一下: http://www.norsys.com/tutorials/netica/secB/tut_B3

python程式設計入門到實踐學習筆記-Django開發使用者賬戶(一)

讓使用者能夠輸入資料(表單) 在建立使用者賬戶身份驗證系統之前,先新增幾個頁面,讓使用者能偶輸入資料。新增新主題、新增新條目以及編輯既有條目。 新增新主題 1.用於新增主題的表單 建立一個forms.py檔案與models.py放在同一目錄下。 from django import

python程式設計入門到實踐學習筆記-Django入門(四)

建立其他網頁 我們接下來擴充“學習筆記”專案,建立兩個顯示資料的網頁,其中一個列出所有的主題,另一個顯示特定主題的所有條目。 模板繼承 編寫一個包含通用元素的父模板,並讓每個網頁都繼承這個模板,而不必在每個網頁中重複定義這些通用元素。這樣我們可以專注於開發每個網頁的獨特部分。1.父模板

python程式設計入門到實踐學習筆記-Django入門(二)

建立網頁:學習筆記主頁 使用django建立網頁通常分三個階段:定義URL、編寫檢視和編寫模板。 首先必須定義URL模式,其描述了URL是如何設計的,讓django知道如何將瀏覽器請求與網站URL匹配,以確定返回哪個網頁。每個URL都被對映到特定的檢視——檢視函式獲取並處理網頁所需的資料。檢視函

python程式設計入門到實踐學習筆記Django入門(一)

  建立應用程式 django專案由一系列應用程式組成,他們協同工作,讓專案稱謂一個整體。首先我們執行命令python manage.py startapp learning_logs。     定義模型 開啟剛剛我們建立的資料夾,並修改mod