2012-08-04 45 views
18

EDIT: Sự cố được giải quyết! Vì vậy, tôi đã đi qua các hướng dẫn OpenGL ES 2 chính thức cho Android, và tôi đã nhận được một phần liên quan đến việc vẽ hình dạng, nhưng tôi không thể có vẻ để có được một hình vuông để làm việc. Nó vẽ một hình tam giác bên phải để thay thế.Android OpenGL ES 2, Vẽ hình vuông

Tôi đã bao gồm mã mà tôi đang sử dụng để xác định và vẽ hình dạng, được sao chép gần như chính xác từ hướng dẫn. Lớp Renderer chỉ đơn giản là tạo ra một thể hiện của hình dạng này và gọi phương thức vẽ.

Vì lý do nào đó, hướng dẫn không cung cấp các giá trị/khai báo cho vertexStride và vertexCount, do đó, những cái tôi có trong đó có những phỏng đoán được giáo dục. Tôi đã thử một số giá trị cho vertexCount (1 đến 12), và không có công việc.

Xin cảm ơn trước.

  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

Trên thực tế, tôi thấy rằng chỉ sử dụng GL_TRANGLE_FAN ở vị trí của GL_TRIANGLES như một cuộc tranh cãi cho glDrawArrays() giải quyết vấn đề này. Đã giải quyết được vấn đề! Mặc dù nếu có ai có thể chỉ cho tôi hướng tới API thực sự giải thích tất cả các phương pháp và giá trị thay vì chỉ liệt kê chúng như Android, điều đó thật tuyệt vời. –

+0

Hãy xem xét điều này: http://stackoverflow.com/questions/6124636/gldrawarrays-vs-gldrawelements –

Trả lời

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 

Hãy cho tôi biết nếu mà làm việc ra cho bạn, chúc may mắn.

Tôi nghĩ rằng bạn cũng bỏ lỡ ModelViewProjection Ma trận được sử dụng để chuyển đổi không gian 3D thành không gian màn hình 2D. mvpMatrix nên được thông qua bởi chức năng vẽ draw(float[] mvpMatrix) Quên đề cập đến bạn cũng nên sử dụng DrawElements(...) (được sử dụng trong ví dụ) nếu bạn không cần đếm hoặc sải chân, chỉ cần chiều dài của mảng idicies và bộ đệm bản vẽ.

// 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

Tôi nghĩ câu trả lời này xứng đáng với dấu kiểm màu xanh lá cây.Một phần vì nó giải thích rõ ràng các câu hỏi 'vertexCount' và' vertexStride' nhưng cũng vì nó chỉ ra hàm 'GLES20.glDrawElements (...)' (trong trường hợp này nên thay thế 'GLES20.glDrawArray (...)' chức năng). 'ModelViewProjection' là không cần thiết, theo kinh nghiệm của tôi, trừ khi bạn không biến đổi tọa độ thế giới của bạn trước khi vẽ hình vuông của bạn (mà dường như không phải là trường hợp ở đây). – dbm

+0

@dbm Cảm ơn! Tôi đã cố gắng giữ nó ngắn gọn và đơn giản để tôi có thể đã bỏ lỡ một vài điều phê phán khác? Tôi đã sử dụng ModelViewProjection chủ yếu bởi vì đó là những gì tôi sử dụng, nhưng cũng bởi vì tôi đã thay đổi cách biến đổi tọa độ thế giới trước khi vẽ. –

-1
+3

Thật tuyệt nếu bạn giải thích cách câu trả lời cho câu hỏi –

6

Các hướng dẫn được thiếu một số bước sau: the final code for the square is here.

Ví dụ được sử dụng để sử dụng glDrawElements thay vì glDrawArrays được biểu thị bằng sự hiện diện của dòng: private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices.

Mảng này chỉ định các đỉnh mong muốn của 2 hình tam giác. 0, 1 và 2 cho lần đầu tiên. Sau đó, 0, 2 và 3 cho lần thứ hai. GL_TRANGLE_FAN chỉ xảy ra để làm việc vì nó sẽ vẽ hình tam giác tiếp theo bằng cách sử dụng đỉnh đầu tiên trong bộ đệm, đỉnh cuối cùng được sử dụng trong tam giác trước đó và đỉnh tiếp theo. Đối với tam giác thứ hai là 0, 2 và 3. Sau đó 0, 3 và 4, v.v. Đã có đỉnh 2 là 5, 5 và đỉnh 3 là -5, 5, thì quạt kết quả sẽ không có hình vuông.

Thay thế những dòng này:

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

Với những:

// Draw the square 
GLES20.glDrawElements(
    GLES20.GL_TRIANGLES, drawOrder.length, 
    GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 
Các vấn đề liên quan