版本記錄
| 版本號(hào) | 時(shí)間 |
|---|---|
| V1.0 | 2017.07.22 |
前言
OpenGL 圖形庫(kù)項(xiàng)目中一直也沒用過,最近也想學(xué)著使用這個(gè)圖形庫(kù),感覺還是很有意思,也就自然想著好好的總結(jié)一下。首先要給大家介紹個(gè)學(xué)習(xí)網(wǎng)站。
1. 歡迎來到OpenGL的世界
2.系列教程
3.教程代碼
4.落影簡(jiǎn)書
OpenGL ES基礎(chǔ)

OpenGL ES是一套多功能開放標(biāo)準(zhǔn)的用于嵌入系統(tǒng)的C-based的圖形庫(kù),用于2D和3D數(shù)據(jù)的可視化。OpenGL被設(shè)計(jì)用來轉(zhuǎn)換一組圖形調(diào)用功能到底層圖形硬件(GPU),由GPU執(zhí)行圖形命令,用來實(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類 來實(shí)現(xiàn)和提供一個(gè)呈現(xiàn)環(huán)境,用來保持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:用來設(shè)置當(dāng)前線程的當(dāng)前context。EAGLContext 的類方法currentContext返回當(dāng)前線程的當(dāng)前context。在切換相同線程的兩個(gè)上下文之前,必須調(diào)用glFlush函數(shù)來確保先前已提交的命令被提交到圖形硬件中。
可以采用不同的方式使用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ū)ο蠼涌?,用來?jiǎn)化OpenGL ES應(yīng)用的開發(fā)。GLKit支持四個(gè)3D應(yīng)用開發(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)畫。視圖管理和維護(hù)一個(gè)framebuffer,應(yīng)用只需在framebuffer進(jìn)行繪畫即可。 -
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繪制過程
使用GLKView和OpenGLES進(jìn)行繪制過程:
創(chuàng)建一個(gè)
GLKView對(duì)象。
GLKView對(duì)象可以編程或使用Interface Builder來創(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,可以通過修改視圖的drawable屬性來控制這些對(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),用來實(shí)現(xiàn)連續(xù)的動(dòng)畫復(fù)雜的場(chǎng)景。animation 呈現(xiàn)循環(huán)的交替速率由GLKViewController的屬性framesPerSecond指示,并使用preferredFramesPerSecond 屬性來修改它。
OpenGL ES版本
iOS系統(tǒng)默認(rèn)支持OpenGl ES1.0、ES2.0以及ES3.0 3個(gè)版本,三者之間并不是簡(jiǎn)單的版本升級(jí),設(shè)計(jì)理念甚至完全不同,在開發(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中,可以通過以下代碼將坐標(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
為了方便大家更快的開發(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í),需要處理并存沖突等問題,比如大家所熟知的GPUImage,都會(huì)使用到EAGLContext。因此,在使用中要記得及時(shí)釋放。有興趣的朋友可以看看這篇文章。
這里還需要記住的是:當(dāng)App退到后臺(tái)時(shí), 切記暫停OpenGL繪制,否則可能導(dǎo)致crash。
后記
這篇主要是基本的介紹和幾個(gè)基礎(chǔ)概念,后面還會(huì)繼續(xù)給大家擴(kuò)展,畢竟基礎(chǔ)的部分是固定的。未完,待續(xù)~~~
