目錄
一茎杂、分析拉伸的原因
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ù)前后照片對比
圖片通過 sketch 制作
2串稀、從問題到目標(biāo)除抛,分析原因
1、它們的頂點(diǎn)數(shù)據(jù)均為:2母截、借助 Matlab 把頂點(diǎn)數(shù)據(jù)繪制出來:
從圖可以看出到忽,這三個(gè)數(shù)據(jù)形成的其實(shí)是一個(gè)等邊直角三角形,而在 iOS 模擬器中通過 OpenGL ES 繪制出來的是直角三角形清寇,所以是有問題的喘漏,三角形被拉伸了。
3华烟、on-Screen (屏幕) 的像素分布情況:
iPhone6s Plus 屏幕:5.5寸翩迈,1920 x 1080 像素分辨率,明顯寬高比不是 1:1 的;
-
OpenGL ES 的屏幕坐標(biāo)系 與 物理屏幕的坐標(biāo)系對比:
OpenGL ES 的屏幕坐標(biāo)系
物理屏幕的坐標(biāo)系
分析:前者是正方體盔夜,后者長方體负饲,不拉伸才怪钞它。
- 首先竖般,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ù):
所以要做的事情是拙毫,把頂點(diǎn)坐標(biāo)的 Y 坐標(biāo)變小蝇率,而且是要根據(jù)當(dāng)前顯示屏幕的像素比來進(jìn)行縮小迟杂。
Gif 圖片刽沾,由 C4D 制作,PS 最終導(dǎo)出排拷;
- 在 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章腊脱;
圖片通過 sketch 制作访得,請放大看
1、4 x 4 方陣
- 它其實(shí)就是一個(gè)齊次矩陣陕凹,是對3D運(yùn)算的一種簡便記法悍抑;
- 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)
-
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ù))
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 使用的是什么向量屡限?
- 英文大意:矩陣和矩陣乘法在處理坐標(biāo)系顯示模型方面是一個(gè)非常有用的途徑炕倘,而且對于處理線性變換而言也是非常方便的機(jī)制钧大。
紅框處的向量就是 v_Position 頂點(diǎn)數(shù)據(jù);即 OpenGL 用的是列向量罩旋;(木有找到更有力的證據(jù)啊央,只能這樣了)
- 左乘右乘問題?
- 英文大意:在我們的視圖模型中涨醋,我們想通過一個(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梯轻、單次三維變換與多次三維變換問題
- OpenGL 的三維變換整體圖:
因?yàn)榱邢蛄康挠绊懯晨模谧鳇c(diǎn)乘的時(shí)候,平移放在下方與右側(cè)是完全不一樣的結(jié)果喳挑,所以進(jìn)行了適應(yīng)性修改
- 平移部分的內(nèi)容:
- 矩陣平移公式
等式左側(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
- 投影(就是零)
- 所有的變換圖例演示
物體的坐標(biāo)是否與屏幕坐標(biāo)原點(diǎn)重疊
- 單次變換(原點(diǎn)重疊)
無變換伊诵,即此矩陣與任一向量相乘单绑,不改變向量的所有分量值,能做到這種效果的就是單位矩陣曹宴,而我們使用的向量是齊次坐標(biāo){x, y, z, w}搂橙,所以使用 4 x 4 方陣;{w === 1}.
- 縮放
單一的線性變換——縮放浙炼,縮放變換是作用在藍(lán)色區(qū)域的 R(3x3) 方陣的正對角線(從m11(x)->m22(y)->m33(z))中;例子是 X份氧、Y、Z 均放大 3 倍弯屈。
- 旋轉(zhuǎn)
單一的線性變換——旋轉(zhuǎn)蜗帜,旋轉(zhuǎn)變換是作用在藍(lán)色區(qū)域的 R(3x3) 方陣中;例子是繞 Z 軸旋轉(zhuǎn) 50 度。
- 平移
單一的線性變換——平移资厉,平移變換是作用在綠色區(qū)域的 R(3x1) 矩陣中({m11, m21, m31}對應(yīng){x, y, z});例子是沿 X 正方向平移 2.5 個(gè)單位厅缺。
- 單次變換(原點(diǎn)不重疊)
以上圖片內(nèi)容來源于《OpenGL Programming Guide》8th, Linear Transformations and Matrices 一小節(jié),使用 skecth 重新排版并導(dǎo)出
- 多次變換
這里的問題就是先旋轉(zhuǎn)還是后旋轉(zhuǎn)。旋轉(zhuǎn)前后湘捎,變化的是物體的坐標(biāo)系(虛線(變換后)诀豁,實(shí)線(變換前)),主要是看你要什么效果窥妇,而不是去評論它的對錯(cuò)舷胜。
圖片來源于,《OpenGL Superblble》7th, Matrix Construction and Operators 一節(jié)活翩;
4烹骨、OpenGL 的變換是在那個(gè)階段發(fā)生的,如何發(fā)生
ES 主要看紅框處的頂點(diǎn)著色階段即可材泄,所以我們的變換代碼是寫在 Vertex Shader 的文件中沮焕。
這里描述了三個(gè)變換階段,第一個(gè)階段是模型變換拉宗,第二個(gè)是視圖變換階段峦树,第三個(gè)是投影變換階段,最后出來的才是變換后的圖形旦事。本文討論的是第一個(gè)階段魁巩。
作為了解即可
以上圖片均來源于,《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);
};
它們都定義在:
注:如果不想自己去寫這些函數(shù)薄湿,那么可以直接使用 GLKit 提供的
個(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)容。