代码之家  ›  专栏  ›  技术社区  ›  monoceres

为什么我的android openGL ES测试渲染器会崩溃

  •  1
  • monoceres  · 技术社区  · 14 年前

    我再次尝试进入openGL,但像往常一样,我在传递顶点/顶点/任何东西时都会窒息,每一个小细节都可能导致灾难(格式错误、初始化设置不正确、内存保存在哪里等等)。

    我的主要目标是将openGL用于2D图形,与常规cpu绘图相比,提高性能。

    总之,我的openGL渲染器如下所示:

    package com.derp.testopengl;
    
    
    import java.nio.Buffer;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.opengl.GLU;
    import android.opengl.GLSurfaceView.Renderer;
    
    public class OpenGLRenderer implements Renderer {
    
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // Set the background color to black ( rgba ).
            gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);  // OpenGL docs.
            // Enable Smooth Shading, default not really needed.
            gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.
            // Depth buffer setup.
            gl.glClearDepthf(1.0f);// OpenGL docs.
            // Enables depth testing.
            gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.
            // The type of depth testing to do.
            gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.
            // Really nice perspective calculations.
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
                              GL10.GL_NICEST);
        }
    
    
        public void onDrawFrame(GL10 gl) {
            // Clears the screen and depth buffer.
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                               GL10.GL_DEPTH_BUFFER_BIT);
    
            // Define the points of my triangle
            float floatbuff[] = {
                    1.0f,0.0f,0.0f,
                    0.0f,1.0f,0.0f,
                    -1.0f,0.0f,0.0f
                    };
            // Create memory on the heap
            ByteBuffer vbb = ByteBuffer.allocateDirect(3 * 3 * 4);
            vbb.order(ByteOrder.nativeOrder());
            FloatBuffer vertices = vbb.asFloatBuffer();
    
            // Insert points into floatbuffer
            vertices.put(floatbuff);
            // Reset position
            vertices.position(0);
    
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    
            // Change color to green
            gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
    
            // Pass vertices to openGL
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);
    
            // Draw 'em
            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
    
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        }
    
    
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // Sets the current view port to the new size.
            gl.glViewport(0, 0, width, height);// OpenGL docs.
            // Select the projection matrix
            gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.
            // Reset the projection matrix
            gl.glLoadIdentity();// OpenGL docs.
    
            // Should give a 2D coordinate system that responds to the screen
            gl.glOrthof(0.0f, width, 0.0f, height, 0, 200.0f);
    
            gl.glMatrixMode(GL10.GL_MODELVIEW); 
            gl.glLoadIdentity();// OpenGL docs.
        }
    }
    

    它目前正在线路上崩溃:

    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
    

    带有IndexOutOfBoundsException,但我相信代码中还有更多问题。

    感谢您的帮助!

    3 回复  |  直到 14 年前
        1
  •  1
  •   Brian    14 年前

    你可能已经解决了这个问题,但我想我已经为别人提供了答案。当你拨打这条电话时:

    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
    

    你是说顶点缓冲区中有3个三角形。但实际上有一个三角形。您应该将3替换为:

    vertices.length / 3
    

    这样,如果为更多多边形添加更多点,它将正确渲染。希望这有帮助。

    -布莱恩

    PS:我目前正在学习如何在android上使用opengl。所以我也在解决这些小问题。祝你好运:)

        2
  •  0
  •   RicardoSBA    14 年前

    尝试更改此选项:

    // Create memory on the heap
    ByteBuffer vbb = ByteBuffer.allocateDirect(3 * 3 * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer vertices = vbb.asFloatBuffer();
    
    // Insert points into floatbuffer
    vertices.put(floatbuff);
    // Reset position
    vertices.position(0);
    

    为此:

    FloatBuffer vertices = FloatBuffer.wrap(floatbuff);
    
        3
  •  0
  •   sravan    14 年前

    这可能不是回答,而是一个建议。。。 不要把下面的代码放在OnDrawFrame中,因为你的三角形坐标不变。。。在onSurfaceCreated中执行这些操作。 使FloatBuffer成为类的成员变量

     // Define the points of my triangle
        float floatbuff[] = {
                1.0f,0.0f,0.0f,
                0.0f,1.0f,0.0f,
                -1.0f,0.0f,0.0f
                };
        // Create memory on the heap
        ByteBuffer vbb = ByteBuffer.allocateDirect(3 * 3 * 4);
        vbb.order(ByteOrder.nativeOrder());
        FloatBuffer vertices = vbb.asFloatBuffer();
    
        // Insert points into floatbuffer
        vertices.put(floatbuff);
    

    看看这门课 TriangleRenderer.java 它会给你基本的