2012-08-04 83 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);