2013-01-06 109 views
0

編輯2:查看this GitHub projectTriangle2d sample以獲取完整的工作示例。二維三角形與OpenGL ES 2.0

編輯:查看accepted answer的鏈接,有一個很好的解釋如何oortographic矩陣的作品。最後,我調整所提供的代碼一點點:

float[] mvp = { 
    2f/width, 0f,   0f, 0f, 
    0f,  -2f/height, 0f, 0f, 
    0f,   0f,   0f, 0f, 
    -1f,   1f,   0f, 1f 
    }; 

請注意,我的小Z固定在0和W固定在1這個矩陣使原點(0,0)在左下角屏幕;如果你想在左上角的起源,嘗試:

float[] mvp = { 
    2f/width, 0f,   0f, 0f, 
    0f,   2f/height, 0f, 0f, 
    0f,   0f,   0f, 0f, 
    -1f,  -1f,   0f, 1f 
    }; 

另一個問題是調用GLES20.glUniformMatrix4fv,我改爲:

FloatBuffer b = ByteBuffer.allocateDirect(mvp.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
b.put(mvp).position(0); 
GLES20.glUniformMatrix4fv(uMvpPos, b.limit()/mvp.length, false, b); 

如果你想惹這一點,嘗試this online calculator 。請記住,您的sorce文件中的行將在計算器中爲列。

原問題: 我想在android上繪製一個使用OpenGL 2.0的二維三角形,但到目前爲止,沒有太大的成功。這是我的着色器:

(Vertex shader) 
uniform mat4 uMvp; 
attribute vec3 aPosition; 
attribute vec3 aColor; 
varying vec4 vColor; 
void main() { 
    vColor = vec4(aColor.xyz, 1.0); 
    vec4 position = vec4(aPosition.xyz, 1.0); 
    gl_Position = uMvp * position; 
}; 

(Fragment shader) 
precision mediump float; 
varying vec4 vColor; 
void main(void) 
{ 
    gl_FragColor = vColor; 
}; 

然後,在GLSurfaceView.Renderer的onSurfaceChanged方法,我把以下內容:

public void onSurfaceChanged(GL10 gl, int width, int height) 
{ 
    // here I load and compile the shaders and link the program. 
    // in the end, I use GLES20.glUseProgram(programHandle); 
    // (code omitted) 

    // create the matrix for the uniform 
    int uMvpPos = GLES20.glGetUniformLocation(programHandle, "uMvp"); 
    float[] mvp = {width, 0f, 0f, 0f, 
       0f, -height, 0f, 0f, 
       0f, 0f, -2f, 0f, 
       -1f, 1, -1f, 1}; 
    GLES20.glUniformMatrix4fv(uMvpPos, mvp.length * 4, false, mvp, 0); 

    // set viewport and clear color to white 
    GLES20.glViewport(0, 0, width, height); 
    GLES20.glClearColor(1f, 1f, 1f,1.0f); 
} 

我用的矩陣的值顯示對this question。我的意圖是以與畫布工作相同的方式處理座標:屏幕左上角的(0,0)和右下角的(寬度,高度)。

最後但並非最不重要的,這是onDrawFrame的代碼:

public void onDrawFrame(GL10 gl) 
{ 
    int aPos = GLES20.glGetAttribLocation(programHandle,"aPosition"); 
    int aColor = GLES20.glGetAttribLocation(programHandle,"aColor"); 

    // assuming I correctly set up my coordinate system, 
    // these are the triangle coordinates and color 
    float[] data = 
     { 
     // XYZ, RGB 
     100f, 100f, 0f, 
     1f, 0f, 0f, 

     50f, 50f, 0f, 
     1f, 0f, 0f, 

     150f, 50f, 0f, 
     1f, 0f, 0f, 
     }; 

    // put all my data into a float buffer 
    // the '* 4' is because a float has 4 bytes 
    FloatBuffer dataVertex = ByteBuffer.allocateDirect(data.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
    dataVertex.put(data).position(0); 

    // set the POSITION values 
    // attribute, dataSize(number of elements), data type, normalized?, size(bytes), data 
    GLES20.glEnableVertexAttribArray(aPos); 
    GLES20.glVertexAttribPointer(aPos, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex); 

    // set the COLOR values 
    dataVertex.position(3); // offset 
    GLES20.glEnableVertexAttribArray(aColor); 
    GLES20.glVertexAttribPointer(aColor, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex); 

    // put a white background 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 

    // and finally draw the triangle! 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 
} 

最終的結果是......一個無聊的白色屏幕,而三角形。我想我犯了一個非常簡單的錯誤,但我無法發現它。有什麼想法嗎?

回答

1

您的正交投影矩陣是錯誤的。 Orthographic projection is defined as(列優先的順序):

2/(r-l), 0, 0, 0, 
0, 2/(t-b), 0, 0, 
0, 0, 2/(f-n), 0, 
(r+l)/(l-r), (t+b)/(b-t), (f+n)/(n-f), 1 

在你的情況r=0, l=width, t=height, b=0, f=1, n=0,你會得到:

-2/width, 0, 0, 0, 
0, 2/height, 0, 0, 
0, 0, 2, 0, 
1, -1, -1, 1 
+0

謝謝!由於我的z和w是固定的(我只對2d感興趣),我對矩陣做了一些調整,現在一切都很好。對glUniformMatrix4fv的調用也是錯誤的。我將編輯原始問題以反映這一點。 –

相關問題