版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.07.22 |
前言
OpenGL 圖形庫(kù)項(xiàng)目中一直也沒(méi)用過(guò),最近也想學(xué)著使用這個(gè)圖形庫(kù)蚂子,感覺(jué)還是很有意思萌庆,也就自然想著好好的總結(jié)一下。首先要給大家介紹個(gè)學(xué)習(xí)網(wǎng)站。
1. 歡迎來(lái)到OpenGL的世界
2.系列教程
3.教程代碼
4.落影簡(jiǎn)書(shū)
OpenGL ES基礎(chǔ)
OpenGL ES
是一套多功能開(kāi)放標(biāo)準(zhǔn)的用于嵌入系統(tǒng)的C-based
的圖形庫(kù)辨图,用于2D
和3D
數(shù)據(jù)的可視化班套。OpenGL
被設(shè)計(jì)用來(lái)轉(zhuǎn)換一組圖形調(diào)用功能到底層圖形硬件(GPU)
,由GPU
執(zhí)行圖形命令故河,用來(lái)實(shí)現(xiàn)復(fù)雜的圖形操作和運(yùn)算吱韭,從而能夠高性能、高幀率利用GPU
提供的2D
和3D
繪制能力鱼的。
OpenGL ES
規(guī)范本身不定義繪制表面和繪制窗口理盆,因此ios為了使用它必須提供和創(chuàng)建一個(gè)OpenGL ES
的呈現(xiàn)環(huán)境,創(chuàng)建和配置存儲(chǔ)繪制命令結(jié)果的framebuffer
及創(chuàng)建和配置一個(gè)或多個(gè)呈現(xiàn)目標(biāo)凑阶。在 iOS中使用EAGL
提供的EAGLContext
類 來(lái)實(shí)現(xiàn)和提供一個(gè)呈現(xiàn)環(huán)境猿规,用來(lái)保持OpenGLES
使用到的硬件狀態(tài)。 EAGL
是一個(gè)Objective-C API
宙橱,提供使OpenGL ES
與Core Animation
和UIKIT
集成的接口坎拐。
在調(diào)用任何OpenGL ES
功能之前必須首先初始化一個(gè)EAGLContext
對(duì)象。每一個(gè)iOS應(yīng)用的每一個(gè)線程都有一個(gè)當(dāng)前context
养匈,在調(diào)用OpenGLES
函數(shù)時(shí)哼勇,使用或改變此context
中的狀態(tài)。EAGLContext
的類方法setCurrentContext:
用來(lái)設(shè)置當(dāng)前線程的當(dāng)前context
呕乎。EAGLContext
的類方法currentContext
返回當(dāng)前線程的當(dāng)前context
积担。在切換相同線程的兩個(gè)上下文之前,必須調(diào)用glFlush
函數(shù)來(lái)確保先前已提交的命令被提交到圖形硬件中猬仁。
可以采用不同的方式使用OpenGL ES
以便呈現(xiàn)OpenGL ES
內(nèi)容到不同的目標(biāo):GLKit
和CAEAGLLayer
帝璧。為了創(chuàng)建全屏幕的視圖或使OpenGL ES
內(nèi)容與UIKit
視圖集成,可以使用GLKit
湿刽。在使用GLKit
時(shí)的烁,GLKit
提供的類GLKView
類本身實(shí)現(xiàn)呈現(xiàn)目標(biāo)及創(chuàng)建和維護(hù)一個(gè)framebuffer
。
為了使OpenGL ES
內(nèi)容作為一個(gè)Core Animation
層的部分內(nèi)容時(shí)诈闺,可以使用CAEAGLLayer
作為呈現(xiàn)目標(biāo)渴庆,并需要另外創(chuàng)建framebuffer
以及自己實(shí)現(xiàn)和控制整個(gè)繪制流程。
GLKit
是一組objective-c
類雅镊,為使用OpenGL ES
提供一個(gè)面向?qū)ο蠼涌诮罄祝脕?lái)簡(jiǎn)化OpenGL ES
應(yīng)用的開(kāi)發(fā)。GLKit
支持四個(gè)3D
應(yīng)用開(kāi)發(fā)的關(guān)鍵領(lǐng)域:
-
GLKView
和GLKViewController
類提供一個(gè)標(biāo)準(zhǔn)的OpenGL ES
視圖和相關(guān)聯(lián)的呈現(xiàn)循環(huán)仁烹。GLKView
可以作為OpenGL ES
內(nèi)容的呈現(xiàn)目標(biāo)耸弄,GLKViewController
提供內(nèi)容呈現(xiàn)的控制和動(dòng)畫(huà)。視圖管理和維護(hù)一個(gè)framebuffer
卓缰,應(yīng)用只需在framebuffer
進(jìn)行繪畫(huà)即可计呈。 -
GLKTextureLoader
為應(yīng)用提供從iOS支持的各種圖像格式的源自動(dòng)加載紋理圖像到OpenGL ES
圖像環(huán)境的方式砰诵,并能夠進(jìn)行適當(dāng)?shù)霓D(zhuǎn)換,并支持同步和異步加載方式捌显。 - 數(shù)學(xué)運(yùn)算庫(kù)胧砰,提供向量、矩陣苇瓣、四元數(shù)的實(shí)現(xiàn)和矩陣堆棧操作等
OpenGL ES 1.1
功能。 -
Effect
效果類提供標(biāo)準(zhǔn)的公共著色效果的實(shí)現(xiàn)偿乖。能夠配置效果和相關(guān)的頂點(diǎn)數(shù)據(jù)击罪,然后創(chuàng)建和加載適當(dāng)?shù)闹鳌?code>GLKit 包括三個(gè)可配置著色效果類:GLKBaseEffect
實(shí)現(xiàn)OpenGL ES 1.1
規(guī)范中的關(guān)鍵的燈光和材料模式,GLKSkyboxEffect
提供一個(gè)skybox
效果的實(shí)現(xiàn)贪薪,GLKReflectionMapEffect
在GLKBaseEffect
基礎(chǔ)上包括反射映射支持媳禁。
GLKView和OpenGL ES繪制過(guò)程
使用GLKView和OpenGLES進(jìn)行繪制過(guò)程:
創(chuàng)建一個(gè)
GLKView
對(duì)象。
GLKView
對(duì)象可以編程或使用Interface Builder
來(lái)創(chuàng)建和配置画切。在采用編程方式時(shí)竣稽,首先創(chuàng)建一個(gè)context
然后調(diào)用initWithFrame:context:
方法。使用Interface Builder
方式時(shí)霍弹,在從storyboard
加載一個(gè)GLKView
后毫别,創(chuàng)建一個(gè)context
和設(shè)置它作為視圖的context
屬性。在iOS
中GLKit
的使用需要?jiǎng)?chuàng)建OpenGL ES 2.0
以上的圖形環(huán)境context
典格。GLKit
視圖自動(dòng)創(chuàng)建和配置它所有的OpenGLES framebuffer
對(duì)象和renderbuffers
岛宦,可以通過(guò)修改視圖的drawable
屬性來(lái)控制這些對(duì)象的屬性。-
繪制
OpenGL
內(nèi)容(發(fā)布繪制命令)
使用GLKit
視圖繪制OpenGL
內(nèi)容需要三個(gè)子步驟:- 準(zhǔn)備
OpenGL ES
基礎(chǔ)耍缴; - 發(fā)布繪制命令砾肺;
- 呈現(xiàn)顯示內(nèi)容到
Core Animation
。
- 準(zhǔn)備
GLKit
類本身已經(jīng)實(shí)現(xiàn)了第一個(gè)和第三個(gè)步驟防嗡,用戶只需實(shí)現(xiàn)第二個(gè)步驟变汪,在視圖的方法drawRect
或視圖的代理對(duì)象的glkView:drawInRect:
中調(diào)用適當(dāng)?shù)?code>OpenGL ES繪制命令進(jìn)行內(nèi)容繪制。GLKViewController
類維護(hù)一個(gè)animation
呈現(xiàn)循環(huán)(包含兩個(gè)方法update
和display
)蚁趁,用來(lái)實(shí)現(xiàn)連續(xù)的動(dòng)畫(huà)復(fù)雜的場(chǎng)景裙盾。animation
呈現(xiàn)循環(huán)的交替速率由GLKViewController
的屬性framesPerSecond
指示,并使用preferredFramesPerSecond
屬性來(lái)修改它他嫡。
OpenGL ES版本
iOS
系統(tǒng)默認(rèn)支持OpenGl ES1.0
闷煤、ES2.0
以及ES3.0
3個(gè)版本,三者之間并不是簡(jiǎn)單的版本升級(jí)涮瞻,設(shè)計(jì)理念甚至完全不同鲤拿,在開(kāi)發(fā)OpenGL
項(xiàng)目前,需要根據(jù)業(yè)務(wù)需求選擇合適的版本署咽。在學(xué)習(xí)OpenGL
代碼的時(shí)候也需要知道它對(duì)應(yīng)著哪個(gè)版本近顷,在ES1
中執(zhí)行ES2
代碼是看不到任何效果的生音,你可以在初始化EAGLContext
時(shí)指定ES
版本號(hào)。
指定版本方法如下所示窒升。
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
OpenGL ES坐標(biāo)系
OpenGL ES
坐標(biāo)系和UI
的坐標(biāo)系是不同的缀遍,具體如下所示。
UI
是以左上角為原點(diǎn)的饱须,而OpenGL ES
坐標(biāo)系是以屏幕中心為原點(diǎn)的域醇。除了方向,還有一點(diǎn)需要注意蓉媳,默認(rèn)情況各個(gè)方向坐標(biāo)值范圍為(-1譬挚,1)
,而不是UIKit
中的(0酪呻,320)
减宣。當(dāng)繪制點(diǎn)(320,0)
時(shí)玩荠,它并不會(huì)出現(xiàn)在屏幕右上角漆腌。在ES1
中,可以通過(guò)以下代碼將坐標(biāo)系轉(zhuǎn)化為熟悉的(320阶冈,480)
闷尿。下面我們看代碼。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glViewport(0, 0, rect.size.width * 2, rect.size.height * 2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, 320, 0, 480, -1024, 1024);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
幾個(gè)重要的類
下面介紹幾個(gè)重要的類女坑。
1. GLKViewController & GLKView
為了方便大家更快的開(kāi)發(fā)悠砚,系統(tǒng)為OpenGL
提供了簡(jiǎn)單的封裝,繼承GLKViewController
定義自己的ViewController
堂飞,GLKViewController
的view
為GLKView
類灌旧,GLKView
的delegate
定義了繪制回調(diào)函數(shù)。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
GLKViewController
定義數(shù)據(jù)刷新函數(shù)绰筛,當(dāng)子類實(shí)現(xiàn)-(void)update
方法枢泰,glkViewControllerUpdate
方法將不再被調(diào)用。
- (void)glkViewControllerUpdate:(GLKViewController *)controller
需要補(bǔ)充一點(diǎn)铝噩,默認(rèn)情況下衡蚂,GLKViewController
渲染RunLoop
并非NSRunLoopCommonModes
,而是NSDefaultRunLoopMode
骏庸,因此在UIKit
中使用GLKViewController
毛甲,當(dāng)滑動(dòng)界面時(shí),OpenGL
是不會(huì)渲染的具被。
2. EAGLContext
在介紹選擇版本時(shí)已經(jīng)提到EAGLContext
玻募,與UIKit
中CGContextRef
相似,EAGLContext
相當(dāng)于OpenGL
繪制句柄或者上下文一姿,在繪制試圖之前七咧,需要指定使用創(chuàng)建的上下文繪制跃惫。
[EAGLContext setCurrentContext:view.context];
當(dāng)一個(gè)APP可能存在多個(gè)EAGLContext
時(shí),需要處理并存沖突等問(wèn)題艾栋,比如大家所熟知的GPUImage爆存,都會(huì)使用到EAGLContext
。因此蝗砾,在使用中要記得及時(shí)釋放先较。有興趣的朋友可以看看這篇文章。
這里還需要記住的是:當(dāng)App退到后臺(tái)時(shí)悼粮, 切記暫停OpenGL
繪制闲勺,否則可能導(dǎo)致crash
。
后記
這篇主要是基本的介紹和幾個(gè)基礎(chǔ)概念矮锈,后面還會(huì)繼續(xù)給大家擴(kuò)展,畢竟基礎(chǔ)的部分是固定的睁蕾。未完苞笨,待續(xù)~~~