為了更方便的進行頂點資料的管理,我建立了乙個glgeometry
類。
typedef enum : nsuinteger glgeometrytype;
typedef struct glvertex;
@inte***ce glgeometry
() @property (strong, nonatomic) nsmutabledata *vertexdata;
@end
@implementation glgeometry
- (instancetype)initwithgeometrytype:(glgeometrytype)geometrytype
return self;
}- (void)dealloc
} void * pvertex = (void *)(&vertex);
nsuinteger size = sizeof(glvertex);
}- (gluint)getvbo
return vbo;
}- (int)vertexcount
複製**
如果我們有乙個紙質的圓柱體模型,我們可以把它剪開成兩個圓形和乙個矩形。
所以我們可以將圓柱體看做三個幾何體來繪製,繪製兩個圓形和乙個卷成桶狀的矩形。我們將圓形半徑定義為radius
,矩形高為height
,寬既是圓形的周長。
下面繪製的**在可以採取多邊形逼近的方式繪製圓形,比如我們可以構建乙個正36邊形來表示乙個圓。本文的**就是利用這個原理來繪製圓的。定義構成圓形的邊數為cylinder
類中,cylinder
繼承自globject
。
sidecount
。
- (glgeometry *)topcircle
}return _topcircle;
}複製**
上面是cylinder.m
中的**,用來構建圓柱體上方的圓形。構建圓形是我使用的是********fan,可以大大減少繪製需要的頂點數。首先新增圓心的頂點,然後圍繞中心頂點,依次加入邊上的頂點。上面的法線都是朝上的,既(0, 1, 0)
。uv和頂點的取值如下圖所示。
圖示為5條邊的情況演示,第n條邊的angle等於2 * pi * n / sidecount
,因為sin函式的範圍是-1到1,所以使用(sin(angle) + 1 ) / 2.0
就可以得到0~1的uv範圍。
下方的圓形和上方主要的區別就是y軸的位置和法線,它位於-height/2
處,法線向下。上方的圓形處於height/2
處,法線向上。
- (glgeometry *)bottomcircle
}return _bottomcircle;
}複製**
細心的讀者可能還會發現,迴圈的順序也不一樣,上面是for (int i = self.sidecount; i >= 0; --i)
,下面是for (int i = 0; i <= self.sidecount; ++i)
。為什麼要這樣呢?因為我開啟了剔除表面,glenable(gl_cull_face);
,並且剔除的是背面glcullface(gl_back);
。剔除背面就意味著背面將不會被渲染,只有正面面向攝像機的時候我們才能看到它被渲染。那麼opengl如何判斷正面還是背面呢?
- (void)draw:(glcontext *)glcontext
複製**
預設情況下,投影到螢幕後頂點順序為逆時針的面為正面。
圖中右邊的是逆時針,所以如果使用了cull face,我們只能看見右邊的面。當然你也可以使用void glfrontface(glenum mode);
將順時針改為正面。
因為我需要頂部圓形的上面一側顯示,所以必須保證從上往下看時,組成三角形的頂點順序是逆時針的。底部的圓形則相反,從下往上看時,需要保證組成三角形的頂點順序是逆時針的。
中間的矩形可以使用三角帶來繪製。
- (glgeometry *)middlecylinder
}return _middlecylinder;
}複製**
可以把它看做self.sidecount
個矩形組成的幾何體。只需要按照下圖方向依次追加頂點即可。
注意新增頂點時候我使用的是從0到2pi的方向,正如上圖所示,這樣才能保證頂點順序是逆時針的。uv直接使用頂點在寬高上的比例即可。
有了這三個幾何體,就可以組合成乙個圓柱體了。下面是繪製**。
- (void)draw:(glcontext *)glcontext
複製**
和之前唯一不同的是[glcontext drawgeometry:self.topcircle];
方法,這個是新增的用於繪製glgeometry
的方法。實現如下:
- (void)drawgeometry:(glgeometry *)geometry else
if (geometry.geometrytype == glgeometrytype********s) else
if (geometry.geometrytype == glgeometrytype********strip)
}複製**
主要就是根據不同的geometrytype
繪製vbo,很好理解。最後回到viewcontroller
,利用三個圓柱體組裝個錘子吧。
- (void)createcylinder
複製**
最終效果圖如下。 學習OpenGL ES之繪製地形
地形模型一般是由nxn的網格構成,網格的點在y軸上的座標由灰度地形圖上相應的顏色決定。顏色越亮,高度越高。顏色每個通道的取值範圍可以是0 255,通過公式轉換,可以很容易的控制生成模型的高度。上篇文章中,我們使用三角帶生成圓柱體的中間部分。現在我們要用多個三角帶來生成地形。如何生成單個三角帶我就不贅...
OPENGL ES之繪製金字塔
今天比照著教材畫了乙個金字塔,這個案例主要涉及到了圖形變換矩陣的使用。但是其中遇到了一些問題不甚明了,在我自己的 中,我設定了view.drawabledepth glkviewdrawabledepth16,結果繪製出來的圖案給人的感覺是從三角形底部看去的,把設定繪製深度的 注釋掉,則我的 的表現...
opengles繪製點精靈
什麼是點精靈 opengl圖形由頂點構成,所謂點精靈就是對點進行紋理對映,簡單說就是把一副紋理貼在乙個點上 原來4個頂點構成乙個矩形,現在乙個頂點就完成了,典型的如粒子效果,雲霧,水流火花都可以用點精靈來實現 這樣減少了3個頂點的計算,效率很高。下面看例子 我們把 shader實現 virtual ...