2012-08-04 14 views
18

संपादित करें: समस्या हल हो गई है! तो मैं एंड्रॉइड के लिए आधिकारिक ओपनजीएल ईएस 2 ट्यूटोरियल के माध्यम से जा रहा हूं, और मैं उस भाग को प्राप्त कर रहा हूं जिसमें आकृतियों को चित्रित करना शामिल है, लेकिन मुझे काम करने के लिए एक वर्ग नहीं मिल रहा है। यह इसके बजाय एक सही त्रिकोण खींचता है।एंड्रॉइड ओपनजीएल ईएस 2, ड्राइंग वर्ग

मैंने उस कोड को शामिल किया है जिसका उपयोग मैं आकार को परिभाषित करने और खींचने के लिए कर रहा हूं, जिसे लगभग ट्यूटोरियल से बिल्कुल कॉपी किया गया है। रेंडरर क्लास बस इस आकार का एक उदाहरण बनाता है और ड्रॉ विधि को कॉल करता है।

किसी कारण से, ट्यूटोरियल vertexStride और vertexCount के लिए मान/घोषणा नहीं देता है, इसलिए मेरे पास वहां मौजूद शिक्षित अनुमान हैं। मैंने vertexCount (12 से 1) के लिए कई मानों की कोशिश की है, और कोई भी काम नहीं है।

अग्रिम धन्यवाद।

  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

वास्तव में, मैंने पाया है कि सिर्फ glDrawArrays के लिए एक तर्क है (जैसा कि GL_TRIANGLES के स्थान पर GL_TRANGLE_FAN का प्रयोग करके) समस्या का समाधान। समस्या सुलझ गयी! हालांकि अगर कोई मुझे एपीआई की तरफ इंगित कर सकता है जो वास्तव में एंड्रॉइड के काम की तरह उन्हें सूचीबद्ध करने के बजाय सभी विधियों और मूल्यों को समझाता है, तो यह बहुत अच्छा होगा। –

+0

इसे देखें: http://stackoverflow.com/questions/6124636/gldrawarrays-vs-gldrawelements –

उत्तर

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 

मुझे पता है कि अगर आप के लिए बाहर काम किया, अच्छी किस्मत करते हैं।

मुझे लगता है कि आपके पास ModelViewProjection मैट्रिक्स भी 3 डी स्पेस को 2 डी स्क्रीन स्पेस में परिवर्तित करने के लिए उपयोग किया जाता है। mvpMatrix ड्रा फंक्शन draw(float[] mvpMatrix) द्वारा पारित किया जाना चाहिए, यह उल्लेख करने के लिए भूल गए कि आपको DrawElements(...) (उदाहरण में उपयोग किया गया) का उपयोग करना चाहिए यदि आपको गिनती या घुमाव की आवश्यकता नहीं है, केवल एक आईडीआईआरआई सरणी और ड्राइंग बफर की लंबाई है।

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

+0

@ डीबीएम धन्यवाद! मैंने इसे छोटा और सरल रखने की कोशिश की ताकि मैं किसी और आलोचना को याद कर सकूं? मैंने मॉडलव्यूप्रोजेक्शन का मुख्य रूप से उपयोग किया क्योंकि मैं इसका उपयोग करता हूं, लेकिन यह भी कि क्योंकि मैंने ड्राइंग से पहले विश्व निर्देशांक को बदलने का अपना तरीका बदल दिया है। –

-1
+3

यह बहुत अच्छा होगा अगर आपने समझाया कि यह प्रश्न का उत्तर कैसे देता है –

6

ट्यूटोरियल कुछ कदम याद आ रही है: the final code for the square is here

उदाहरण का उद्देश्य glDrawArrays के बजाय glDrawElements का उपयोग करना था जो लाइन की उपस्थिति से संकेत मिलता है: private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices

यह सरणी 2 त्रिकोणों के वांछित शिखर निर्दिष्ट करती है। पहले के लिए 0, 1 और 2। फिर दूसरे के लिए 0, 2 और 3। GL_TRANGLE_FAN बस काम करने के लिए होता है क्योंकि यह बफर में पहले चरम का उपयोग करके अगला त्रिकोण खींचता है, पिछली त्रिकोण और अगले चरम पर उपयोग किया गया अंतिम चरम। दूसरे त्रिकोण के लिए यह 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); 
संबंधित मुद्दे