學習OpenGL ES之繪製圓柱體

2021-09-11 14:11:27 字數 3032 閱讀 2056

為了更方便的進行頂點資料的管理,我建立了乙個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,寬既是圓形的周長。

下面繪製的**在cylinder類中,cylinder繼承自globject

可以採取多邊形逼近的方式繪製圓形,比如我們可以構建乙個正36邊形來表示乙個圓。本文的**就是利用這個原理來繪製圓的。定義構成圓形的邊數為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 ...