最近用GLSL實(shí)現(xiàn)渲染圖片,原始圖片是正常顯示的政冻,但是渲染出來(lái)的是倒置的枚抵,通過(guò)查找許多資料才明白是因?yàn)槭謾C(jī)的(0,0)點(diǎn)在左上角,紋理的(0,0)點(diǎn)在左下角明场,所以才會(huì)產(chǎn)生這樣的問(wèn)題,所以總結(jié)了下面5種紋理翻轉(zhuǎn)方法供大家參考也方便后期查閱李丰。
一苦锨、旋轉(zhuǎn)頂點(diǎn)坐標(biāo)
在頂點(diǎn)著色器中,將頂點(diǎn)坐標(biāo)叉乘一個(gè)180度旋轉(zhuǎn)矩陣趴泌。代碼如下:
-
頂點(diǎ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; }
-
旋轉(zhuǎn)矩陣輸入
//1. rotate等于shaderv.vsh中的uniform屬性舟舒,rotateMatrix GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix"); //2.獲取渲旋轉(zhuǎn)的弧度 float radians = 180 * 3.14159f / 180.0f; //3.求得弧度對(duì)于的sin\cos值 float s = sin(radians); float c = cos(radians); //4.因?yàn)樵?D課程中用的是橫向量,在OpenGL ES用的是列向量 /* 參考Z軸旋轉(zhuǎn)矩陣 */ GLfloat zRotation[16] = { c,-s,0,0, s,c,0,0, 0,0,1,0, 0,0,0,1 }; //5.設(shè)置旋轉(zhuǎn)矩陣 /* glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) location : 對(duì)于shader 中的ID count : 個(gè)數(shù) transpose : 轉(zhuǎn)置 value : 指針 */ glUniformMatrix4fv(rotate, 1, GL_FALSE, zRotation);
二嗜憔、解壓圖片時(shí)改變圖片坐標(biāo)
加載紋理時(shí)秃励,需要解壓圖片,此時(shí)通過(guò)平移縮放改變圖片坐標(biāo)吉捶,即可達(dá)成目的夺鲜。相關(guān)代碼如下:
-
圖片解壓、平移呐舔、縮放
//1币励、將 UIImage 轉(zhuǎn)換為 CGImageRef CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage; //判斷圖片是否獲取成功 if (!spriteImage) { NSLog(@"Failed to load image %@", fileName); exit(1); } //2、讀取圖片的大小珊拼,寬和高 size_t width = CGImageGetWidth(spriteImage); size_t height = CGImageGetHeight(spriteImage); //3.獲取圖片字節(jié)數(shù) 寬*高*4(RGBA) GLubyte * spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte)); //4.創(chuàng)建上下文 /* 參數(shù)1:data,指向要渲染的繪制圖像的內(nèi)存地址 參數(shù)2:width,bitmap的寬度食呻,單位為像素 參數(shù)3:height,bitmap的高度,單位為像素 參數(shù)4:bitPerComponent,內(nèi)存中像素的每個(gè)組件的位數(shù)澎现,比如32位RGBA仅胞,就設(shè)置為8 參數(shù)5:bytesPerRow,bitmap的沒(méi)一行的內(nèi)存所占的比特?cái)?shù) 參數(shù)6:colorSpace,bitmap上使用的顏色空間 kCGImageAlphaPremultipliedLast:RGBA */ CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); //5、在CGContextRef上--> 將圖片繪制出來(lái) /* CGContextDrawImage 使用的是Core Graphics框架剑辫,坐標(biāo)系與UIKit 不一樣干旧。UIKit框架的原點(diǎn)在屏幕的左上角,Core Graphics框架的原點(diǎn)在屏幕的左下角揭斧。 CGContextDrawImage 參數(shù)1:繪圖上下文 參數(shù)2:rect坐標(biāo) 參數(shù)3:繪制的圖片 */ CGRect rect = CGRectMake(0, 0, width, height); //6.使用默認(rèn)方式繪制 CGContextDrawImage(spriteContext, rect, spriteImage); CGContextTranslateCTM(spriteContext, rect.origin.x, rect.origin.y); CGContextTranslateCTM(spriteContext, 0, rect.size.height);//平移 CGContextScaleCTM(spriteContext, 1.0, -1.0);//縮放 CGContextTranslateCTM(spriteContext, -rect.origin.x, -rect.origin.y); CGContextDrawImage(spriteContext, rect, spriteImage); //7莱革、畫(huà)圖完畢就釋放上下文 CGContextRelease(spriteContext);
三峻堰、改變紋素獲取坐標(biāo)
在片元著色器中,改變紋素獲取的y值,即可達(dá)成目的盅视。
-
片元著色器代碼
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)); }
四捐名、改變紋理坐標(biāo)
在頂點(diǎn)著色器中,改變紋理坐標(biāo)的y值闹击,即可達(dá)成目的镶蹋。
-
頂點(diǎn)著色器代碼
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; }
五、直接改動(dòng)紋理坐標(biāo)數(shù)組
最復(fù)雜的方法赏半,但是最容易想到的贺归,就是在頂點(diǎn)、紋理坐標(biāo)數(shù)組里改變紋理坐標(biāo)值断箫。
-
數(shù)組改變代碼
//前3個(gè)是頂點(diǎn)坐標(biāo)拂酣,后2個(gè)是紋理坐標(biāo) // 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, };