1. 程式人生 > >OpenGL紋理詳解(glsl, 混合, soil)

OpenGL紋理詳解(glsl, 混合, soil)

http://www.jianshu.com/p/2d31eae7c3d8

紋理的載入

當我們設定好紋理物件後,就可以載入我們的紋理資料了。下面這個例子演示瞭如何載入一幅2*2畫素的紋理:


載入一幅2*2的紋理 

這個函式非常重要,下面我們來看一下每個引數所表示的意義:

第一個引數很簡單,表示繫結紋理物件的種類,這裡我們依然以GL_TEXTURE_2D的紋理為例。

第二個引數表示該紋理對應的mipmaps的等級,0表示沒有進行縮小的原始圖片等級。

第三個引數表示了紋理所採用的內部格式,內部格式是我們的畫素資料在顯示卡中儲存的格式,這裡的GL_RGB顯然就表示紋理中畫素的顏色值是以RGB的格式儲存的。

第四個和第五個引數表示了紋理的寬和高,這裡我們採用的是2*2畫素寬度的紋理,因此這兩個引數都是2。

第六個引數通常為0.

第七和第八個引數描述了畫素在記憶體中的儲存格式和資料型別。

第九個引數是存放紋理資料的指標。

不過問題又來了,我們如何生成一個含有紋理資料的陣列呢?在實際工作中,我們通常需要使用一張JPG和PNG等格式的圖片檔案作為模型的紋理,而OpenGL中並沒有提供相關API用於將這些圖片檔案轉換成我們所需要的陣列。因此我們需要使用第三方庫來解決這一難題,目前使用得最廣泛的應該是SOIL庫,下面我們將以它為例來介紹如何將圖片檔案轉換成紋理資料。

SOIL

SOIL(Simple OpenGL Image Library)是一個簡單易用的圖片載入庫,它提供的API可以將指定的任意格式圖片檔案載入並生成紋理資料:


SOIL庫載入圖片生成紋理

這裡,我們將一個名為“img.png”的圖片檔案載入進記憶體,最終將儲存紋理資料的指標image返回給我們,並且這個API還同時可以獲取圖片的寬度width和高度height,也可以指定內部格式為RGB。

紋理資料使用完畢後釋放的工作也可以交給它完成:


SOIL庫釋放紋理資料 

正如上一篇中所提到的,OpenGL中紋理座標系是以紋理左下角為座標原點的,而圖片中畫素的儲存順序是從左上到右下的,因此我們需要對我們的座標系進行一次Y軸的“翻轉”。我們以後的教程中的0,0座標將會假設為是紋理的左上角而不再是左下角,這樣講解起來會更加直觀一些。

使用紋理

我們知道紋理是採用紋理座標進行取樣的,我們在使用紋理時,需要將頂點對應的紋理座標輸入OpenGL。這裡我們建立一個矩形區域的頂點陣列,數組裡每個頂點所包含的資料除位置、顏色外,還有紋理座標的s和t值。


包含紋理座標的頂點陣列

頂點著色器中將紋理座標Texcoord接收並傳入片段著色器:


頂點著色器

和其他頂點屬性一樣,將紋理座標以AttribPointer的形式輸入著色器:


新增紋理座標屬性

現在只剩下最後一件事情要處理,那就是在片段著色器中進行真正的紋理取樣。取樣方式很簡單,首先在著色器中宣告一個sapler2D型別的取樣器tex,然後呼叫texture函式進行取樣。texture函式第一個引數是取樣器,第二個引數就是我們由頂點著色器傳入的紋理座標。在這裡我們對採集後的紋理與我們頂點的顏色進行一個混合,混合的方式就是對兩者做一個笛卡爾積。


片段著色器

最終我們得到的效果如下:


紋理與頂點顏色混合效果

紋理單元

紋理單元是能夠被著色器取樣的紋理物件的引用, 紋理通過呼叫glBindTexture函式繫結到指定的紋理單元。由於你沒有明確指定使用哪個紋理單元,所以紋理被預設繫結到了GL_TEXTURE0,這就是為什麼我們在片段著色器中給我們的取樣器物件傳入一個0它依然能夠正常工作的原因。

那麼我們怎麼指定當前我們使用的紋理單元呢?OpenGL提供了一個叫做glActiveTexture的API來讓我們選擇用來繫結紋理的紋理單元ID:


指定紋理單元

OpenGL中最大支援的紋理單元數量根據顯示卡不同而有所區別,最少支援48個。不過基本上你同時用完所有紋理單元的機率為0。下面讓我們通過一個例子來看看怎樣同時使用多個紋理單元來完成多張紋理的混合,首先我們需要修改一下我們的片段著色器,讓它同時對兩張紋理進行取樣:


使用著色器同時對兩張紋理進行取樣

colKitten和colPuppy分別對應兩幅紋理中的取樣結果,最終的片段顏色值由mix函式將兩者進行混合後得到。

mix這個函式是GLSL中一個特殊的線性插值函式,他將前兩個引數的值基於第三個引數按照以下公式進行插值:

genType mix (genType x, genType y, float a)

返回線性混合的x和y,如:x⋅(1−a)+y⋅a

現在我們的兩個取樣器物件texKitten和texPuppy已經準備好了,你需要在應用程式中將兩幅紋理繫結給兩個紋理單元,再將這兩個紋理單元的ID通過glUniform函式分別賦值給我們的取樣器,應用程式端程式碼如下:


為兩個紋理單元分別繫結紋理

最終兩張紋理混合後得到的效果如下:


兩張紋理混合效果

相關推薦

OpenGL紋理(glsl, 混合, soil)

http://www.jianshu.com/p/2d31eae7c3d8 紋理的載入 當我們設定好紋理物件後,就可以載入我們的紋理資料了。下面這個例子演示瞭如何載入一幅2*2畫素的紋理: 載入一幅2*2的紋理  這個函式非常重要,下面我們來看一下每個引數

OpenGL第一個OpenGL程式

/////////////////////////////////////////////////////////////////////// // // triangles.cpp // ////////////////////////////////////////////////////////////

Android openGl開發(二)

https://zhuanlan.zhihu.com/p/35192609   Android openGl開發詳解(二)——通過SurfaceView,TextureView,GlSurfaceView顯示相機預覽(附Demo) aserbao 程式設計·生活·職場

Android openGl開發(一)——繪製簡單圖形

學習五部曲,弄清楚5個W一個H(when(什麼時候使用)、where(在哪個地方使用?)、who(對誰使用)、what(是個什麼東西)、why(為什麼要這麼用?).一個H即:how(到底該怎麼用?)),基本的概念篇主要圍繞這幾個方面進行分析

OpenGL】遊戲程式設計常用TGA影象格式以及載入紋理程式設計實現

TGA格式影象是遊戲中十分常見的一種影象格式,所以有必要了解其內部格式以及程式設計實現。 TGA影象一般有非壓縮和壓縮兩種格式,下面分別進行介紹。 一、非壓縮TGA影象 注:前面的標記綠色的部分(共12位元組)表示對於所有的非壓縮TGA格式影象值都是相同的!所以通常用來

OpenGL GLSL 語法和函式

變數和資料型別 可用的資料型別只有4種:有符號整數,無符號整數,浮點數,布林值。  OpenGL著色語言中沒有指標和字串或字元。返回值可以為void。 向量型別 所有4種基本資料型別都可以儲存在二維、三維或者四維向量中:  OpenGL著色語言向量資料型別 型別

混合雲資料安全傳輸兩大解決方案

Gartner稱,雲端計算的使用正在不斷增加,到2016年這一增長將佔據大量新增IT開支。2016年將是雲端計算決定性的一年,私有云開始讓路給混合雲,近半數的大型企業將在2017年年底部署混合雲。 但在此過程中,從公共雲到私有云之間的資料安全傳輸問題也成為各方關注的焦點。 本文詳細解讀了阿里

android平臺下OpenGL ES 3.0例項頂點屬性、頂點陣列

OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E

android平臺下OpenGL ES 3.0例項頂點緩衝區物件(VBO)和頂點陣列物件(VAO)

OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E

GMM混合高斯模型演算法

使用概率模型的原因 k均值等價於假設了球對稱形狀的聚類。使用帶權歐式距離,仍然假設了軸對齊的橢球。沒有考慮聚類的形狀。 促使概率模型的原因:混合模型 提供觀測點到聚類的軟分配soft assignment(分配包含不確定性) 考慮了聚類的形狀而不僅僅是中心

《OpenCV3程式設計入門》——5.2.3 addWeighted()函式(線性混合)(附程式碼

addWeighted()函式用來計算兩個陣列(影象陣列)的加權和。 格式如下: void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray

C/C++混合程式設計--extern “C” 使用方法

1. 首先要明白: 被extern “C”修飾的變數和函式是按照C語言方式編譯和連結的 (1) 首先看看C++中對類似C的函式是怎樣編譯的。 C++支援函式過載,而過程式語言C則不支援。函式被C++編譯後在符號庫中的名字與C語言的不同。例如,假設某個函式的原型為: void foo( i

對“初鏈”混合共識和雙鏈結構的

前段時間寫了篇部落格說了說自己對“初鏈”白皮書和黃皮書的解讀,其中一部分涉及到對“初鏈”混合共識和雙鏈技術的解讀,由於是從說明文件中獲取的資訊,難免會有誤解,雖然大體上和實際的處理邏輯相符合,但在細節上還是有一定的出入。出於對混合共識技術和雙鏈邏輯的好奇,博主我

OpenGL gluLookAt函式

第三組就是頭頂朝向的方向(因為你可以歪著頭看同一個物體)。#include <stdlib.h>#include <GL/glut.h>#pragma comment(lib, "glut32.lib")void init(void) {   glClearColor (0.0, 0.

Photoshop中27種圖層混合模式原理圖文

  本教程是向大家圖文詳解Photoshop中27種圖層混合模式原理,所謂圖層混合模式就是指一個層與其下圖層的色彩疊加方式,在這之前我們所使用的是正常模式,除了正常以外,還有很多種混合模式,它們都可以產生迥異的合成效果。那麼,為了讓大家更加了解混合工具的使用

C++:10---多級混合繼承、虛基類

一、多級混合繼承 下面介紹菱形繼承 //菱形繼承 class A { public: int data; }; class B:public A { public: int data; }; class C:public A { public: int data;

渲染到紋理(Render To Texture, RTT)

 RTT是現在很多特效裡面都會用到的一項很基本的技術,實現起來很簡單,也很重要。但是讓人不解的是網上搜索了半天只找到很少的文章說這個事兒,不知道是因為太簡單還是因為這項技術已經出現很長時間了。總之我是在摸索這個東西的時候繞了不少彎子。現在把具體的實現方法寫下來。渲染到紋理,顧

Qt Quick 之 QML 與 C++ 混合程式設計

    Qt Quick 技術的引入,使得你能夠快速構建 UI ,具有動畫、各種絢麗效果的 UI 都不在話下。但它不是萬能的,也有很多侷限性,原來 Qt 的一些技術,比如低階的網路程式設計如 QTcpSocket ,多執行緒,又如 XML 文件處理類庫 QXmlStreamR

Photoshop PS圖層混合模式

Photoshop 7.0的圖層混合選項中增添了“線性加深”模式、“線性減淡”模式、“亮光”模式、“線性光”模式和“點光”模式,這樣在製作一些效果時更為方便。  這裡我們便以中文版Photoshop 7.0為例來介紹一下Photoshop“圖層混合模式”,除了新增的少許混合

OpenGL glRenderbufferStorage 函式

OpenGL glRenderbufferStorage 函式詳解 glRenderbufferStorage 指定儲存在 renderbuffer 中影象的寬高以及顏色格式,並按照此規格為之分配儲存空間,當一個渲染快取被建立,它沒有任何資料儲存區域,所以我們還要為他分配