OpenGL ES使用投影和相機視圖

OpenGL ES環(huán)境允許你以更接近于你眼睛看到的物理對象的方式來顯示你繪制的對象勺爱。物理查看的模擬是通過對你所繪制的對象的坐標(biāo)進(jìn)行數(shù)學(xué)變換完成的:

  • Projection(投影) — 這個變換是基于他們所顯示的GLSurfaceView的寬和高來調(diào)整繪制對象的坐標(biāo)的甲献。沒有這個計算變換,通過OpenGL繪制的形狀會在不同顯示窗口變形痊剖。這個投影變化通常只會在OpenGL view的比例被確定或者在你渲染器的onSurfaceChanged()方法中被計算。想要了解更多的關(guān)于投影和坐標(biāo)映射的相關(guān)信息垒玲,請看繪制對象的坐標(biāo)映射陆馁。
  • Camera View — 這個換是基于虛擬的相機的位置來調(diào)整繪制對象坐標(biāo)的。需要著重注意的是合愈,OpenGL ES并沒有定義一個真實的相機對象叮贩,而是提供一個實用方法,通過變換繪制對象的顯示來模擬一個相機佛析。相機視圖變換可能只會在你的GLSurfaceView被確定時被計算益老,或者基于用戶操作或你應(yīng)用程序的功能來動態(tài)改變。

1 定義投影

投影變化的數(shù)據(jù)是在你GLSurfaceView.Renderer類的onSurfaceChanged()方法中被計算的寸莫。下面的示例代碼是獲取GLSurfaceView的高和寬捺萌,并通過Matrix.frustumM()方法用它們填充到投影變換矩陣中。

// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

上面的代碼填充有一個投影矩陣mProjectionMatrix储狭,mProjectionMatrix可以在onFrameDraw()方法中與下一部分的相機視圖結(jié)合在一起互婿。

注意:如果僅僅只把投影矩陣應(yīng)用的到你繪制的對象中,通常你只會得到一個非沉杀罚空的顯示。一般情況下呛牲,你還必須為你要在屏幕上顯示的任何內(nèi)容應(yīng)用相機視圖刮萌。

2 定義相機視圖

通過在你的渲染器中添加相機視圖變換作為你繪制過程的一部分來完成你的繪制圖像的變換過程。在下面的代碼中娘扩,通過Matrix.setLookAtM()方法計算相機視圖變換着茸,然后將其與之前計算出的投影矩陣結(jié)合到一起。合并后的矩陣接下來會傳遞給繪制的圖形琐旁。

@Override
public void onDrawFrame(GL10 unused) {
    ...
    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    // Draw shape
    mTriangle.draw(mMVPMatrix);
}

3 應(yīng)用投影和相機變換

為了使用在上一部分內(nèi)容中展示的投影和相機視圖變換的合并矩陣涮阔,首先要在之前Triangle類中定義的定點著色器代碼中添加一個矩陣變量:

public class Triangle {

    private final String vertexShaderCode =
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "void main() {" +
        // the matrix must be included as a modifier of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

    // Use to access and set the view transformation
    private int mMVPMatrixHandle;

    ...
}

下一步,修改你的圖形對象的draw()方法來接收聯(lián)合變換矩陣灰殴,并將它們應(yīng)用到圖形中:

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    ...

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Pass the projection and view transformation to the shader
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

一旦你正確的計算并應(yīng)用投影和相機視圖變換敬特,你的繪圖對象將會以正確的比例繪制,它看起來應(yīng)該像下面這樣:


豎屏
橫屏

現(xiàn)在你已經(jīng)有一個可以以正確比例顯示圖形的應(yīng)用了牺陶。后面的章節(jié)伟阔,我們可以了解如何為你的圖形添加運動了。
源碼地址:https://github.com/Xiaoben336/OpenGLES20Study

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掰伸,一起剝皮案震驚了整個濱河市皱炉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狮鸭,老刑警劉巖合搅,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件多搀,死亡現(xiàn)場離奇詭異,居然都是意外死亡灾部,警方通過查閱死者的電腦和手機酗昼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梳猪,“玉大人麻削,你說我怎么就攤上這事〈好郑” “怎么了呛哟?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匿沛。 經(jīng)常有香客問我扫责,道長,這世上最難降的妖魔是什么逃呼? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任鳖孤,我火速辦了婚禮,結(jié)果婚禮上抡笼,老公的妹妹穿的比我還像新娘苏揣。我一直安慰自己,他們只是感情好推姻,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布平匈。 她就那樣靜靜地躺著,像睡著了一般藏古。 火紅的嫁衣襯著肌膚如雪增炭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天拧晕,我揣著相機與錄音隙姿,去河邊找鬼。 笑死厂捞,一個胖子當(dāng)著我的面吹牛输玷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔫敲,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饲嗽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奈嘿?” 一聲冷哼從身側(cè)響起貌虾,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎裙犹,沒想到半個月后尽狠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衔憨,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年袄膏,在試婚紗的時候發(fā)現(xiàn)自己被綠了践图。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡沉馆,死狀恐怖码党,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斥黑,我是刑警寧澤揖盘,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站锌奴,受9級特大地震影響兽狭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹿蜀,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一箕慧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茴恰,春花似錦颠焦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至婉商,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渣叛,已是汗流浹背丈秩。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留淳衙,地道東北人蘑秽。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像箫攀,于是被迫代替她去往敵國和親肠牲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

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