OpenGL ES 案例07:GLSL使用索引繪圖 + 紋理顏色混合

OpenGL + OpenGL ES +Metal 系列文章匯總
本文案例代碼有OC及Swift版本脑融,詳情見文末鏈接喻频,講解以O(shè)C版本為主

本案例是在OpenGL ES 案例05:GLSL使用索引繪圖案例的基礎(chǔ)上新增紋理與顏色的混合填充功能

整體效果圖如下:


效果圖.gif

這個案例的思路很簡單肘迎,主要就是OpenGL ES 案例04:GLSL加載圖片OpenGL ES 案例05:GLSL使用索引繪圖案例中功能結(jié)合的一個綜合案例,下面主要針對新增的功能作一個說明

如圖所示窿侈,在案例05的基礎(chǔ)上,作了以下修改
注:圖中標(biāo)準(zhǔn)的(D诵恪6逖丁Q撑)即表示需要修改或者新增代碼的位置

整體修改圖示

主要需要修改和新增兩個部分

  • 自定義著色器
  • renderLayer函數(shù)

自定義著色器

主要是在頂點著色器和片元著色器中新增紋理相關(guān)的變量和源碼超凳,如下圖所示


自定義著色器修改圖示

頂點著色器

  • 新增attribute修飾的紋理坐標(biāo)
  • 新增varying修飾的橋接紋理坐標(biāo)
  • main函數(shù)中轮傍,將紋理坐標(biāo)賦值給橋接紋理坐標(biāo)
頂點著色器源碼

片元著色器

  • 新增與頂點中一致的橋接紋理坐標(biāo)
  • 新增uniform修飾的紋理采樣器
  • main函數(shù)中杭跪,計算每個像素的紋素并與頂點顏色混合驰吓,將最終的顏色值賦值給gl_FragColor
片元著色器源碼

片元著色器中檬贰,顏色混合方式有兩種

  • 直接使用GLSL的內(nèi)建函數(shù)mix(x, y, alpha),返回一個vec4類型的顏色值庄蹋,內(nèi)部的計算為x(1-alpha) +y*alpha
    vec4 weakMask = texture2D(colorMap, varyTextCoord);
    vec4 mask = varyColor;
    
//    mix(x,y,a) return x(1-a) +y*a
    gl_FragColor = mix(mask, weakMask, 0.3);
    vec4 weakMask = texture2D(colorMap, varyTextCoord);
    vec4 mask = varyColor;
    float alpha = 0.3;

    vec4 tempColor = mask * (1.0 - alpha) + weakMask * alpha;
    gl_FragColor = tempColor;

renderLayer函數(shù)

render函數(shù)修改圖示

render函數(shù)的主要功能是渲染蝙泼,由于新增了紋理顏色混合汤踏,主要修改的是設(shè)置頂點數(shù)據(jù)部分舔腾,需要增加紋理相關(guān)數(shù)據(jù)稳诚、加載等

修改頂點數(shù)組

增加頂點的紋理坐標(biāo)

 //前3個元素,是頂點數(shù)據(jù)才避;中間3個元素普办,是頂點顏色值徘钥,最后2個是紋理坐標(biāo)
    GLfloat attrArr[] =
    {
        -0.5f, 0.5f, 0.0f,      1.0f, 0.0f, 1.0f,       0.0f, 1.0f,//左上
        0.5f, 0.5f, 0.0f,       1.0f, 0.0f, 1.0f,       1.0f, 1.0f,//右上
        -0.5f, -0.5f, 0.0f,     1.0f, 1.0f, 1.0f,       0.0f, 0.0f,//左下
        
        0.5f, -0.5f, 0.0f,      1.0f, 1.0f, 1.0f,       1.0f, 0.0f,//右下
        0.0f, 0.0f, 1.0f,       0.0f, 1.0f, 0.0f,       0.5f, 0.5f,//頂點
    };

新增紋理相關(guān)操作

  • 處理紋理數(shù)據(jù)
    將紋理坐標(biāo)傳入到頂點著色器
  • 新增setupTexture函數(shù)呈础,用于加載紋理
  • 設(shè)置紋理采樣器
    用于采集紋理對應(yīng)像素點的顏色而钞,并傳入片元著色器中,與頂點顏色進(jìn)行混合

renderlayer函數(shù)中
新增紋理相關(guān)代碼如下

//    ---------處理紋理數(shù)據(jù)
    GLuint textCoord = glGetAttribLocation(self.myPrograme, "textCoordinate");
    glEnableVertexAttribArray(textCoord);
    glVertexAttribPointer(textCoord, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*8, (float*)NULL+6);
    
        
    //    ------加載紋理
    [self setupTexture:@"mouse"];
        
    //    ------設(shè)置紋理采樣器
    glUniform1i(glGetUniformLocation(self.myPrograme, "colorMap"), 0);

setupTexture函數(shù)
主要是將png/jpg圖片解壓成位圖撬陵,然后進(jìn)行綁定巨税、加載

- (GLuint)setupTexture: (NSString *)fileName{
//將UIImage轉(zhuǎn)換為CGImageRef
    CGImageRef image = [UIImage imageNamed:fileName].CGImage;
    
    if (!image) {
        NSLog(@"failed to load image %@", fileName);
        exit(1);
    }
    
    //獲取圖片的寬高
    size_t width = CGImageGetWidth(image);
    size_t height = CGImageGetHeight(image);
    
    //獲取圖片的字節(jié)數(shù)
    GLubyte *imageData = (GLubyte *)calloc(width*height*4, sizeof(GLubyte));
    
    //創(chuàng)建context & 使用默認(rèn)方式繪制圖片草添,即紋理的加載就是重新繪制圖片
    CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, width*4, CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
    
    CGRect rect = CGRectMake(0, 0, width, height);
    CGContextDrawImage(context, rect, image);
    CGContextRelease(context);
    
    //綁定紋理到默認(rèn)的標(biāo)識符0扼仲,0默認(rèn)是激活狀態(tài)
    glBindTexture(GL_TEXTURE_2D, 0);
    
    //設(shè)置紋理參數(shù)(過濾方式抄淑、環(huán)繞模式)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    float fw = width, fh = height;
    
    //加載紋理
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
    
    return 0;
}

完整的代碼見github - 11_02_GLSL三角形變換+紋理與顏色混合_OC肆资、11_02_GLSL三角形變換+紋理與顏色混合_Swift

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末迅耘,一起剝皮案震驚了整個濱河市颤专,隨后出現(xiàn)的幾起案子钠乏,更是在濱河造成了極大的恐慌,老刑警劉巖簇捍,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暑塑,死亡現(xiàn)場離奇詭異锅必,居然都是意外死亡,警方通過查閱死者的電腦和手機驹愚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門逢捺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劫瞳,“玉大人绷柒,你說我怎么就攤上這事』匝玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵憔恳,是天一觀的道長。 經(jīng)常有香客問我输硝,道長程梦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任郎逃,我火速辦了婚禮褒翰,結(jié)果婚禮上匀泊,老公的妹妹穿的比我還像新娘。我一直安慰自己揣非,他們只是感情好躲因,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布毛仪。 她就那樣靜靜地躺著芯勘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衡怀。 梳的紋絲不亂的頭發(fā)上安疗,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天荐类,我揣著相機與錄音,去河邊找鬼屈嗤。 笑死,一個胖子當(dāng)著我的面吹牛铁追,可吹牛的內(nèi)容都是我干的茫船。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涩禀,長吁一口氣:“原來是場噩夢啊……” “哼埋泵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丽声,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤雁社,失蹤者是張志新(化名)和其女友劉穎晒骇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徒坡,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡喇完,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年锦溪,在試婚紗的時候發(fā)現(xiàn)自己被綠了府怯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡则涯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肖揣,到底是詐尸還是另有隱情浮入,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布彤断,位于F島的核電站易迹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏供炼。R本人自食惡果不足惜窘疮,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一闸衫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔚出,春花似錦、人聲如沸稀余。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茁影。三九已至,卻和暖如春募闲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背靴患。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留农渊,地道東北人或颊。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓囱挑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親平挑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353