OpenGL的變換

OpenGL ES 中有兩套矩陣,都是4×4的GLfloat矩陣。一個叫 modelview matrix ,你大部分時間都會與之打交道。它是你用來對虛擬世界進行變換的矩陣。要對虛擬世界中的物體進行旋轉,轉移或尺寸變化,你都需要對此矩陣進行修改。
另一個矩陣用來創建根據設定的視口對世界坐標進行描述的二維表示。此矩陣稱為 projection matrix 。在絕大部分時間內,你都不需要接觸該矩陣。
從三維空間到二維平面,就如同用相機拍照一樣,通常都要經歷以下幾個步驟 (括號內表示的是相應的圖形學概念):
第一步,將相機置於三角架上,讓它對准三維景物(
視點變換,Viewing Transformation)。
第二步,將三維物體放在適當的位置(
模型變換,Modeling Transformation)。
第三步,選擇相機鏡頭並調焦,使三維物體投影在二維膠片上(
投影變換,Projection Transformation)。
第四步,決定二維像片的大小(
視口變換,Viewport Transformation)。
這樣,一個三維空間里的物體就可以用相應的二維平面物體表示了,也就能在二維的電腦屏幕上正確顯示了。
變換后的x坐標范圍是[-1, 1],y坐標范圍是[-1, 1],z坐標范圍是[0, 1](OpenGL略有不同,z值范圍是[-1, 1])。
因為在光柵化之前,我們需要對z坐標的倒數進行插值(原因請參見Mathematics for 3D Game Programming and Computer Grahpics 3rd section 5.4),所以可以將z''寫成z的一次表達式形式,如下
這個導致如果z坐標不在視錐體內的點,最后的z坐標范圍會大於[-1, 1],導致不顯示。
着色
Flat coloring(單色)
是通知OpenGL使用單一的顏色來渲染,OpenGL將一直使用指定的顏色來渲染直到你指定其它的顏色。
指定顏色的方法為
public abstract void glColor4f(float red, float green, float blue, float alpha)。
缺省的red,green,blue為1,代表白色。
Smooth coloring (平滑顏色過渡)
當給每個頂點定義一個顏色時,OpenGL自動為不同頂點顏色之間生成中間過渡顏色(漸變色)。
OpenGL 支持兩種着色模式:單調着色(Flat)與平滑着色(smooth,也稱Gouraud着色)。單調着色就是整個圖元的顏色就是它的任何一個頂點的顏色,比如教程02中的紅色三角形效果;平滑着色下每個頂點都是單獨進行的,頂點之間的點是所有頂點顏色的均勻插值計算而得。
在 OpenGL 中,全局環境光的強度為 (0.2, 0.2, 0.2, 1.0),這弱弱的白色全局環境光確保即使沒有額外的光源,場景中的物體依然是可見的。
gl_FragCoord根據glsl language spec的解釋為:
它是fragment shaders的輸入變量,並持有該framgent的屏幕相對坐標(x, y, z, 1/w)
深度測試
GL_POLYGON_OFFSET_FILL
The value of the offset is factor * DZ + bias, where DZ is a measurement of the change in z relative to the screen area of the polygon. The offset is added before the Depth Test is performed and before the value is written into the Depth Buffer.
在進行深度測試和寫入深度緩沖區之前,會把深度值加上一個offset。offset的計算公式是factor * DZ + bias,其中factor和bias是由glPolygonOffset指定
深度緩存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
CAEAGLLayer
顯示比例不對,屏幕大小只有320*480.
contentsScale屬性定義了寄宿圖的像素尺寸和視圖大小的比例
限定符賦給變量特殊的含義:
const-- 用於聲明非可寫的編譯時常量變量
attribute-- 用於經常更改的信息,
只可以在頂點着色器中使用
uniform-- 用於
不經常更改的信息,用於頂點着色器和片元着色器
varying-- 用於從頂點着色器傳遞到片元着色器的
插值信息
GLSL內建變量
Vertex Shader的輸出數據時使用的內置變量:
vec4
gl_posotion; 用來設置頂點轉換到屏幕坐標的位置,Vertex Shader一定要去更新這個數值
float
gl_pointSize; 是啟動PointSprite功能時,用來設置矩形大小的數值
vec4 gl_ClipVertex; 如果啟用了Clip Plane功能,gl_ClipVertex可以放入用來與Clip Plane平面做測試用的位置
Fragment Shader的內置輸出變量:
vec4
gl_FragColor; 代表畫面所要填入的顏色
vec4 gl_FragData[gl_MaxDrawBuffers]; 用來填入畫面的顏色,用在啟用多個FrameBuffer時,調用gl_FragData填入畫面顏色
vec4 gl_FrData填入畫面顏色
vec4
gl_FragDepth; 用來指定Z Buffer測試時所使用的Z值,這樣就可以不通過頂點內插得到的Z值
GLSL
GLSL是嚴格的類型匹配,int和float不會默認互轉;
着色語言定了三種級別的精度:lowp, mediump, highp。我們可以在 glsl 腳本文件的開頭定義默認的精度。
precision mediump float;
注意,在片着色器,不會有默認的精度,所以如果沒有上面這一句,會有編譯錯誤哦;
OpenGL
寫 OpenGL 代碼時從前到后的順序依次是:設定 viewport(視口變換),設定投影變換,設定視圖變換,設定模型變換,在本地坐標空間描繪物體。而在前面為了便於理解做介紹時,說的順序是
OpenGL 中物體最初是在本地坐標空間中,然后轉換到世界坐標空間,再到 camera 視圖空間,再到投影空間。由於模型變換包括了本地空間變換到世界坐標空間,所以我們
理解3D 變換是一個順序,而真正寫代碼時則是以相反的順序進行的,如果從左乘矩陣這點上去理解就很容易明白為什么會是反序的。
用數組表示 Matrix 又分為兩種形式:行主序和列主序,它們在本質上是等價的,只不過是一個是右乘(行主序,矩陣放右邊)和一個是左乘(列主序,矩陣放左邊)。
OpenGL 使用列主序矩陣,即列矩陣,
因此我們總是倒過來算的(左乘矩陣,變換效果是按從右向左的順序進行): 投影矩陣 × 視圖矩陣 × 模型矩陣 × 3D位置。
glUniform2fv 參數的count 是glsl里面vec2 vecArr[3]的vecArr數組個數,不是vec2的數組個數。
1,glUniform4fv和glUniform4f的區別?
帶v表示是vec,賦值的是基礎是向量;
2,glUniform 無效?
先調用glUseProgram(myprogram),再調用glUniform;
對於沒有調用過的變量,glGetUniformLocation返回值-1;(編譯器優化)
3,
mediump 在片着色器必須帶有這類修飾符
片元語言沒有默認的浮點數精度修飾符。因此,對於浮點數,浮點數向量和矩陣變量聲明,要么聲明必須包含一個精度修飾符,要不默認的精度修飾符在之前已經被聲明過了。
學習的博客