前言
OpenGLES Android篇零基礎系統前面已經寫了三篇了,因爲OpenGL裏面的水着實是深,所以裏面好多的概念都沒有去查資料,如果一碰到不會的就去查,就感覺沒有連貫性。所以就只能是先一筆帶過,然後再慢慢研究。
正文
前面我們已經瞭解到,OpenGL其實是把物體從世界座標系通過各種複雜的轉變,計算等變成屏幕座標系,顯示在視口中。即:把三維物體轉變爲二維圖像。而轉變的方式有透視、正射,
首先我們看下何謂視景體:
視景體:就是一個可以觀看投影物體的可視區域,由近平面,遠平面,左,上,右,下各面組成。
只有在可視區域內纔可見,區域外會被裁剪。
透視投影
假設有一個視點E(Xp,Yp,Zp),以及世界座標系中任意一點X(Xa,Ya,Za),還有置於E與X之間的一個視平面P(或近平面)。然後以X爲起點,向視點E做射線,與視平面相交於點S。點S即爲我們看到的點。下面我偷個圖一看就明白了:
這種投影就與我們現實生活中用肉眼看東西時很接近了,很逼真。
用一個有照相機的圖如下 :
在OpenGLES2.x中我們這樣用PerspectiveProjection透視投影:
//定義一個16x16的透視矩陣
private final float[] mProjMatrix = new float[16];
//視圖矩陣
private final float[] mVMatrix= new float[16];
//透視矩陣與視圖矩陣變換後的總矩陣
private final float[] mMVPMatrix= new float[16];
/**
*橫豎屏切換時調用
*
**/
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio = (float) width / height;
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
//創建一個透視視景體
//注意:near,far都必須大於0,且二者不能相等,
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
public void onDrawFrame(GL10 gl) {
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1f, 0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
}
如上,當我們拿到頂點的變化總矩陣後,就可以爲GLSL中的MVPMatrix索引賦值,那樣最終得到的gl_Position就能正確在屏幕上展示:
/**
* 頂點着色器的語句
*/
private final String mVertexShader =
"attribute vec4 position;\n" +
"uniform mat4 uMVPMatrix;" +
"void main(){\n" +
"gl_Position = uMVPMatrix * position ;\n" +
"};\n"
正射投影
正射投影又稱正交投影,其視景體爲長方體,投影物體的大小不會隨視點與遠平面之間的距離而變化,
這也是與透視投影最大的區別。見下圖: