片元着色器 varying vec2 TexCoord; uniform sampler2D ourTexture;微信
void main() { gl_FragColor = texture(ourTexture, TexCoord); }函數
TexCoord 紋理座標,經過頂點着色器傳遞學習
ourTexture,紋理採樣器ui
片元着色器,是如何訪問紋理對象 首先,思考咱們是如何將紋理對象傳遞給片元着色器? GLSL 中提供一個共紋理對象使用的內建數據類型,叫作採樣器(sampler). 例如,sampler1D,sampler2D,sampler3D 表示不一樣維度的紋理類型. 那麼咱們在片元着色器是如何獲取一個紋理的? 咱們簡單聲明一個紋理對象. uniform sampler2D,將一個紋理添加片元着色器中. //聲明一個紋理對象 uniform sampler2D ourTexture;spa
如何獲取紋理對應像素點的顏色值 咱們可使用GLSL內建的texture函數來採樣紋理的顏色值. gl_FragColor = texture(ourTexture, TexCoord); //參數1: 紋理採樣器對象 //參數2: 紋理座標code
紋理單元 你可能會奇怪爲何sampler2D變量是個uniform,咱們卻不用glUniform給它賦值. 使用glUniform1i,咱們能夠給紋理採樣器分配一個位置值,這樣的話咱們可以在一個片斷着色器中設置多個紋理。 一個紋理的位置值一般稱爲一個紋理單元(Texture Unit)。一個紋理的默認紋理單元是0,它是默認的激活紋理單元. 紋理單元的主要目的是讓咱們在着色器中可使用多於一個的紋理。 經過把紋理單元賦值給採樣器,咱們能夠一次綁定多個紋理,只要咱們首先激活對應的紋理單元。就像glBindTexture同樣,咱們可使用glActiveTexture激活紋理單元,傳入咱們須要使用的紋理單元: //在綁定紋理以前先激活紋理單元 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture);orm
激活紋理單元以後,接下來的glBindTexture函數調用會綁定這個紋理到當前激活的紋理單元,紋理單元GL_TEXTURE0默認老是被激活.對象
OpenGL至少保證有16個紋理單元供你使用,也就是說你能夠激活從GL_TEXTURE0到GL_TEXTRUE15。它們都是按順序定義的,因此咱們也能夠經過GL_TEXTURE0 + 8的方式得到GL_TEXTURE8,這在當咱們須要循環一些紋理單元的時候會頗有用。圖片
varying vec2 TexCoord; uniform sampler2D ourTexture1; uniform sampler2D ourTexture2;ip
void main() { gl_FragColor = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2); }
最終輸出顏色是兩個紋理的結合。 GLSL內建的mix函數須要接受兩個值做爲參數,並對它們根據第三個參數進行線性插值。 若是第三個值是0.0,它會返回第一個輸入;若是是1.0,會返回第二個輸入值。輸入0.2則會返回80%的第一個輸入顏色和20%的第二個輸入顏色,即返回兩個紋理的混合色。 爲了使用第二個紋理(以及第一個),咱們必須改變一點渲染流程,先綁定兩個紋理到對應的紋理單元,而後定義哪一個uniform採樣器對應哪一個紋理單元: glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1);
注意,咱們使用glUniform1i設置uniform採樣器的位置值,或者說紋理單元。經過glUniform1i的設置,咱們保證每一個uniform採樣器對應着正確的紋理單元 關於紋理翻轉 OpenGL要求y軸0.0座標是在圖片的底部的,可是圖片的y軸0.0座標一般在頂部
咱們能夠改變頂點數據的紋理座標,翻轉y值(用1減去y座標)。 咱們能夠編輯頂點着色器來自動翻轉y座標,替換TexCoord的值爲TexCoord = vec2(texCoord.x, 1.0f - texCoord.y);。
iOS紋理翻轉解決策略 第1種: 旋轉矩陣翻轉圖形,不翻轉紋理
讓圖形頂點座標旋轉180°. 而紋理保持原狀.
GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix");
float radians = 180 * 3.14159f / 180.0f;
float s = sin(radians);
float c = cos(radians);
GLfloat zRotation[16] = {
c, -s, 0, 0,
s, c, 0, 0,
0, 0, 1.0, 0,
0.0, 0, 0, 1.0
};
複製代碼
glUniformMatrix4fv(rotate, 1, GL_FALSE, (GLfloat *)&zRotation[0]);
第2種: 解壓圖片時,將圖片源文件翻轉 CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
size_t width = CGImageGetWidth(spriteImage); size_t height = CGImageGetHeight(spriteImage); GLubyte * spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
CGRect rect = CGRectMake(0, 0, width, height); CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), 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);
CGContextRelease(spriteContext); glBindTexture(GL_TEXTURE_2D, 0);
第3種: 修改片元着色器,紋理座標 varying lowp vec2 varyTextCoord; uniform sampler2D colorMap; void main() { gl_FragColor = texture2D(colorMap, vec2(varyTextCoord.x,1.0-varyTextCoord.y)); }
第4種: 修改頂點着色器,紋理座標 attribute vec4 position; attribute vec2 textCoordinate; varying lowp vec2 varyTextCoord;
void main() { varyTextCoord = vec2(textCoordinate.x,1.0-textCoordinate.y); gl_Position = position; }
第5種:直接從源紋理座標數據修改 GLfloat attrArr[] = { 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, //右下 -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // 左上 -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // 左下 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // 右上 -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // 左上 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // 右下 }; */
小編這呢,給你們推薦一個優秀的iOS交流平臺,平臺裏的夥伴們都是很是優秀的iOS開發人員,咱們專一於技術的分享與技巧的交流,你們能夠在平臺上討論技術,交流學習。歡迎你們的加入(想要進入的可加小編微信)。
微信號:17336563535
來源:本文爲第三方轉載,若有侵權請聯繫小編刪除。