通常生活中,地磚的圖文亿虽,壁紙的圖文 這種比普通顏色復(fù)雜的顏色就是紋理
紋理
為了將紋理映射到三角形,我們需要告訴三角形的每個(gè)頂點(diǎn)對(duì)應(yīng)的紋理部分迎膜。每個(gè)頂點(diǎn)應(yīng)該有一個(gè)紋理坐標(biāo)與它們相關(guān)聯(lián),指定要從哪個(gè)部分紋理圖像中進(jìn)行抽樣。片段插值然后對(duì)其他片段進(jìn)行其余的處理混弥。
紋理坐標(biāo)范圍從0到1的x和y軸線(現(xiàn)在使用的是2D紋理圖像)。調(diào)用使用紋理坐標(biāo)檢索紋理顏色采樣对省。紋理坐標(biāo)從(0,0)紋理圖像的(1,1)左下角開始到紋理圖像的右上角
為三角形指定3個(gè)紋理坐標(biāo)點(diǎn)蝗拿。我們希望三角形的左下方與紋理的左下方對(duì)應(yīng),所以我們使用(0,0)三角形左下角的紋理坐標(biāo)蒿涎。同樣適用于具有(1,0)紋理坐標(biāo)的右下側(cè)哀托。三角形的頂部應(yīng)與紋理圖像的頂部中心對(duì)應(yīng),因此我們將(0.5,1.0)其作為其紋理坐標(biāo)劳秋。我們只需要將3個(gè)紋理坐標(biāo)傳遞給頂點(diǎn)著色器仓手,然后將它們傳遞給片段著色器,從而對(duì)每個(gè)片段的所有紋理坐標(biāo)進(jìn)行內(nèi)插玻淑。
float texCoords[] = {
0.0f, 0.0f, // 左下角
1.0f, 0.0f, // 右下角
0.5f, 1.0f // 中間的點(diǎn)
};
紋理包裝
OpenGL的默認(rèn)行為是重復(fù)紋理圖像(我們基本上忽略浮點(diǎn)紋理坐標(biāo)的整數(shù)部分)嗽冒,但OpenGL提供了以下選項(xiàng):
- GL_REPEAT:紋理的默認(rèn)行為。重復(fù)紋理圖像补履。
- GL_MIRRORED_REPEAT:與GL_REPEAT相同添坊,但每次重復(fù)都會(huì)鏡像圖像。
- GL_CLAMP_TO_EDGE:夾住0和之間的坐標(biāo)1箫锤。結(jié)果是較高的坐標(biāo)被夾緊到邊緣帅腌,導(dǎo)致拉伸的邊緣圖案。
- GL_CLAMP_TO_BORDER:范圍外的坐標(biāo)現(xiàn)在被賦予用戶指定的邊框顏色麻汰。
看一下每個(gè)選項(xiàng)不同的效果:
前述每個(gè)選項(xiàng)可以為每個(gè)坐標(biāo)軸進(jìn)行設(shè)置(s速客,t(和r如果您正在使用3D紋理),相當(dāng)于x五鲫,y溺职,z)與glTexParameter*
功能:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
/*
*第一個(gè)參數(shù)指定紋理目標(biāo),我們正在使用2D紋理,因此紋理目標(biāo)是GL_TEXTURE_2D
*第二個(gè)參數(shù)要求我們要設(shè)置什么選項(xiàng),以及哪個(gè)紋理軸浪耘。我們要配置該WRAP選項(xiàng)S并T為軸指定它
*最后一個(gè)參數(shù)要求我們傳遞我們想要的紋理包裝模式乱灵,在這種情況下,OpenGL將使用GL_MIRRORED_REPEAT在當(dāng)前活動(dòng)的紋理上設(shè)置其紋理包裝選項(xiàng)七冲。
*/
紋理過濾
紋理坐標(biāo)不依賴于分辨率痛倚,但可以是任何浮點(diǎn)值,因此OpenGL必須弄清楚哪個(gè)紋理像素(也稱為 紋理元素)將紋理坐標(biāo)映射到澜躺。有幾個(gè)選項(xiàng)可用蝉稳,但現(xiàn)在我們將討論最重要的選項(xiàng):GL_NEAREST
和GL_LINEAR
。
GL_NEAREST(也稱為最近鄰濾波)是OpenGL的默認(rèn)紋理過濾方法掘鄙。當(dāng)設(shè)置為GL_NEAREST時(shí)耘戚,OpenGL會(huì)選擇中心最接近紋理坐標(biāo)的像素。下面你可以看到4個(gè)像素操漠,其中十字架代表確切的紋理坐標(biāo)收津。左上紋理體的中心最靠近紋理坐標(biāo),因此被選為采樣顏色:
GL_LINEAR(也稱為(bi)線性濾波)從紋理坐標(biāo)的相鄰紋素中獲取內(nèi)插值浊伙,逼近紋素之間的顏色撞秋。從紋理坐標(biāo)到紋素中心的距離越小,紋素的顏色越多嚣鄙,對(duì)采樣的顏色有所貢獻(xiàn)吻贿。下面我們可以看到返回相鄰像素的混合顏色:
看一下2個(gè)選項(xiàng)效果
GL_NEAREST導(dǎo)致阻塞的模式,我們可以清楚地看到形成紋理的像素拗慨,而GL_LINEAR產(chǎn)生更平滑的圖案廓八,其中各個(gè)像素不太可見奉芦。GL_LINEAR產(chǎn)生更逼真的輸出赵抢,但是我們更喜歡更多的8位外觀,因此選擇GL_NEAREST選項(xiàng)声功。
注意:如果使用圖片當(dāng)作紋理烦却,需要圖像的寬度和高度
生成紋理
- 創(chuàng)建一個(gè)紋理被引用的ID
int texture;
glGenTextures(1, &texture);
/*
*第一個(gè)參數(shù):指定要生成的紋理對(duì)象的數(shù)量
*第二個(gè)參數(shù):指定存儲(chǔ)生成的紋理的數(shù)組
*/
2.綁定紋理
glBindTexture(GL_TEXTURE_2D, texture);
/*
*將給定的紋理對(duì)象設(shè)置為當(dāng)前活動(dòng)的紋理對(duì)象
*第一個(gè)參數(shù):指定最常見的紋理綁定到的目標(biāo) GL_TEXTURE_1D GL_TEXTURE_2D GL_TEXTURE_3D
*指定要綁定的紋理
*/
3.生成紋理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
/*
*在當(dāng)前紋理單元的當(dāng)前綁定紋理對(duì)象上生成紋理圖像
*第一個(gè)參數(shù)指定紋理目標(biāo); 將其設(shè)置為GL_TEXTURE_2D意味著此操作將在同一目標(biāo)上的當(dāng)前綁定紋理對(duì)象上生成紋理(因此,綁定到目標(biāo)GL_TEXTURE_1D或GL_TEXTURE_3D的任何紋理都不會(huì)受到影響)先巴。
*第二個(gè)參數(shù)指定要為其創(chuàng)建紋理的mipmap級(jí)別其爵,如果要手動(dòng)設(shè)置每個(gè)mipmap級(jí)別,但我們將其保留在基本級(jí)別0伸蚯。
*第三個(gè)參數(shù)告訴OpenGL我們想要存儲(chǔ)紋理的是什么樣的格式摩渺。我們的圖像只有RGB值,所以我們將保存紋理與RGB值剂邮。
*第4和第5個(gè)參數(shù)設(shè)置結(jié)果紋理的寬度和高度摇幻。我們?cè)诩虞d圖像時(shí)存儲(chǔ)了那些,所以我們將使用相應(yīng)的變量。
下一個(gè)參數(shù)應(yīng)該是0(一些遺留的東西)绰姻。
*第7和第8個(gè)參數(shù)指定源圖像的格式和數(shù)據(jù)類型枉侧。我們使用RGB值加載圖像并將其存儲(chǔ)為chars(字節(jié)),以便我們傳遞相應(yīng)的值狂芋。
*最后一個(gè)參數(shù)是實(shí)際的圖像數(shù)據(jù)榨馁。
*/
4.一旦 glTexImage2D被調(diào)用,當(dāng)前綁定的紋理對(duì)象現(xiàn)在具有附加的紋理圖像帜矾。然而翼虫,目前它只具有加載的紋理圖像的基本級(jí)別,如果我們要使用mipmap黍特,我們必須手動(dòng)指定所有不同的圖像(通過不斷增加第二個(gè)參數(shù))蛙讥,或者我們可以調(diào)用glGenerateMipmap生成紋理后。這將自動(dòng)生成當(dāng)前綁定紋理的所有必需的mipmap灭衷。
glGenerateMipmap(GL_TEXTURE_2D);
生成完以后次慢,釋放圖像內(nèi)存
應(yīng)用紋理
首先必須使用紋理坐標(biāo)更新頂點(diǎn)數(shù)據(jù):
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
必須調(diào)整前兩個(gè)頂點(diǎn)屬性的步幅參數(shù)8 * sizeof(float)
glEnableVertexAttribArray(2);