紋理翻轉(zhuǎn)解析

紋理翻轉(zhuǎn)解析

我們在使用紋理貼圖來渲染一張圖片的時,在解壓縮紋理圖像的過程中,畫出來的位圖原點是從圖像的左下角開始的,畫出的結(jié)果就是倒置的,怎么讓它翻轉(zhuǎn)過來呢?這就需要在圖片渲染過程中紋理相關(guān)的部分處理了。

原圖

上下倒置的鏡像圖

倒置圖看起來就像是原圖在水面上的倒影,是個上下倒置的鏡像圖。

1. 修改紋理坐標

首先,頂點坐標是和紋理坐標相對應(yīng)的。圖片角度不對,就依次改變頂點對應(yīng)的紋理坐標實現(xiàn)翻轉(zhuǎn)。數(shù)組中每行最后兩列的紋理坐標由:

GLfloat attrArr[] = {
    0.5f, -0.5f, -1.0f,     1.0f, 0.0f,
    -0.5f, 0.5f, -1.0f,     0.0f, 1.0f,
    -0.5f, -0.5f, -1.0f,    0.0f, 0.0f,
    
    0.5f, 0.5f, -1.0f,      1.0f, 1.0f,
    -0.5f, 0.5f, -1.0f,     0.0f, 1.0f,
    0.5f, -0.5f, -1.0f,     1.0f, 0.0f,
};

改為

GLfloat attrArr[] = {
    0.5f, -0.5f, -1.0f,     1.0f, 1.0f,
    -0.5f, 0.5f, -1.0f,     0.0f, 0.0f,
    -0.5f, -0.5f, -1.0f,    0.0f, 1.0f,

    0.5f, 0.5f, -1.0f,      1.0f, 0.0f,
    -0.5f, 0.5f, -1.0f,     0.0f, 0.0f,
    0.5f, -0.5f, -1.0f,     1.0f, 1.0f,
};

這種做法一勞永逸。但是需要一個一個對照著改,很麻煩。如果頂點很多,在修改紋理坐標時也是很費時的。

2.解壓圖片時翻轉(zhuǎn)

在渲染之前我們需要把png或者jpg之類的圖片進行解壓縮,而解壓縮其實就是重新繪制成位圖。在獲取圖片數(shù)據(jù)后,可以先把圖片翻轉(zhuǎn),然后再繪制。

使用Quartz中用戶空間和設(shè)備空間中間的轉(zhuǎn)換矩陣CTM實現(xiàn)。下面的圖畫的不是太準確,理解就好,不糾結(jié)。

CGRect rect = CGRectMake(0, 0, width, height);

CGContextTranslateCTM(bitmapContext, 0, rect.size.height);
CGContextScaleCTM(bitmapContext, 1, -1);

先下移一個圖片高度,再針對Y軸做一個鏡像。

QQ20190611-095926@2x.png

3. 使用旋轉(zhuǎn)矩陣

創(chuàng)建一個旋轉(zhuǎn)180度的矩陣,通過uniform通道傳給頂點著色器。

//1. rotate等于shaderv.vsh中的uniform屬性,rotateMatrix
GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix");
    
//2.獲取渲旋轉(zhuǎn)的弧度
float radians = 180 * (M_PI / 180.0f);
   
//3.求得弧度對于的sin\cos值
float s = sin(radians);
float c = cos(radians);
    
//4.定義旋轉(zhuǎn)矩陣
GLfloat zRotation[16] = {
    1,0,0,0,
    s,c,0,0,
    c,-s,0,0,
    0,0,0,1
};
    
//5.設(shè)置旋轉(zhuǎn)矩陣
glUniformMatrix4fv(rotate, 1, GL_FALSE, zRotation);

著色器部分把頂點向量和旋轉(zhuǎn)矩陣相乘或得一個旋轉(zhuǎn)后的頂點位置:

attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;

varying lowp vec2 varyTextCoord;

void main() {
    varyTextCoord = textCoordinate;

    vec4 vPos = position;
    vPos = vPos * rotateMatrix;
    
    gl_Position = vPos;
}

4.在頂點著色器中修改

用1.0減去紋理坐標的Y值,使y坐標反轉(zhuǎn)。片元著色器會對每個像素進行計算,調(diào)用次數(shù)很多,這里應(yīng)該盡量去掉不必要的操作。

attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;

void main()
{
    //varyTextCoord = textCoordinate;
    varyTextCoord = vec2(textCoordinate.x, 1.0 - textCoordinate.y);
    gl_Position = position;
}

5.在片元著色器中修改

同樣的方法也可以在頂點著色器中使用。頂點數(shù)據(jù)相對較少,不過也不建議寫不必要的操作。

varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main() {
//    gl_FragColor = texture2D(colorMap, varyTextCoord);
    gl_FragColor = texture2D(colorMap, vec2(varyTextCoord.x, 1.0 - varyTextCoord.y));
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容