日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS 开发 OpenGL 新手入门

發(fā)布時間:2025/6/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS 开发 OpenGL 新手入门 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、搭建開發(fā)環(huán)境

1、打開XCODE,新建一個工程

選擇:IOS-->ApplicationàSingle View Application模板。

取名為“HelloOpenGL”,勾選“UseStoryboards”,然后創(chuàng)建。

?
??

2、添加必要的框架

在“Build Phases”欄,添加進(jìn)三個框架:



3、修改viewController.h

添加“#import <GLKit/glkit.h>”,并將它修改為繼承“GLKViewController”。


?

??

4、修改“view”的類

雙擊“MainStoryboard.storyboard”展開,選擇“view”。

?
??

然后,在其“Identity Inspector”中,將它的類改為“GLKView”。

?

?至此,OpenGL環(huán)境已基本搭建出來了。運行,應(yīng)該不會報錯,盡管它目前仍是黑屏。

?

二、開始堆代碼

基本上,所有的代碼都在“ViewController.m”中寫。

1、添加全局屬性聲明

?

當(dāng)然,還得在實現(xiàn)部分補足“@synthesize context;”和“@synthesize effect;”。

?

2、添加一組頂點數(shù)據(jù)

這是一個正方形頂點的數(shù)組,實際上它是由二個三角形接合而成的。

?每行頂點數(shù)據(jù)的排列含義是:

頂點X、頂點Y,頂點Z、法線X、法線Y、法線Z、紋理S、紋理T。

在后面解析此數(shù)組時,將參考此規(guī)則。

頂點位置用于確定在什么地方顯示,法線用于光照模型計算,紋理則用在貼圖中。

一般約定為“頂點以逆時針次序出現(xiàn)在屏幕上的面”為“正面”。

世界坐標(biāo)是OpenGL中用來描述場景的坐標(biāo),Z+軸垂直屏幕向外,X+從左到右,Y+軸從下到上,是右手笛卡爾坐標(biāo)系統(tǒng)。我們用這個坐標(biāo)系來描述物體及光源的位置。

?

三、初始化OpenGL環(huán)境

1、基本的初始化代碼

在“viewDidLoad”方法內(nèi),補充初始化代碼:

?

第一部分:使用“ES2”創(chuàng)建一個“EAGLContext”實例。

第二部分:將“view”的context設(shè)置為這個“EAGLContext”實例的引用。并且設(shè)置顏色格式和深度格式。

第三部分:將此“EAGLContext”實例設(shè)置為OpenGL的“當(dāng)前激活”的“Context”。這樣,以后所有“GL”的指令均作用在這個“Context”上。隨后,發(fā)送第一個“GL”指令:激活“深度檢測”。

第四部分:創(chuàng)建一個GLK內(nèi)置的“著色效果”,并給它提供一個光源,光的顏色為綠色。

?

2、運行

現(xiàn)在應(yīng)該是粉紅色屏幕了(目前場景仍是空的),說明初始化過程沒問題。

?

四、將頂點數(shù)據(jù)寫入通用的頂點屬性存儲區(qū)

1、寫入過程

首先將數(shù)據(jù)保存進(jìn)GUP的一個緩沖區(qū)中,然后再按一定規(guī)則,將數(shù)據(jù)取出,復(fù)制到各個通用頂點屬性中。

注:如果頂點數(shù)據(jù)只有一種類型(如單純的位置坐標(biāo)),換言之,在讀數(shù)據(jù)時,不需要確定第一個數(shù)據(jù)的內(nèi)存位置(總是從0開始),則不必事先保存進(jìn)緩沖區(qū)。

?

2、頂點數(shù)組保存進(jìn)緩沖區(qū)

?

這幾行代碼表示的含義是:聲明一個緩沖區(qū)的標(biāo)識(GLuint類型)à讓OpenGL自動分配一個緩沖區(qū)并且返回這個標(biāo)識的值à綁定這個緩沖區(qū)到當(dāng)前“Context”à最后,將我們前面預(yù)先定義的頂點數(shù)據(jù)“squareVertexData”復(fù)制進(jìn)這個緩沖區(qū)中。

注:參數(shù)“GL_STATIC_DRAW”,它表示此緩沖區(qū)內(nèi)容只能被修改一次,但可以無限次讀取。

?

3、將緩沖區(qū)的數(shù)據(jù)復(fù)制進(jìn)通用頂點屬性中

??

首先,激活頂點屬性(默認(rèn)它的關(guān)閉的)。“GLKVertexAttribPosition”是頂點屬性集中“位置Position”屬性的索引。

頂點屬性集中包含五種屬性:位置、法線、顏色、紋理0,紋理1。

它們的索引值是0到4。

激活后,接下來使用“glVertexAttribPointer”方法填充數(shù)據(jù)。

參數(shù)含義分別為:

頂點屬性索引(這里是位置)、3個分量的矢量、類型是浮點(GL_FLOAT)、填充時不需要單位化(GL_FALSE)、在數(shù)據(jù)數(shù)組中每行的跨度是32個字節(jié)(4*8=32。從預(yù)定義的數(shù)組中可看出,每行有8個GL_FLOAT浮點值,而GL_FLOAT占4個字節(jié),因此每一行的跨度是4*8)。

最后一個參數(shù)是一個偏移量的指針,用來確定“第一個數(shù)據(jù)”將從內(nèi)存數(shù)據(jù)塊的什么地方開始。

?

4、繼續(xù)復(fù)制其他數(shù)據(jù)

在前面預(yù)定義的頂點數(shù)據(jù)數(shù)組中,還包含了法線和紋理坐標(biāo),所以參照上面的方法,將剩余的數(shù)據(jù)分別復(fù)制進(jìn)通用頂點屬性中。

?

原則上,必須先“激活”某個索引,才能將數(shù)據(jù)復(fù)制進(jìn)這個索引表示的內(nèi)存中。

因為紋理坐標(biāo)只有兩個(S和T),所以上面參數(shù)是“2”。

?

五、執(zhí)行渲染循環(huán)

萬事具備,現(xiàn)在可以讓OpenGL顯示一些東西了。

在GLKit框架中,盡管OpenGL的行為,是由“GLKViewController”和“GLKView”聯(lián)合控制的,但實際上“GLKView”類中完全不需要寫任何自己的代碼,因為,“GLKView”類中每幀觸發(fā)的兩個方法“update”和“glkView”,都轉(zhuǎn)交給“GLKViewController”代理執(zhí)行了。

?

1、添加代理方法

在“ViewController.m”中添加兩個方法:

??

這兩個方法每幀都執(zhí)行一次(循環(huán)執(zhí)行),一般執(zhí)行頻率與屏幕刷新率相同(但也可以更改)。

第一次循環(huán)時,先調(diào)用“glkView”再調(diào)用“update”。

一般,將場景數(shù)據(jù)變化放在“update”中,而渲染代碼則放在“glkView”中。

2、渲染場景

?

??

前兩行為渲染前的“清除”操作,清除顏色緩沖區(qū)和深度緩沖區(qū)中的內(nèi)容,并且填充淡藍(lán)色背景(默認(rèn)背景是黑色)。

“prepareToDraw”方法,是讓“效果Effect”針對當(dāng)前“Context”的狀態(tài)進(jìn)行一些配置,它始終把“GL_TEXTURE_PROGRAM”狀態(tài)定位到“Effect”對象的著色器上。此外,如果Effect使用了紋理,它也會修改“GL_TEXTURE_BINDING_2D”。

?

接下來,用“glDrawArrays”指令,讓OpenGL“畫出”兩個三角形(拼合為一個正方形)。OpenGL會自動從通用頂點屬性中取出這些數(shù)據(jù)、組裝、再用“Effect”內(nèi)置的著色器渲染。

?

3、結(jié)果

?

渲染內(nèi)容終于呈現(xiàn)了,藍(lán)色背景、還有一個綠色矩形(其實是兩個三角形)。綠色并非是此物體的本色,而受是綠色燈光影響。

PS:在前面的頂點數(shù)據(jù)定義中,期望得到一個正方形,但為什么顯示結(jié)果卻是一個矩形?

?

六、正確顯示正方形外觀

默認(rèn),“Effect”的投影矩陣是一個單位矩陣,它不做任何變換,將場景(-1,-1,-1)到(1,1,1)的立文體范圍的物體,投射到屏幕的X:-1,1,Y:-1,1。因此,當(dāng)屏幕本身是非正方形時,正方形的物體將被拉伸,從而顯示為矩形。

實際上,默認(rèn)的“Effect”模型視圖矩陣也是一個單位矩陣。

透視投影中的觀察點位于原點(0,0,0),并沿著Z軸的負(fù)方向進(jìn)行觀察,就像是從屏幕內(nèi)部看進(jìn)去。

?

1、修改投影矩陣

為了正確顯示,需要修改投影矩陣。在“update”方法中添加下面的代碼:

?

首先計算出屏幕的縱橫比(aspect),然后縮放單位矩陣的Y軸,強制將Y軸的單位刻度與X軸保持一致。

?

2、渲染觀察效果

?

3、使用透視投影矩陣

把單位矩陣做拉伸,本質(zhì)上仍然是一個正交投影。要模擬人眼觀察世界的效果,則必須使用透視投影。

把上面的代碼做一些修改:

?

使用GLKit自帶的方法創(chuàng)建出一個透視矩陣,視角、縱橫比、近平面、遠(yuǎn)平面。

渲染效果如下:

?

4、修改模型視圖矩陣

上圖看起來感覺像一個正方形,但似乎左右兩邊沒顯示完整。

原因是,正方形與透視視點距離太近。

有兩個方法解決這個問題:一是修改原始的頂點數(shù)據(jù)(Z軸值),使之透視視點;二是通過所謂的“模型視圖矩陣”,將正方形“變換”到遠(yuǎn)一點的位置。

添加以下代碼:

?這樣,同樣再次顯出一個精確的正方形。

?

七、使用紋理

1、準(zhǔn)備紋理

在PS中剪切、調(diào)節(jié)紋理尺寸(512*512),并保存為Tulips.JPG。本例中使用的圖像是一幅黃色的郁金香。

然后在XCODE,導(dǎo)入進(jìn)工程中。

?

2、使用GLKTextureLoader加載紋理

在“viewDidLoad”方法的后面,追加下列代碼:

?

首先用“NSBundle”找到資源“Tulips.jpg”的路徑,然后用“GLKTextureLoader”類方法同步加載這個紋理,也可以用它的實例方法異步進(jìn)行加載。

默認(rèn),此圖片加載進(jìn)TEXTURE0,如果需要加載進(jìn)其他單元,需要先用指令“glActiveTexure(GL_TEXTUREn)”。——n為1-(CL_COMBINED_TEXTURE_IMAGE_UNITS-1)中的一個數(shù)值。

加載成功后,該紋理的信息都保存在“textureInfo”中,以后,直接使用此變量的相關(guān)屬性,就可以在OpenGL中應(yīng)用這個紋理了。

?

3、將紋理綁定到Effect

接著,繼續(xù)添加后續(xù)代碼:

?

4、渲染

?

與意料中的結(jié)果似乎有差距,黃色的花瓣變成了綠色?圖像是上下顛倒的?

?

八、紋理細(xì)節(jié)調(diào)整

造成上面錯誤是原因是:

在最初構(gòu)造Effect光照時,使用了綠色,所以整個紋理被“染”成為綠色。

圖像顛倒是因為紋理的坐標(biāo)原點不在左下角。

1、修改光照顏色

?

2、將紋理坐標(biāo)原點改為左下角

GLKit加載紋理,默認(rèn)都是把坐標(biāo)設(shè)置在“左上角”。然而,OpenGL的紋理貼圖坐標(biāo)卻是在左下角,這樣剛好顛倒。

在加載紋理之前,添加一個“options”:

?

這個參數(shù)可以讓系統(tǒng)在加載紋理后,做一些基本的處理。如預(yù)乘Alpha、創(chuàng)建“Mipmaps”等。

?

3、渲染,一切正常

九、使用自定義的著色器

迄今,例中只是簡單地調(diào)用了“GLKit”內(nèi)置的著色程序進(jìn)行渲染。但是,在某些情況下,可能需要使用自己的特殊的著色器。

1、編寫著色程序

一個著色器由兩個部分構(gòu)成(可以是兩個文件,也可以是硬編碼嵌在程序中的兩段代碼字串)。

它們分別是:頂點著色程序和片段著色程序。

創(chuàng)建兩個“Empty”文件,分別命名為“v.shader”和“f.shader”。

?

??

然后,兩個文件分別寫入這些代碼:

2、加載、存儲、編譯、附著、鏈接

在OpenGL中使用自定義著色器,過程比較繁瑣。

首先需要加載這個文件-->把它轉(zhuǎn)換為GLChar(UTF8編碼)-->保存進(jìn)GUP內(nèi)存-->編譯內(nèi)存中的字串代碼-->附著給“program”對象。

上述過程要進(jìn)行兩次(分別為頂點程序和片段程序)。

最后,將“program”鏈接到當(dāng)前“Context”,這樣才能在OpenGL中發(fā)揮作用。

為了簡化代碼,可以寫成兩個方法,作為公共的加載方法使用:

??

3、開始加載自定義的著色器

在“viewDidLoad”方法里追加以下代碼:

?

如何判斷著色器是否能正常工作?可以用:

glGetProgramiv(_program, GL_LINK_STATUS, &params);

如果返回的“params”為1,則說明一切正常。

另外,上面代碼中“_program”為新添加進(jìn)去的公共變量

???

4、為著色器提供參數(shù)

頂點著色程序需要一個屬性參數(shù):position(表示頂點的位置)

?

5、在“glkView”方法后追加

渲染結(jié)果為:

屏幕上出現(xiàn)兩個矩形,有圖案的是用“effct”渲染的,上面紅色的是用“_program”自定義著色器渲染的。

十、增加著色器顯示紋理

上述著色器是一個超級簡單的著色器(幾乎沒實現(xiàn)什么功能,僅是簡單地著為紅色)。

下面逐漸增加它的功能。

?

1、修改著色器

給頂點著色器,增加紋理坐標(biāo)屬性“TexCoord”和該坐標(biāo)的輸出“coord”(此輸出將在片段著色器中使用)。


給片段著色器,增加紋理坐標(biāo)輸入“coord”,以及統(tǒng)一的“sampler2D”變量。

?片段的顏色改為由“texture2D”函數(shù)計算出來,實際上就是按紋理坐標(biāo)從紋理像素中取樣。

2、綁定著色器變量

要使著色器正常工作,必須提供它需要的參數(shù)內(nèi)容。

在“viewDidload”方法后,添加“綁定”代碼:

??

第一部分是綁定“position”屬性到通用的的頂點屬性索引“0”上,綁定“texCoord”到通用的頂點屬性索引“3”上。(索引1是法線,2是頂點顏色)。

綁定后,必須調(diào)用“glLinkProgram”方法才能生效。

?

第二部分,綁定“統(tǒng)一的紋理sampler2D”變量,到紋理0號單元——在使用“GLKTextureLoader”加載紋理時,默認(rèn)是激活了“0”號單元。當(dāng)然,如果是激活其他單元(例如8),則這里就相應(yīng)的改為8。

綁定之前,必須調(diào)用“glUseProgram”才起作用。

?

3、運行渲染

?

十一、著色器頂點變換矩陣

在上述著色器代碼中,是直接使用:

gl_Position = position;

也就是說,頂點位置沒有經(jīng)過任何變換,直接使用它的原始數(shù)據(jù)(所以它的圖像也被顯示為一個矩形)。

?

1、引入變換矩陣

修改頂點著色器代碼:

??

添加了一個統(tǒng)一的矩陣變量“modelViewProjectionMatrix”(模型、視圖、投影矩陣,是這三個變換矩陣合并后(乘法),得到一個單個的矩陣)。將來,要在主程序中將矩陣值傳入。

?

2、傳入矩陣值

在“update”方法中,追加下面的代碼:

??

查詢到“modelViewProjectionMatrix”變量à計算合并矩陣à傳給著色器。

傳入著色器的值是modelViewProjectionMatrix.m,注意后面的“m”,它表示是一維數(shù)組形式的矩陣。

?

3、再次渲染

?

因為,“Effect”的變換矩陣與“著色器”的渲染結(jié)果相同,所以,顯示為兩個完全重合的正方形。

?

4、偏離屏幕中心

為了更便于觀察,下面將“著色器”渲染的正方形偏離一下。

修改代碼:

?

?

在合并矩陣之前,先把“modelViewMatrix”做一個平移(1.0,1.0,-1.0)。

結(jié)果為:

?

?

注意到兩個圖像的顏色略有差別,這是因為“Effect”內(nèi)置的著色器使用了光源。而自定義的著色器沒有光效代碼,它完全照搬了紋理的“原色”。另外,后面那個正方形變小了,是因為它更遠(yuǎn)離了“相機”。

?

?

十二、動畫

所謂動畫,其實就是在“update”中有規(guī)律地修改一些Matrix參數(shù),連續(xù)刷新時,即產(chǎn)生動畫的“錯覺”。

1、旋轉(zhuǎn)動畫

添加一些代碼,如下:

?

??

首先要添加一個全局旋轉(zhuǎn)變量“_rotation”。

然后讓它每幀旋轉(zhuǎn)一點點,并以此修改“modelVireMatrix”矩陣。

?

2、渲染動畫效果

?

結(jié)果是,正方形圍繞“自己”進(jìn)行了旋轉(zhuǎn)。

如果希望它繞屏幕中心旋轉(zhuǎn),怎么做?

?

3、理解矩陣堆棧

OpenGL的矩陣變換是放在一個矩陣堆棧中的(后進(jìn)先出),代碼中矩陣變換的次序,決定了堆棧中矩陣的變換順序。所以,上述矩陣的變換實際上是倒過來進(jìn)行的:先做平移,再做旋轉(zhuǎn),這樣它就圍繞屏幕中心旋轉(zhuǎn)了。

把上面的代碼中“平移”和“旋轉(zhuǎn)”交換一下次序即可:

?

(完)

轉(zhuǎn)載于:https://www.cnblogs.com/suoyin/p/7018991.html

總結(jié)

以上是生活随笔為你收集整理的iOS 开发 OpenGL 新手入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。