003-OpenGL ES之紋理

什么是紋理

紋理是一個(gè)用來(lái)保存圖像的顏色色素值得OpenGL ES緩存, 紋理的作用是為了使我們渲染的幾何圖像更加的逼真, 通常來(lái)說(shuō)就是使用一張圖片貼在我們需要渲染的幾何圖形上.

當(dāng)一個(gè)圖像初始化一個(gè)紋理緩存之后, 在這個(gè)圖像中的每個(gè)像素就變成了紋素(texel), 紋素也是用來(lái)保存顏色數(shù)據(jù)的.

紋理坐標(biāo)

紋理坐標(biāo)是一個(gè)命名為S和T的2D軸, 在一個(gè)紋理坐標(biāo)中, 無(wú)論紋素有多少個(gè), 在紋理的尺寸永遠(yuǎn)是S軸上從0.0到1 .0, 在T軸上從0.0到1.0. 紋理坐標(biāo)是一個(gè)相對(duì)坐標(biāo)的概念.

例如, 從一個(gè)1像素高, 64像素寬的圖像初始化來(lái)的紋理會(huì)沿著T軸有一個(gè)紋素, 沿著S軸有64個(gè)紋素.

屏幕快照 2017-07-04 上午10.03.31.png

轉(zhuǎn)換幾何形狀數(shù)據(jù)為幀緩存中的顏色像素的渲染步驟叫做點(diǎn)陣化(rasterizing), 每個(gè)顏色像素叫做(fragment). 當(dāng)OpenGL ES沒有使用紋理時(shí), GPU會(huì)根據(jù)包含該片元的對(duì)象的頂點(diǎn)的顏色來(lái)計(jì)算每個(gè)片元的顏色, 當(dāng)設(shè)置了紋理之后, GPU會(huì)根據(jù)當(dāng)前綁定的紋理緩存中的紋素來(lái)計(jì)算每個(gè)片元的顏色.

其實(shí)紋理就是要把一張圖片貼在我們繪制的幾何圖像上, 我們要制定貼在哪個(gè)位置, 這時(shí)就需要用到OpenGL ES坐標(biāo)與紋理坐標(biāo)之間的轉(zhuǎn)化.

我的理解是紋理坐標(biāo)是一個(gè)相對(duì)的坐標(biāo), 是相對(duì)與OpenGL ES的坐標(biāo)

屏幕快照 2017-07-05 下午10.46.15.png

OpenGL ES之繪制三角形(一)一節(jié)中, 我們繪制三角形需要指定三角形的頂點(diǎn)位置, 同樣, 我們繪制紋理, 也需要指定紋素的位置

typedef struct {
    GLKVector3  positionCoords;
    GLKVector2  textureCoords;
}
SceneVertex;

在原先的結(jié)構(gòu)體中新增一個(gè)類型GLKVector2, 用于存儲(chǔ)紋理的坐標(biāo)數(shù)據(jù)

static const SceneVertex vertices[] =
{
    {{-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f}}, 
    {{ 0.5f, -0.5f, 0.0f}, {1.0f, 0.0f}}, 
    {{-0.5f,  0.5f, 0.0f}, {0.0f, 1.0f}},
};

頂點(diǎn)坐標(biāo){-0.5f, -0.5f, 0.0f}映射到紋理坐標(biāo)就變?yōu)閧0.0f, 0.0f}, 頂點(diǎn)左下角的坐標(biāo)對(duì)應(yīng)紋理的左下角, 然后依次向S軸和T軸延伸到1.

接下來(lái)就是開始渲染紋理

   // Setup texture
   CGImageRef imageRef =  [[UIImage imageNamed:@"leaves.gif"] CGImage];
      
   GLKTextureInfo *textureInfo = [GLKTextureLoader 
      textureWithCGImage:imageRef 
      options:nil 
      error:NULL];
   
   self.baseEffect.texture2d0.name = textureInfo.name;
   self.baseEffect.texture2d0.target = textureInfo.target;

textureWithCGImage方法, 把CGImageRef轉(zhuǎn)成GLKTextureInfo類型的紋理緩存, GLKTextureInfo類保存了紋理緩存的信息, target屬性指定被配置的紋理緩存的類型, name是紋理緩存的一個(gè)標(biāo)識(shí)符.

至此紋理就被成功的渲染出來(lái)了.

混合

我們都知道三原色是紅, 黃, 藍(lán), 通過(guò)這三種顏色可以調(diào)配出其他的顏色滴铅。
混合就是把兩種顏色通過(guò)某種特定的方式混在一起橡淆。實(shí)現(xiàn)特殊的效果。就是透過(guò)一個(gè)物體去看另外一個(gè)物體的模式, 如果遮擋物是透明的, Alpha為0, 則我們可以透過(guò)遮擋物去看到被遮擋的物體, 就像玻璃一樣, 你可以透過(guò)玻璃去看到玻璃里面的東西; 如果遮擋物不是透明的, Alpha為1, 你就看不到被遮擋的物體, 就像你不能透過(guò)一堵墻去看墻另一側(cè)的物體.

要使用OpenGL的混合功能准脂,只需要調(diào)用:glEnable(GL_BLEND)即可良风。
要關(guān)閉OpenGL的混合功能脆炎,只需要調(diào)用:glDisable(GL_BLEND)即可踏拜。
注意:只有在RGBA模式下,才可以使用混合功能荚虚,顏色索引模式下是無(wú)法使用混合功能的薛夜。

混合需要把原來(lái)的顏色和將要畫上去的顏色找出來(lái),經(jīng)過(guò)某種方式處理后得到一種新的顏色版述。這里把將要畫上去的顏色稱為“源顏色”梯澜,把原來(lái)的顏色稱為“目標(biāo)顏色”。

OpenGL 會(huì)把源顏色和目標(biāo)顏色各自取出渴析,并乘以一個(gè)系數(shù)(源顏色乘以的系數(shù)稱為“源因子”晚伙,目標(biāo)顏色乘以的系數(shù)稱為“目標(biāo)因子”),然后進(jìn)項(xiàng)數(shù)學(xué)運(yùn)算, 這樣就得到了新的顏色俭茧。

源因子和目標(biāo)因子是可以通過(guò)glBlendFunc函數(shù)來(lái)進(jìn)行設(shè)置的咆疗。glBlendFunc有兩個(gè)參數(shù),前者表示源因子母债,后者表示目標(biāo)因子午磁。這兩個(gè)參數(shù)可以是多種值,下面介紹比較常用的幾種毡们。

GL_ZERO: 表示使用0.0作為因子迅皇,實(shí)際上相當(dāng)于不使用這種顏色參與混合運(yùn)算创泄。
GL_ONE: 表示使用1.0作為因子籍铁,實(shí)際上相當(dāng)于完全的使用了這種顏色參與混合運(yùn)算江兢。
GL_SRC_ALPHA:表示使用源顏色的alpha值來(lái)作為因子照激。
GL_DST_ALPHA:表示使用目標(biāo)顏色的alpha值來(lái)作為因子。
GL_ONE_MINUS_SRC_ALPHA:表示用1.0減去源顏色的alpha值來(lái)作為因子扣囊。
GL_ONE_MINUS_DST_ALPHA:表示用1.0減去目標(biāo)顏色的alpha值來(lái)作為因子吉嫩。

舉例來(lái)說(shuō):

  1. 如果設(shè)置了glBlendFunc(GL_ONE, GL_ZERO);其掂,則表示完全使用源顏色脖隶,完全不使用目標(biāo)顏色扁耐,因此畫面效果和不使用混合的時(shí)候一致(當(dāng)然效率可能會(huì)低一點(diǎn)點(diǎn))。如果沒有設(shè)置源因子和目標(biāo)因子产阱,則默認(rèn)情況就是這樣的設(shè)置婉称。
  2. 如果設(shè)置了glBlendFunc(GL_ZERO, GL_ONE);,則表示完全不使用源顏色构蹬,因此無(wú)論你想畫什么王暗,最后都不會(huì)被畫上去了。(但這并不是說(shuō)這樣設(shè)置就沒有用庄敛,有些時(shí)候可能有特殊用途)
  3. 如 果設(shè)置了glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);俗壹,則表示源顏色乘以自身的alpha 值,目標(biāo)顏色乘以1.0減去源顏色的alpha值藻烤,這樣一來(lái)绷雏,源顏色的alpha值越大,則產(chǎn)生的新顏色中源顏色所占比例就越大怖亭,而目標(biāo)顏色所占比例則減 小涎显。這種情況下,我們可以簡(jiǎn)單的將源顏色的alpha值理解為“不透明度”兴猩。這也是混合時(shí)最常用的方式期吓。
  4. 如果設(shè)置了glBlendFunc(GL_ONE, GL_ONE);,則表示完全使用源顏色和目標(biāo)顏色倾芝,最終的顏色實(shí)際上就是兩種顏色的簡(jiǎn)單相加讨勤。例如紅色(1, 0, 0)和綠色(0, 1, 0)相加得到(1, 1, 0),結(jié)果為黃色蛀醉。

注意:
所 謂源顏色和目標(biāo)顏色悬襟,是跟繪制的順序有關(guān)的。假如先繪制了一個(gè)紅色的物體拯刁,再在其上繪制綠色的物體脊岳。則綠色是源顏色,紅色是目標(biāo)顏色垛玻。如果順序反過(guò)來(lái)割捅,則 紅色就是源顏色,綠色才是目標(biāo)顏色帚桩。在繪制時(shí)亿驾,應(yīng)該注意順序,使得繪制的源顏色與設(shè)置的源因子對(duì)應(yīng)账嚎,目標(biāo)顏色與設(shè)置的目標(biāo)因子對(duì)應(yīng)莫瞬。不要被混亂的順序搞暈 了儡蔓。

在上面的代碼中我們已經(jīng)完成了單個(gè)紋理的實(shí)現(xiàn), 現(xiàn)在我們?cè)偬砑右粋€(gè)紋理, 來(lái)實(shí)現(xiàn)多重混合

設(shè)置坐標(biāo), 兩個(gè)三角形, 組成一個(gè)矩形

static const SceneVertex vertices[] = 
{
//第一個(gè)三角形
   {{-1.0f, -0.5f, 0.0f}, {0.0f, 0.0f}},  // first triangle
   {{ 1.0f, -0.5f, 0.0f}, {1.0f, 0.0f}},
   {{-1.0f,  0.5f, 0.0f}, {0.0f, 1.0f}},
//第二個(gè)三角形
   {{ 1.0f, -0.5f, 0.0f}, {1.0f, 0.0f}},  // second triangle
   {{-1.0f,  0.5f, 0.0f}, {0.0f, 1.0f}},
   {{ 1.0f,  0.5f, 0.0f}, {1.0f, 1.0f}},
};

前面說(shuō)過(guò)OpenGL ES 采用的是世界坐標(biāo)系, 世界坐標(biāo)系以屏幕中心為原點(diǎn)(0, 0, 0)。你面對(duì)屏幕疼邀,你的右邊是x正軸喂江,上面是y正軸,屏幕指向你的為z正軸旁振。長(zhǎng)度單位這樣來(lái)定: 窗口范圍按此單位恰好是(-1,-1)到(1,1)获询。

通過(guò)此坐標(biāo)系渲染之后將是一個(gè)矩形, 但是實(shí)際上是有兩個(gè)三角形組成的矩形

第一個(gè)三角形
第二個(gè)三角形
   //紋理 texture0
   CGImageRef imageRef0 = 
      [[UIImage imageNamed:@"leaves.gif"] CGImage];
      
   self.textureInfo0 = [GLKTextureLoader 
      textureWithCGImage:imageRef0 
      options:[NSDictionary dictionaryWithObjectsAndKeys:
         [NSNumber numberWithBool:YES], 
         GLKTextureLoaderOriginBottomLeft, nil] 
      error:NULL];
      
   // 紋理 texture1
   CGImageRef imageRef1 = 
      [[UIImage imageNamed:@"beetle.png"] CGImage];
      
   self.textureInfo1 = [GLKTextureLoader 
      textureWithCGImage:imageRef1 
      options:[NSDictionary dictionaryWithObjectsAndKeys:
         [NSNumber numberWithBool:YES], 
         GLKTextureLoaderOriginBottomLeft, nil] 
      error:NULL];
//GLKTextureLoaderOriginBottomLeft 設(shè)置成YES
  //開啟混合
   glEnable(GL_BLEND);
//設(shè)置源因子與目標(biāo)因子的關(guān)系
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

我們現(xiàn)在設(shè)置了兩個(gè)紋理, 所以當(dāng)我們繪制的時(shí)候也需要分別進(jìn)行繪制, 此處注意, 紋理顯示的先后順序是根據(jù)繪制的先后順訊決定的. 先繪制的在下面, 后繪制的在上面, 這個(gè)和UIView的層級(jí)結(jié)構(gòu)是一樣的.
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法里進(jìn)行繪制, 這些方法也可以寫在設(shè)置設(shè)置紋理的時(shí)候

   self.baseEffect.texture2d0.name = self.textureInfo0.name;
   self.baseEffect.texture2d0.target = self.textureInfo0.target;
      
   self.baseEffect.texture2d0.name = self.textureInfo1.name;
   self.baseEffect.texture2d0.target = self.textureInfo1.target;

混合就是在繪制時(shí),不是直接把新的顏色覆蓋在原來(lái)舊的顏色上拐袜,而是將新的顏色與舊的顏色經(jīng)過(guò)一定的運(yùn)算吉嚣,從而產(chǎn)生新的顏色。新的顏色稱為源顏色蹬铺,原來(lái)舊的顏色稱為目標(biāo)顏色尝哆。傳統(tǒng)意義上的混合,是將源顏色乘以源因子丛塌,目標(biāo)顏色乘以目標(biāo)因子较解,然后相加。

源 因子和目標(biāo)因子是可以設(shè)置的赴邻。源因子和目標(biāo)因子設(shè)置的不同直接導(dǎo)致混合結(jié)果的不同印衔。將源顏色的alpha值作為源因子,用1.0減去源顏色alpha值作 為目標(biāo)因子姥敛,是一種常用的方式奸焙。這時(shí)候,源顏色的alpha值相當(dāng)于“不透明度”的作用彤敛。利用這一特點(diǎn)可以繪制出一些半透明的物體与帆。

在進(jìn)行混合時(shí),繪制的順序十分重要墨榄。因?yàn)樵诶L制時(shí)玄糟,正要繪制上去的是源顏色,原來(lái)存在的是目標(biāo)顏色袄秩,因此先繪制的物體就成為目標(biāo)顏色阵翎,后來(lái)繪制的則成為源顏色。繪制的順序要考慮清楚之剧,將目標(biāo)顏色和設(shè)置的目標(biāo)因子相對(duì)應(yīng)郭卫,源顏色和設(shè)置的源因子相對(duì)應(yīng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末背稼,一起剝皮案震驚了整個(gè)濱河市贰军,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蟹肘,老刑警劉巖词疼,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俯树,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贰盗,警方通過(guò)查閱死者的電腦和手機(jī)聘萨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)童太,“玉大人,你說(shuō)我怎么就攤上這事胸完∈槭停” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵赊窥,是天一觀的道長(zhǎng)爆惧。 經(jīng)常有香客問我,道長(zhǎng)锨能,這世上最難降的妖魔是什么扯再? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮址遇,結(jié)果婚禮上熄阻,老公的妹妹穿的比我還像新娘。我一直安慰自己倔约,他們只是感情好秃殉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浸剩,像睡著了一般钾军。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绢要,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天吏恭,我揣著相機(jī)與錄音,去河邊找鬼重罪。 笑死樱哼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛆封。 我是一名探鬼主播唇礁,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惨篱!你這毒婦竟也來(lái)了盏筐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤砸讳,失蹤者是張志新(化名)和其女友劉穎琢融,沒想到半個(gè)月后界牡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漾抬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年宿亡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纳令。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挽荠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出平绩,到底是詐尸還是另有隱情圈匆,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布捏雌,位于F島的核電站跃赚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏性湿。R本人自食惡果不足惜纬傲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肤频。 院中可真熱鬧叹括,春花似錦、人聲如沸着裹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)骇扇。三九已至摔竿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間少孝,已是汗流浹背继低。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稍走,地道東北人袁翁。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像婿脸,于是被迫代替她去往敵國(guó)和親粱胜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 前言 本文主要是對(duì)OpegGL ES的api做一些資料上的搜集,給大家推薦一個(gè)中文詳解網(wǎng)站:鏈接,雖然作者還沒有寫...
    Link913閱讀 2,498評(píng)論 1 6
  • 1.OpenGLES提供了一個(gè)為幾何圖形中的每個(gè)頂點(diǎn)設(shè)置不同顏色的方法狐树。 2.紋理可以控制一個(gè)渲染的三角形中的每個(gè)...
    碧玉小瑕閱讀 412評(píng)論 0 0
  • 一焙压、紋理基礎(chǔ) 3D圖形渲染中最基本的操作就是對(duì)一個(gè)表面應(yīng)用紋理。紋理可以表現(xiàn)只從網(wǎng)格的幾何形狀無(wú)法得到的附加細(xì)節(jié)。...
    cain_huang閱讀 8,814評(píng)論 0 7
  • 版本記錄 前言 OpenGL 圖形庫(kù)項(xiàng)目中一直也沒用過(guò)涯曲,最近也想學(xué)著使用這個(gè)圖形庫(kù)野哭,感覺還是很有意思,也就自然想著...
    刀客傳奇閱讀 8,859評(píng)論 0 8
  • 混合 在OpenGL中幻件,物體透明技術(shù)通常被叫做混合(Blending)拨黔。透明的物體(或物體的一部分)非純色而是混合...
    IceMJ閱讀 3,074評(píng)論 1 4