OpenGL ES 2.0 (iOS)[02]:修復(fù)三角形的顯示


目錄

一茎杂、分析拉伸的原因

1、修復(fù)前后照片對比
2理澎、從問題到目標(biāo)逞力,分析原因

二、準(zhǔn)備知識糠爬,三維變換

1寇荧、4 x 4 方陣
2、線性變換(縮放與旋轉(zhuǎn))
3执隧、平移
4揩抡、向量(四元數(shù))
5户侥、w 與 其它

三、OpenGL 下的三維變換

1峦嗤、OpenGL 的坐標(biāo)系
2蕊唐、OpenGL 的 gl_Position 是行向量還是列向量
3、單次三維變換與多次三維變換問題
4烁设、OpenGL 的變換是在那個(gè)階段發(fā)生的替梨,如何發(fā)生

四、修復(fù)拉伸問題

1装黑、改寫 Shader Code
2副瀑、應(yīng)用 3D 變換知識,重新綁定數(shù)據(jù)
  1) 在 glLinkProgram 函數(shù)之后恋谭,利用 glGetUniformLocation 函數(shù)
     得到 uniform 變量的 location (內(nèi)存標(biāo)識符)
  2) 從 Render Buffer 得到屏幕的像素比(寬:高)值糠睡,即為縮小的值
  3) 使用 Shader Program , 調(diào)用 glUseProgram 函數(shù)
  4) 使用 3D 變換知識,得到一個(gè)縮放矩陣變量 scaleMat4
  5) 使用 glUniform* 函數(shù)把 scaleMat4 賦值給 uniform 變量
3疚颊、完整工程

一狈孔、分析拉伸的原因

1、修復(fù)前后照片對比

問題與目標(biāo)

圖片通過 sketch 制作

2串稀、從問題到目標(biāo)除抛,分析原因

1、它們的頂點(diǎn)數(shù)據(jù)均為:
頂點(diǎn)數(shù)組

VFVertex

2母截、借助 Matlab 把頂點(diǎn)數(shù)據(jù)繪制出來:


分布圖

從圖可以看出到忽,這三個(gè)數(shù)據(jù)形成的其實(shí)是一個(gè)等邊直角三角形,而在 iOS 模擬器中通過 OpenGL ES 繪制出來的是直角三角形清寇,所以是有問題的喘漏,三角形被拉伸了。

3华烟、on-Screen (屏幕) 的像素分布情況:

  1. iPhone6s Plus 屏幕:5.5寸翩迈,1920 x 1080 像素分辨率,明顯寬高比不是 1:1 的;

  2. OpenGL ES 的屏幕坐標(biāo)系 與 物理屏幕的坐標(biāo)系對比:


    OpenGL ES 的屏幕坐標(biāo)系

    物理屏幕的坐標(biāo)系

分析:前者是正方體盔夜,后者長方體负饲,不拉伸才怪钞它。

  1. 首先竖般,OpenGL 最后生成的都是像素信息罩锐,再顯示在物理屏幕上山叮;通過 1) 和 2) 可以知道 Y 方向的像素?cái)?shù)量大于 X 方向的像素?cái)?shù)量,導(dǎo)致真實(shí)屏幕所生成的 Y 軸與 X 軸的刻度不一致(就是Y=0.5 > X=0.5)戈咳,從而引起了最后渲染繪制出來的圖形是向 Y 方向拉伸了的缠局。

動(dòng)畫演示修復(fù):


FixTriangle.gif

所以要做的事情是拙毫,把頂點(diǎn)坐標(biāo)的 Y 坐標(biāo)變小蝇率,而且是要根據(jù)當(dāng)前顯示屏幕的像素比來進(jìn)行縮小迟杂。

Gif 圖片刽沾,由 C4D 制作,PS 最終導(dǎo)出排拷;

  1. 在 Shader 里面侧漓,v_Position 的數(shù)據(jù)類型是 vec4 ,即為4分量的向量數(shù)據(jù){x,y,z,w};就是說攻泼,要把這個(gè)向量通過數(shù)學(xué)運(yùn)算變成適應(yīng)當(dāng)前屏幕的向量火架。

二鉴象、準(zhǔn)備知識忙菠,三維變換

-- 建議 --:如果向量、矩陣知識不熟悉的可以看看《線性代數(shù)》一書纺弊;如果已經(jīng)有相應(yīng)的基礎(chǔ)了牛欢,可以直接看《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》,了解 3D 的世界是如何用向量和矩陣知識描述的淆游;若對 3D 知識有一定的認(rèn)識傍睹,可以直接看《OpenGL Programming Guide》8th 的變換知識, 或 《OpenGL Superblble》7th 的矩陣與變換知識,明確 OpenGL 是如何應(yīng)用這些知識進(jìn)行圖形渲染的犹菱。

注:以下核心知識均來源于拾稳,《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》,建議看一下第8章腊脱;

4x4 整體

圖片通過 sketch 制作访得,請放大看

1、4 x 4 方陣

4X4方陣
    1. 它其實(shí)就是一個(gè)齊次矩陣陕凹,是對3D運(yùn)算的一種簡便記法悍抑;
    1. 3x3矩陣并沒有包含平移,所以擴(kuò)展到4x4矩陣杜耙,從而可以引入平移的運(yùn)算搜骡;

2、線性變換(縮放與旋轉(zhuǎn))

線性變換
  • n佑女,是標(biāo)準(zhǔn)化向量记靡,而向量標(biāo)準(zhǔn)化就是指單位化:
    normalied

a、 v不能是零向量团驱,即零向量為{0摸吠,0,0}店茶;
b蜕便、||v||是向量的模,即向量的長度贩幻;
c轿腺、例子是2D向量的两嘴,3D/4D向量都是一樣的
【 sqrt(pow(x,2)+pow(y,2)+pow(w,2)...) 】

圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》5.7

  • k,是一個(gè)常數(shù)族壳;

  • a憔辫,是一個(gè)弧度角;

1) 線性縮放

線性縮放
  • XYZ 方向的縮放:


X方向仿荆,就是{1贰您,0,0}拢操;Y方向锦亦,就是{0,1令境,0}杠园;Z方向,就是{0舔庶,0抛蚁,1};分別代入上面的公式即可得到惕橙。

圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》8.3.1

2) 線性旋轉(zhuǎn)

線性旋轉(zhuǎn)
  • X方向{1瞧甩,0,0}的旋轉(zhuǎn):


  • Y方向{0弥鹦,1肚逸,0}的旋轉(zhuǎn):


  • Z方向{0,0惶凝,1}的旋轉(zhuǎn):


圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》8.2.2

3吼虎、平移

平移

直接把平移向量,按分量{x, y, z}依次代入齊次矩陣即可苍鲜;

圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》9.4.2

4思灰、向量(四元數(shù))

四元數(shù)

a.向量,即4D向量混滔,也稱齊次坐標(biāo){x, y, z, w}; 4D->3D洒疚,{x/w, y/w, z/w};

b.四元數(shù)坯屿,[ w, v ]或[ w, (x,y,z) ]兩種記法油湖,其中 w 就是一個(gè)標(biāo)量,即一個(gè)實(shí)數(shù)领跛;

c.點(diǎn)乘

矩陣乘法乏德,點(diǎn)乘

c.1 上面兩種是合法的,而下面兩種是不合法的,就是沒有意義的喊括;
c.2 第一個(gè)為 A(1x3) 行向量(矩陣)與 B(3x3)方陣的點(diǎn)乘胧瓜,第二個(gè)是 A(3x3) 的方陣與 A(3x1) 的列向量(矩陣)的點(diǎn)乘;

圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》7.1.7

5郑什、w 與 其它

這塊內(nèi)容現(xiàn)在先不深究府喳,不影響對本文內(nèi)容的理解。

  • W
    w

w蘑拯,與平移向量{x, y, z}組成齊次坐標(biāo)钝满;一般情況下,都是1申窘;

  • 投影
    投影

這里主要是控制投影弯蚜,如透視投影;如:


圖片來源于《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》9.4.6


三偶洋、OpenGL 下的三維變換

這里主要討論第一階段 Vertex 的 3D 變換熟吏,對于視圖變換、投影變換玄窝,不作過多討論;如果要完全掌握后面兩個(gè)變換悍引,還需要掌握 OpenGL 下的多坐標(biāo)系系統(tǒng)恩脂,以及攝像機(jī)系統(tǒng)的相關(guān)知識。

1趣斤、OpenGL 的坐標(biāo)系

  • 坐標(biāo)系方向定義分兩種:


圖片來源于俩块,《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》8.1;左右手坐標(biāo)系是用來定義方向的浓领。

  • 旋轉(zhuǎn)的正方向


    右手坐標(biāo)

圖片來源于玉凯,Diney Bomfim 的《Cameras on OpenGL ES 2.x - The ModelViewProjection Matrix》;這個(gè)就是 OpenGL 使用的坐標(biāo)系联贩,右手坐標(biāo)系漫仆;其中白色小手演示了在各軸上旋轉(zhuǎn)的正方向(黑色箭頭所繞方向);

2泪幌、OpenGL 的 gl_Position 是行向量還是列向量

  • 這里討論的核心是盲厌,gl_Position 接收的是 行向量,還是列向量祸泪?
行向量
列向量
  • 討論行列向量的目的是明確吗浩,3D 矩陣變換在做乘法的時(shí)候是使用左乘還是右乘;

圖片來源于没隘,《線性代數(shù)》矩陣及其運(yùn)算一節(jié)

從圖中的結(jié)果就可以看出懂扼,左乘和右乘運(yùn)算后是完全不一樣的結(jié)果;雖然圖片中的矩陣是 2 x 2 方陣右蒲,但是擴(kuò)展到 n x n 也是一樣的結(jié)果阀湿;

  • 那么 OpenGL 使用的是什么向量屡限?
圖1,列向量
  • 英文大意:矩陣和矩陣乘法在處理坐標(biāo)系顯示模型方面是一個(gè)非常有用的途徑炕倘,而且對于處理線性變換而言也是非常方便的機(jī)制钧大。
圖2

紅框處的向量就是 v_Position 頂點(diǎn)數(shù)據(jù);即 OpenGL 用的是列向量罩旋;(木有找到更有力的證據(jù)啊央,只能這樣了)

  • 左乘右乘問題?
圖3
  • 英文大意:在我們的視圖模型中涨醋,我們想通過一個(gè)向量來與矩陣變換進(jìn)行乘法運(yùn)算瓜饥,這里描述了一個(gè)矩陣乘法,向量先乘以 A 矩陣再乘以 B 矩陣:

很明顯浴骂,例子使用的就是左乘乓土,即 OpenGL 用的是左乘;

圖 1溯警、3 來源于趣苏,《OpenGL Programming Guide 8th》第5章第二節(jié)
圖 2 來源于,《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》7.1.8

3梯轻、單次三維變換與多次三維變換問題

多次變換
  1. OpenGL 的三維變換整體圖:
4x4 整體 OpenGL

因?yàn)榱邢蛄康挠绊懯晨模谧鳇c(diǎn)乘的時(shí)候,平移放在下方與右側(cè)是完全不一樣的結(jié)果喳挑,所以進(jìn)行了適應(yīng)性修改

  • 平移部分的內(nèi)容:
4X4方陣 OpenGL
平移 OpenGL
  • 矩陣平移公式

等式左側(cè):A(4x4)方陣點(diǎn)乘{(lán)v.x, v.y, v.z, 1.0}是頂點(diǎn)數(shù)據(jù)列向量彬伦;右側(cè)就是一個(gè) xyz 均增加一定偏移的列向量

圖片來源于,《OpenGL Superblble》7th, Part 1, Chapter 4. Math for 3D Graphics

  • 投影(就是零)
投影 OpenGL
  1. 所有的變換圖例演示

物體的坐標(biāo)是否與屏幕坐標(biāo)原點(diǎn)重疊

Linaer Transforms
  • 單次變換(原點(diǎn)重疊)
Identity

無變換伊诵,即此矩陣與任一向量相乘单绑,不改變向量的所有分量值,能做到這種效果的就是單位矩陣曹宴,而我們使用的向量是齊次坐標(biāo){x, y, z, w}搂橙,所以使用 4 x 4 方陣;{w === 1}.

  • 縮放
Scale

單一的線性變換——縮放浙炼,縮放變換是作用在藍(lán)色區(qū)域的 R(3x3) 方陣的正對角線(從m11(x)->m22(y)->m33(z))中;例子是 X份氧、Y、Z 均放大 3 倍弯屈。

  • 旋轉(zhuǎn)
Rotate

單一的線性變換——旋轉(zhuǎn)蜗帜,旋轉(zhuǎn)變換是作用在藍(lán)色區(qū)域的 R(3x3) 方陣中;例子是繞 Z 軸旋轉(zhuǎn) 50 度。

  • 平移
Translation

單一的線性變換——平移资厉,平移變換是作用在綠色區(qū)域的 R(3x1) 矩陣中({m11, m21, m31}對應(yīng){x, y, z});例子是沿 X 正方向平移 2.5 個(gè)單位厅缺。

  • 單次變換(原點(diǎn)不重疊)
Translation&Scale
Translation&Rotate

以上圖片內(nèi)容來源于《OpenGL Programming Guide》8th, Linear Transformations and Matrices 一小節(jié),使用 skecth 重新排版并導(dǎo)出

  1. 多次變換
連續(xù)變換

這里的問題就是先旋轉(zhuǎn)還是后旋轉(zhuǎn)。旋轉(zhuǎn)前后湘捎,變化的是物體的坐標(biāo)系(虛線(變換后)诀豁,實(shí)線(變換前)),主要是看你要什么效果窥妇,而不是去評論它的對錯(cuò)舷胜。

圖片來源于,《OpenGL Superblble》7th, Matrix Construction and Operators 一節(jié)活翩;

4烹骨、OpenGL 的變換是在那個(gè)階段發(fā)生的,如何發(fā)生

3D變換

ES 主要看紅框處的頂點(diǎn)著色階段即可材泄,所以我們的變換代碼是寫在 Vertex Shader 的文件中沮焕。

變換轉(zhuǎn)換

這里描述了三個(gè)變換階段,第一個(gè)階段是模型變換拉宗,第二個(gè)是視圖變換階段峦树,第三個(gè)是投影變換階段,最后出來的才是變換后的圖形旦事。本文討論的是第一個(gè)階段魁巩。

詳細(xì)過程

作為了解即可

以上圖片均來源于,《OpenGL Programming Guide》8th, 5. Viewing Transformations, Clipping, and Feedback 的 User Transformations 一節(jié)族檬;


四歪赢、修復(fù)拉伸問題

1、改寫 Shader Code

增加了一個(gè) uniform 變量单料,而且是 mat4 的矩陣類型,同時(shí)左乘于頂點(diǎn)數(shù)據(jù)点楼;

  • 為什么使用 uniform 變量扫尖?
    • 首先, Vertex Shader 的輸入量可以是 : attribute掠廓、unforms换怖、samplers、temporary 四種;
    • 其次蟀瞧,我們的目的是把每一個(gè)頂點(diǎn)都縮小一個(gè)倍數(shù)沉颂,也就是它是一個(gè)固定的變量,即常量悦污,所以排除 arrribute铸屉、temporary ;
    • 同時(shí)切端,既然是一個(gè)常量數(shù)據(jù)彻坛,那么 samplers 可以排除,所以最后使用的是 uniforms 變量;
  • 為什么使用 mat4 類型昌屉?
    v_Position 是{x, y, z, w}的列向量钙蒙,即為 4 x 1 的矩陣,如果要最終生成 gl_Position 也是 4 x 1 的列向量间驮,那么就要左乘一個(gè) 4 x 4 方陣躬厌;而 mat4 就是 4 x 4 方陣。

補(bǔ)充:n x m · 4 x 1 -> 4 x 1竞帽,如果要出現(xiàn)最終 4 x 1 那么扛施,n 必須要是 4;如果矩陣點(diǎn)乘成立抢呆,那么 m 必須要是 4; 所以最終結(jié)果是 n x m = 4 x 4 ;

2煮嫌、應(yīng)用 3D 變換知識,重新綁定數(shù)據(jù)

這里主要解決抱虐,如何給 uniform 變量賦值昌阿,而且在什么時(shí)候進(jìn)行賦值的問題

核心步驟

1、在 glLinkProgram 函數(shù)之后恳邀,利用 glGetUniformLocation 函數(shù)得到 uniform 變量的 location (內(nèi)存標(biāo)識符);

2懦冰、從 Render Buffer 得到屏幕的像素比(寬:高)值,即為縮小的值;

3谣沸、使用 Shader Program , 調(diào)用 glUseProgram 函數(shù);

4刷钢、使用 3D 變換知識,得到一個(gè)縮放矩陣變量 scaleMat4;

5乳附、使用 glUniform* 函數(shù)把 scaleMat4 賦值給 uniform 變量;

  • 如何給 uniform 變量賦值内地?

1、得到 uniform 的內(nèi)存標(biāo)識符

要在 glLinkProgram 后赋除,再獲取 location 值阱缓,因?yàn)橹挥墟溄雍?Program 才會(huì) location 的值

- (BOOL)linkShaderWithProgramID:(GLuint)programID {
    // 綁定 attribute 變量的下標(biāo)
    // 如果使用了兩個(gè)或以上個(gè) attribute 一定要綁定屬性的下標(biāo),不然會(huì)找不到數(shù)據(jù)源的
    // 因?yàn)槭褂昧艘粋€(gè)的時(shí)候举农,默認(rèn)訪問的就是 0 位置的變量荆针,必然存在的,所以才不會(huì)出錯(cuò)
    [self bindShaderAttributeValuesWithShaderProgramID:programID];
    // 鏈接 Shader 到 Program
    glLinkProgram(programID);
    // 獲取 Link 信息
    GLint linkSuccess;
    glGetProgramiv(programID, GL_LINK_STATUS, &linkSuccess);
    if (linkSuccess == GL_FALSE) {
        GLint infoLength;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLength);
        if (infoLength > EmptyMessage) {
            GLchar *messages = malloc(sizeof(GLchar *) * infoLength);
            glGetProgramInfoLog(programID, infoLength, NULL, messages);
            NSString *messageString = [NSString stringWithUTF8String:messages];
            NSLog(@"Error: Link Fail %@ !", messageString);
            free(messages);
        }
        return Failure;
    }
    // 在這里
    [self.shaderCodeAnalyzer updateActiveUniformsLocationsWithShaderFileName:@"VFVertexShader"
                                                                   programID:programID];
    return Successfully;
}
- (void)updateActiveUniformsLocationsWithShaderFileName:(NSString *)fileName programID:(GLuint)programID {
    
    NSDictionary *vertexShaderValueInfos = self.shaderFileValueInfos[fileName];
    ValueInfo_Dict *uniforms = vertexShaderValueInfos[UNIFORM_VALUE_DICT_KEY];
    
    NSArray *keys = [uniforms allKeys];
    for (NSString *uniformName in keys) {
        const GLchar * uniformCharName = [uniformName UTF8String];
        // 在這里
        GLint location = glGetUniformLocation(programID, uniformCharName); 
        VFShaderValueInfo *info = uniforms[uniformName];
        info.location = location;
    }
    
}

補(bǔ)充:

glGetActiveUniform
void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, char* name)
program 指 Shader Program 的內(nèi)存標(biāo)識符
index 指下標(biāo)颁糟,第幾個(gè) uniform 變量航背,[0, activeUniformCount]
bufSize 所有變量名的字符個(gè)數(shù),如:v_Projection , 就有 12 個(gè)棱貌,如果還定義了 v_Translation 那么就是12 + 13 = 25個(gè)
length * NULL 即可*
size 數(shù)量玖媚,uniform 的數(shù)量,如果不是 uniform 數(shù)組键畴,就寫 1最盅,如果是數(shù)組就寫數(shù)組的長度
type uniform 變量的類型突雪,GL_FLOAT, GL_FLOAT_VEC2,GL_FLOAT_VEC3, GL_FLOAT_VEC4,GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4, GL_BOOL,GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4,GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FLOAT_MAT4,GL_SAMPLER_2D, GL_SAMPLER_CUBE
name uniform 變量的變量名
// 這個(gè)函數(shù)可以得到,正在使用的 uniform 個(gè)數(shù)涡贱,即可以知道 index 是從 0 到幾咏删;
// 還有可以得到,bufSize 的長度
glGetProgramiv(progObj, GL_ACTIVE_UNIFORMS, &numUniforms);
glGetProgramiv(progObj, GL_ACTIVE_UNIFORM_MAX_LENGTH,
&maxUniformLen);

注:VFShaderValueRexAnalyzer 類就是一個(gè)方便進(jìn)行調(diào)用的一種封裝而已问词,你可以使用你喜歡的方式進(jìn)行封裝督函;

圖片來源于,《OpenGL ES 2.0 Programming Guide》4. Shaders and Programs,Uniforms and Attributes 一節(jié)

  • 在什么時(shí)候進(jìn)行賦值操作激挪?
    一定要在 glUseProgram 后再進(jìn)行賦值操作辰狡,不然無效
- (void)drawTriangle {

    [self.shaderManager useShader];
    [self.vertexManager makeScaleToFitCurrentWindowWithScale:[self.rboManager windowScaleFactor]];
    [self.vertexManager draw];
    [self.renderContext render];
    
}

2、得到屏幕的像素比

- (CGFloat)windowScaleFactor {
    
    CGSize renderSize = [self renderBufferSize];
    float scaleFactor = (renderSize.width / renderSize.height);
    
    return scaleFactor;
    
}

補(bǔ)充:renderBufferSize

- (CGSize)renderBufferSize {
    GLint renderbufferWidth, renderbufferHeight;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderbufferWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderbufferHeight);
    return CGSizeMake(renderbufferWidth, renderbufferHeight);
}

3垄分、使用 Shader Program

- (void)useShader {
    
    glUseProgram(self.shaderProgramID);
    
}

4宛篇、使用 3D 變換知識,得到一個(gè)縮放矩陣變量 scaleMat4

 VFMatrix4 scaleMat4 = VFMatrix4MakeScaleY(scale);

擴(kuò)展1:

    VFMatrix4 VFMatrix4MakeXYZScale(float sx, float sy, float sz) {
        VFMatrix4 r4 = VFMatrix4Identity;
        VFMatrix4 _mat4 = {
              sx  , r4.m12, r4.m13, r4.m14,
            r4.m21,   sy  , r4.m23, r4.m24,
            r4.m31, r4.m32,   sz  , r4.m34,
            r4.m41, r4.m42, r4.m43, r4.m44,
        };
        return _mat4;
    };
    VFMatrix4 VFMatrix4MakeScaleX(float sx) {
        return VFMatrix4MakeXYZScale(sx, 1.f, 1.f);
    };
    VFMatrix4 VFMatrix4MakeScaleY(float sy) {
        return VFMatrix4MakeXYZScale(1.f, sy, 1.f);
    };
    VFMatrix4 VFMatrix4MakeScaleZ(float sz) {
        return VFMatrix4MakeXYZScale(1.f, 1.f, sz);
    };

它們都定義在:


VFMath

注:如果不想自己去寫這些函數(shù)薄湿,那么可以直接使用 GLKit 提供的

數(shù)學(xué)函數(shù)

個(gè)人建議叫倍,自己去嘗試寫一下會(huì)更好

5、使用 glUniform 函數(shù)把 scaleMat4 賦值給 uniform 變量*

- (void)makeScaleToFitCurrentWindowWithScale:(float)scale {
    
    NSDictionary *vertexShaderValueInfos = self.shaderCodeAnalyzer.shaderFileValueInfos[@"VFVertexShader"];
    ValueInfo_Dict *uniforms = vertexShaderValueInfos[UNIFORM_VALUE_DICT_KEY];
//    NSLog(@"uniforms %@", [uniforms allKeys]);
    
    // v_Projection 投影
//    VFMatrix4 scaleMat4 = VFMatrix4Identity;
    VFMatrix4 scaleMat4 = VFMatrix4MakeScaleY(scale);
    VFMatrix4 transMat4 = VFMatrix4Identity; //VFMatrix4MakeTranslationX(0.3)
    glUniformMatrix4fv((GLint)uniforms[@"v_Projection"].location,   // 定義的 uniform 變量的內(nèi)存標(biāo)識符
                       1,                                           // 不是 uniform 數(shù)組豺瘤,只是一個(gè) uniform -> 1
                       GL_FALSE,                                    // ES 下 只能是 False
                       (const GLfloat *)scaleMat4.m1D);             // 數(shù)據(jù)的首指針
    
    glUniformMatrix4fv((GLint)uniforms[@"v_Translation"].location,   // 定義的 uniform 變量的內(nèi)存標(biāo)識符
                       1,                                           // 不是 uniform 數(shù)組吆倦,只是一個(gè) uniform -> 1
                       GL_FALSE,                                    // ES 下 只能是 False
                       (const GLfloat *)transMat4.m1D);             // 數(shù)據(jù)的首指針

}

擴(kuò)展2:

  • 賦值函數(shù)有那些?
    它們分別是針對不同的 uniform 變量進(jìn)行的賦值函數(shù)


3坐求、完整工程:Github: DrawTriangle_Fix

glsl 代碼分析類


核心的知識是正則表達(dá)式蚕泽,主要是把代碼中的變量解析出來,可以對它們做大規(guī)模的處理桥嗤。有興趣可以看一下须妻,沒有興趣的可以忽略它完全不影響學(xué)習(xí)和練習(xí)本文的內(nèi)容。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泛领,一起剝皮案震驚了整個(gè)濱河市璧南,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌师逸,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豆混,死亡現(xiàn)場離奇詭異篓像,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)皿伺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門员辩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鸵鸥,你說我怎么就攤上這事奠滑〉ぶ澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵宋税,是天一觀的道長摊崭。 經(jīng)常有香客問我,道長杰赛,這世上最難降的妖魔是什么呢簸? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮乏屯,結(jié)果婚禮上根时,老公的妹妹穿的比我還像新娘。我一直安慰自己辰晕,他們只是感情好蛤迎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著含友,像睡著了一般替裆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唱较,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天扎唾,我揣著相機(jī)與錄音,去河邊找鬼南缓。 笑死胸遇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汉形。 我是一名探鬼主播纸镊,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼概疆!你這毒婦竟也來了逗威?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤岔冀,失蹤者是張志新(化名)和其女友劉穎凯旭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體使套,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罐呼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侦高。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫉柴。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奉呛,靈堂內(nèi)的尸體忽然破棺而出计螺,到底是詐尸還是另有隱情夯尽,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布登馒,位于F島的核電站匙握,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谊娇。R本人自食惡果不足惜肺孤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望济欢。 院中可真熱鬧赠堵,春花似錦、人聲如沸法褥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽半等。三九已至揍愁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杀饵,已是汗流浹背莽囤。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留切距,地道東北人朽缎。 一個(gè)月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像谜悟,于是被迫代替她去往敵國和親话肖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容