2012-08-04 84 views
18

編輯:問題解決了! 所以我一直打算通過官方的OpenGL ES 2個教程Android和我已經得到了涉及繪製形狀的一部分,但我似乎無法得到方形的工作。它會畫一個直角三角形。的Android的OpenGL ES 2,繪圖方塊

我包括我使用來定義和繪製形狀,這是複製幾乎完全從教程中的代碼。 Renderer類只是創建這個形狀的實例並調用draw方法。

出於某種原因,本教程不給值/聲明vertexStride和vertexCount,所以我的那些在有猜測。我已經嘗試了vertexCount(1到12)的幾個值,但都沒有工作。

在此先感謝。

  public class Square { 

       private FloatBuffer vertexBuffer; 
       private ShortBuffer drawListBuffer; 

       // number of coordinates per vertex in this array 
       static final int COORDS_PER_VERTEX = 3; 
       static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left 
               -0.5f, -0.5f, 0.0f, // bottom left 
               0.5f, -0.5f, 0.0f, // bottom right 
               0.5f, 0.5f, 0.0f }; // top right 

       private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices 
       float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; 


       private final String vertexShaderCode = 
         "attribute vec4 vPosition;" + 
         "void main() {" + 
         " gl_Position = vPosition;" + 
         "}"; 

       private final String fragmentShaderCode = 
        "precision mediump float;" + 
        "uniform vec4 vColor;" + 
        "void main() {" + 
        " gl_FragColor = vColor;" + 
        "}"; 

       int mProgram; 

       static final int vertexStride = COORDS_PER_VERTEX * 4; 
       static final int vertexCount = 4; 

       public Square() { 
        // initialize vertex byte buffer for shape coordinates 
        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float) 
        bb.order(ByteOrder.nativeOrder()); 
        vertexBuffer = bb.asFloatBuffer(); 
        vertexBuffer.put(squareCoords); 
        vertexBuffer.position(0); 

        // initialize byte buffer for the draw list 
        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short) 
        dlb.order(ByteOrder.nativeOrder()); 
        drawListBuffer = dlb.asShortBuffer(); 
        drawListBuffer.put(drawOrder); 
        drawListBuffer.position(0); 


        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 

        mProgram = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
        GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
        GLES20.glLinkProgram(mProgram);     // creates OpenGL ES program executables 
       } 

       public static int loadShader(int type, String shaderCode){ 

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
        int shader = GLES20.glCreateShader(type); 

        // add the source code to the shader and compile it 
        GLES20.glShaderSource(shader, shaderCode); 
        GLES20.glCompileShader(shader); 

        return shader; 
       } 

       public void draw() { 
        // Add program to OpenGL ES environment 
        GLES20.glUseProgram(mProgram); 

        // get handle to vertex shader's vPosition member 
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 

        // Enable a handle to the triangle vertices 
        GLES20.glEnableVertexAttribArray(mPositionHandle); 

        // Prepare the triangle coordinate data 
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
               GLES20.GL_FLOAT, false, 
               vertexStride, vertexBuffer); 

        // get handle to fragment shader's vColor member 
        int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 

        // Set color for drawing the triangle 
        GLES20.glUniform4fv(mColorHandle, 1, color, 0); 

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

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

事實上,我發現,只是在地方GL_TRIANGLES使用GL_TRANGLE_FAN作爲調用glDrawArrays()的變量解決問題。問題解決了! 雖然任何人都可以指向一個實際解釋所有方法和值的API,而不是像Android那樣列出它們,那會很棒。 – 2012-08-06 01:33:27

+0

看看這個:http://stackoverflow.com/questions/6124636/gldrawarrays-vs-gldrawelements – 2012-08-16 15:16:14

回答

23
vertexCount = squareCoords.length/COORDS_PER_VERTEX; //Vertex count is the array divided by the size of the vertex ex. (x,y) or (x,y,z) 
vertexStride = COORDS_PER_VERTEX * 4;    //4 are how many bytes in a float 

讓我知道這是否爲你制定出來的,好運氣。

我想你也缺少用於三維空間轉換到2D屏幕空間ModelViewProjection矩陣。 mvpMatrix應繪製函數draw(float[] mvpMatrix) 忘了提,你也應該使用DrawElements(...)傳遞中(例如,在使用)如果你沒有必要爲計數或步幅,只是一個idicies數組的長度和繪製緩衝區。

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

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

    // Draw the square 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, 
          GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 
+1

我認爲這個答案值得一個綠色的複選標記。部分原因是它清楚地解釋了'vertexCount'和'vertexStride'問題,但也因爲它指向了'GLES20.glDrawElements(...)'函數(在這種情況下,它應該替代'GLES20.glDrawArray(...)功能)。根據我的經驗,「ModelViewProjection」不是必需的,除非在繪製廣場之前不改變世界座標(在這裏似乎不是這種情況)。 – dbm 2012-10-28 13:11:37

+0

@dbm謝謝!我試圖保持它簡短和簡單,所以我可能錯過了其他評論?我使用ModelViewProjection主要是因爲這是我使用的,但也因爲我已經改變了我在繪製之前改變世界座標的方式。 – 2012-10-28 14:40:08

-1
+3

如果你解釋這是如何回答這個問題,那將會很棒 – 2013-04-12 00:07:57

6

教程缺少一些步驟:the final code for the square is here

該示例旨在使用glDrawElements而不是glDrawArrays,這是由存在的行private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices表示。

此數組指定2個三角形的所需頂點。第一,0,1和2。然後是0,2和3。因爲它將使用緩衝區中的第一個頂點,上一個三角形中使用的最後一個頂點和下一個頂點繪製下一個三角形。對於第二個三角形,這是0,2和3.然後是0,3和4等。如果頂點2是5,5,頂點3是-5,5,則結果風扇不會是正方形。

替換這些行:

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

有了這些:

// Draw the square 
GLES20.glDrawElements(
    GLES20.GL_TRIANGLES, drawOrder.length, 
    GLES20.GL_UNSIGNED_SHORT, drawListBuffer);