iOS開(kāi)發(fā)-OpenGL ES入門(mén)教程4

教程

OpenGL ES入門(mén)教程1-Tutorial01-GLKit
OpenGL ES入門(mén)教程2-Tutorial02-shader入門(mén)
OpenGL ES入門(mén)教程3-Tutorial03-三維變換
這次我們用GLKit,更簡(jiǎn)單的實(shí)現(xiàn)圖形變換合搅、紋理貼圖樟插、著色睬关、深度測(cè)試(代碼在這)。

OpenGL ES系列教程在這里曙寡。
OpenGL ES系列教程的代碼地址 - 你的star和fork是我的源動(dòng)力绿店,你的意見(jiàn)能讓我走得更遠(yuǎn)。

效果展示

核心思路

使用GLKit來(lái)進(jìn)行圖形變換拖吼、紋理貼圖加載、深度測(cè)試这吻,用GLKBaseEffect來(lái)管理紋理貼圖和進(jìn)行著色吊档。

具體細(xì)節(jié)

1、頂點(diǎn)屬性

typedef NS_ENUM(GLint, GLKVertexAttrib)
{
    GLKVertexAttribPosition,
    GLKVertexAttribNormal,
    GLKVertexAttribColor,
    GLKVertexAttribTexCoord0,
    GLKVertexAttribTexCoord1
} NS_ENUM_AVAILABLE(10_8, 5_0);

GLKEffects用到的頂點(diǎn)屬性已經(jīng)定義好唾糯,使用時(shí)直接用枚舉量賦值籍铁。如下圖涡上,直接對(duì)頂點(diǎn)的位置趾断、顏色拒名、紋理坐標(biāo)進(jìn)行賦值。

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, (GLfloat *)NULL);
    //頂點(diǎn)顏色
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, 4 * 8, (GLfloat *)NULL + 3);
    
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 4 * 8, (GLfloat *)NULL + 6);

2芋酌、紋理

在自定義shader中使用紋理增显,需要用CoreGraphics把圖像轉(zhuǎn)換成bitmapdata,再申請(qǐng)紋理內(nèi)存脐帝,把圖像數(shù)據(jù)傳進(jìn)去同云,最后還要釋放bitmapdata。
在GLKit中堵腹,僅僅需要如下三行代碼炸站,就可以完成紋理的加載。

    //紋理
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"png"];
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];
    GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];

GLKTextureLoaderOriginBottomLeft 參數(shù)是避免紋理上下顛倒疚顷,原因是紋理坐標(biāo)系和世界坐標(biāo)系的原點(diǎn)不同旱易。

最后創(chuàng)建著色器,啟用紋理腿堤,把剛剛創(chuàng)建的textureInfo的name賦值給著色器阀坏。

    //著色器
    self.mEffect = [[GLKBaseEffect alloc] init];
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;

3、圖形變換

在OpenGL ES里面笆檀,圖形變換的表現(xiàn)形式就是矩陣操作忌堂,GLKit也提供了很多矩陣操作函數(shù)。

    //初始的投影
    CGSize size = self.view.bounds.size;
    float aspect = fabs(size.width / size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(90.0), aspect, 0.1f, 10.f);
    projectionMatrix = GLKMatrix4Scale(projectionMatrix, 1.0f, 1.0f, 1.0f);
    self.mEffect.transform.projectionMatrix = projectionMatrix;
    
    GLKMatrix4 modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0f, 0.0f, -2.0f);
    self.mEffect.transform.modelviewMatrix = modelViewMatrix;
    

GLKMatrix4MakePerspective是透視投影變換
GLKMatrix4Translate是平移變換

/**
 *  場(chǎng)景數(shù)據(jù)變化
 */
- (void)update {
    GLKMatrix4 modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0f, 0.0f, -2.0f);
    
    modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, self.mDegreeX);
    modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, self.mDegreeY);
    modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, self.mDegreeZ);
    
    self.mEffect.transform.modelviewMatrix = modelViewMatrix;
}

在場(chǎng)景變換函數(shù)里面酗洒,GLKMatrix4RotateY是繞Y軸旋轉(zhuǎn)士修,其他的分分別是繞X、Z軸旋轉(zhuǎn)樱衷。

4棋嘲、深度測(cè)試

在前面的教程介紹過(guò),開(kāi)啟深度測(cè)試需要分配深度測(cè)試的緩沖區(qū)箫老,并掛載到相應(yīng)的幀緩沖區(qū)封字。
在GLKit代碼中,深度測(cè)試的開(kāi)啟十分簡(jiǎn)單耍鬓。
在新建上下文時(shí)調(diào)用glEnable(GL_DEPTH_TEST);開(kāi)啟深度測(cè)試阔籽。

    //新建OpenGL ES 上下文
    self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
    GLKView* view = (GLKView *)self.view;
    view.context = self.mContext;
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    
    [EAGLContext setCurrentContext:self.mContext];
    glEnable(GL_DEPTH_TEST);
    

在渲染場(chǎng)景時(shí),glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear參數(shù)加入GL_DEPTH_BUFFER_BIT即可牲蜀。

/**
 *  渲染場(chǎng)景代碼
 */
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
    [self.mEffect prepareToDraw];
    glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0);
}

總結(jié)

OpenGL ES的入門(mén)已經(jīng)差不多笆制,后面還有很多很多知識(shí),需要時(shí)再學(xué)習(xí)即可涣达。
總結(jié)這幾篇教程花了一個(gè)星期左右在辆。
學(xué)習(xí)過(guò)程中有幾部分最難受:

  • 第一部分是OpenGL ES的頂點(diǎn)屬性证薇、紋理貼圖,對(duì)頂點(diǎn)到圖形的過(guò)程不理解匆篓,對(duì)OpenGL ES的數(shù)據(jù)緩存機(jī)制不了解浑度,無(wú)知容易使人知難而退
  • 第二部分是shader和glsl鸦概,glsl無(wú)法調(diào)試箩张、編譯信息不會(huì)查看、語(yǔ)法不懂等等窗市,一個(gè)1.0 + 1都會(huì)報(bào)錯(cuò)先慷,自己卻莫名其妙,只能通過(guò)二分注釋代碼來(lái)定位問(wèn)題咨察,特別讓人泄氣论熙;
  • 第三部分是OpenGL ES的三維圖形變換和光照等,這部分更多的是數(shù)學(xué)知識(shí)和物理知識(shí)摄狱,代碼一般都很簡(jiǎn)單脓诡;這部分比前面的都難,但是因?yàn)橹滥睦锶笔Ф叮m然不懂誉券,但是不慌,只是有點(diǎn)難受刊愚。

最后的感想踊跟,計(jì)算機(jī)圖形學(xué)和線(xiàn)性代數(shù)畢竟是基礎(chǔ),自己多花點(diǎn)時(shí)間學(xué)習(xí)鸥诽,培養(yǎng)為核心競(jìng)爭(zhēng)力非常不錯(cuò)商玫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市牡借,隨后出現(xiàn)的幾起案子拳昌,更是在濱河造成了極大的恐慌,老刑警劉巖钠龙,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炬藤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡碴里,警方通過(guò)查閱死者的電腦和手機(jī)沈矿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)咬腋,“玉大人羹膳,你說(shuō)我怎么就攤上這事「停” “怎么了陵像?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵就珠,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我醒颖,道長(zhǎng)妻怎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任图贸,我火速辦了婚禮蹂季,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疏日。我一直安慰自己,他們只是感情好撒汉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布沟优。 她就那樣靜靜地躺著,像睡著了一般睬辐。 火紅的嫁衣襯著肌膚如雪挠阁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天溯饵,我揣著相機(jī)與錄音侵俗,去河邊找鬼。 笑死丰刊,一個(gè)胖子當(dāng)著我的面吹牛隘谣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播啄巧,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寻歧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了秩仆?” 一聲冷哼從身側(cè)響起码泛,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澄耍,沒(méi)想到半個(gè)月后噪珊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡齐莲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年痢站,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铅搓。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑟押,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出星掰,到底是詐尸還是另有隱情多望,我是刑警寧澤嫩舟,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站怀偷,受9級(jí)特大地震影響家厌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜椎工,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一饭于、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧维蒙,春花似錦掰吕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至斑响,卻和暖如春菱属,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舰罚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工纽门, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人营罢。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓赏陵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親愤钾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瘟滨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容