從零開始學習OpenGL ES之一 基本概念

2021-05-27 21:52:00 字數 2812 閱讀 3689

我曾寫過一些文章介紹iphone opengl es程式設計,但大部分針對的是已經至少懂得一些3d程式設計知識的人。

已經有大量有關opengl的好教程和書籍。但是,卻沒有多少是關於opengl es,而且沒有(至少在我撰寫此文時)是專門針對學習iphone上3d程式設計的。因為大部分有關學習opengl的材料是從所謂「直接模式(direct mode)」開始的,而opengl es並不支援此模式,對於沒有3d背景知識的iphone開發者而言,使用現有的書籍和教程是十分困難的。為滿足一些開發者的要求,我決定撰寫乙個針對3d初學者的博文系列。這是此系列的第一篇文章。

首先我們要討論的是opengl的資料型別。因為opengl是乙個跨平台的api,資料型別的大小會隨使用的程式語言以及處理器(64位,32位,16位)等的不同而不同,所以opengl定義了自己的資料型別。當傳遞資料到opengl時,你應該堅持使用這些opengl的資料型別,從而保證傳遞資料的尺寸和精度正確。不這樣做的後果是可能會導致無法預料的結果或由於執行時的資料轉換造成效率低下。不論平台或語言實現的opengl都採用這種方式定義資料型別以保證在各平台上資料的尺寸一致,並使平台間opengl**移植更為容易。

下面是opengl的各種資料型別:

opengl es (至少iphone目前所使用的版本)不支援8位元組(64位)資料型別,如long或double。opengl 其實具有這些大型資料型別,但考慮到大部分嵌入式裝置螢幕尺寸以及可能為它們所寫的程式型別而且使用它們有可能對效能造成不利的影響,最後的決定是在opengl es中排除這些資料型別。

3d影象的最小單位稱為點(point)或者頂點vertex。它們代表三維空間中的乙個點並用來建造更複雜的物體。多邊形就是由點構成,而物體是由多個多邊形組成。儘管通常opengl支援多種多邊形,但opengl es只支援三邊形(即三角形)。

如果你回憶高中學過的幾何學,你可能會記得所謂笛卡爾座標。 基本概念是在空間中任選一點,稱作原點。 然後你可以通過參照原點並使用****三維的數值指定空間中的任意一點,座標是由三個想象的通過原點線表示的。從左至右的想象直線叫x-軸。沿著x-軸從左至右數值變大,向左移動數值變小。原點左方x為負值,右邊為正值。另外兩軸同理。沿y軸向上,y值增加,向下y值減小。原點上方y為正,原點下方為負。對於z軸,當物體離開觀察者,數值變小,向觀察者移動(或超出觀察者),數值變大。原點前方z值為正,原點之後為負。下圖幫助說明了這一點:

note:iphone上另一種繪圖框架core graphics使用了稍微不同的座標系統,當向螢幕上方移動時y值減小,而向下移動y值增加。

沿各軸增加或減小的數值是以任意刻度進行的 – 它們不代表任何真實單位,如英呎,英吋或公尺等。你可以選擇任何對你的程式有意義的刻度。如果你想設計的遊戲以英呎為單位,你可以那樣做。如果你希望單位為公釐,同樣可行。opengl不管它對終端使用者代表什麼,只是將它作為單位處理,保證它們具有相同的距離。

由於任何物體在三維空間中的方位可以由三個數值表示,物體的位置通常在opengl中由使用乙個三維陣列的三個glfloat變數表示,陣列中的第一項(索引0)為x位置,第二項(索引1)為y位置,第三項(索引2)為z位置。下面是乙個建立opengl es頂點的簡單例子:

glfloat vertex[3];

vertex[0] = 10.0; // x

vertex[1] = 23.75; // y

vertex[2] = -12.532; // z

處理所有這些glfloat是很痛苦的事情。幸運的是,有乙個容易的方法。我們可以定義乙個資料結構了儲存多個頂點,像這樣:

typedef struct  vertex3d;
通過這樣做,我們的**可讀性更強:

vertex3d vertex;

vertex.x = 10.0;

vertex.y = 23.75;

vertex.z = -12.532;

static inline vertex3d vertex3dmake(cgfloat inx, cgfloat iny, cgfloat inz)

如果你回憶起幾何學(如果不記得也不要緊)的內容,你會知道空間中兩點間的距離是使用下面公式計算的:

我們可以在乙個簡單的內聯函式中實現這個公式來計算三維空間中任何兩點間的直線距離:

static inline glfloat vertex3dcalculatedistancebetweenvertices (vertex3d first, vertex3d second)

;

由於opengl es僅支援三角形,因此我們可以通過建立乙個資料結構將三個頂點組合成乙個三角形物體。

typedef struct  ********3d;
乙個 ********3d實際上與乙個九個glfloat構成的陣列是完全一樣的,因為我們通過頂點和三角形而不是glfloat陣列來構建物體,所以它能幫助我們更容易地處理我們的**。

然而關於三角形你需要知道更多的事情。在opengl中有乙個概念叫捲繞(winding), 它表示頂點繪製的次序是重要的。不像真實世界中的物體,opengl中的多邊形通常都不會有兩面。它們只有一面,被當做front face(前面),三角形只有其front face面對觀察者時才可見。可以設定opengl將多邊形作為兩面處理,但預設狀態下,三角形只有乙個可見面。通過知道哪乙個面是多邊形的前面或可見面,才能使opengl只做一半的計算。

上圖中,左邊青色的三角形是backface,因此將不可見。而右方的三角形是frontface,所以將被繪製。

OPENGL ES 從零開始系列

opengl es for iphone drawing a circle part1 circle part i.html part2 circle part ii.html part3 ircle part iii.html opengl es 從零開始系列 1.從零開始學習opengl es之...

從零開始學習react

react.createlement tag,content class shoppinglist extends react.component return 我們可以把兩者結合起來,使 react 的 state 成為 唯一資料來源 渲染表單的 react 元件還控制著使用者輸入過程中表單發生的...

C 從零開始學習

首先你需要乙個編譯器,在這裡我首先是推薦功能強大的visual studio最強ide。vs 可以嘗試自己在ide裡面敲一下,畢竟只有多動手才能成功!include 此為標頭檔案 using namespace std 告訴編譯器使用 std 命名空間。main方法為主函式,是程式開始執行的地方 i...