调用glVertexAttribPointer时,Android应用程序崩溃

时间:2015-02-25 23:12:41

标签: java android opengl-es

我试图在Android上使用OpenGL ES集成创建应用 当我致电glVertexAttribPointer时,我的应用似乎崩溃了。

渲染器类:

public class Renderer implements  GLSurfaceView.Renderer {
    int matrixHandle=0;
    int positionHandle=0;
    int colorHandle=0;

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.7f,0.7f,0.7f,1.0f);

        try{
            loadShaders(matrixHandle,positionHandle,colorHandle);
        }catch(RuntimeException ex){
            ex.printStackTrace();
        }
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO: Implement this method
        GLES20.glViewport(0,0,width,height);
        float ratio = (float)width/height;
        float left=-ratio;
        float right=ratio;
        float bottom=-1.0f;
        float top=1.0f;
        float near=1.0f;
        float far=10.0f;
        float[] projectionMatrix=new float[16];
        Matrix.frustumM(projectionMatrix,0,left,right,bottom,top,near,far);
    }

    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        float[] mVMatrix = new float[16];
        float camX=0.0f;
        float camY=1.0f;
        float camZ=1.0f;
        float lookX=0.0f;
        float lookY=0.0f;
        float lookZ=0.0f;
        float upX=0.0f;
        float upY=1.0f;
        float upZ=0.0f;
        Matrix.setLookAtM(mVMatrix,0,camX,camY,camZ,lookX,lookY,lookZ,upX,upY,upZ);
        Grid floor =new Grid(positionHandle);
    }

    public void loadShaders(int matrix, int position,int color){
        String vShader = "uniform mat4 u_MVPMatrix;\n"
                +"attribute vec4 a_Position;\n"
                +"attribute vec4 a_Color;\n"
                +"varying vec4 v_color;\n"
                +"void main(){\n"
                +"  v_color=a_Color;\n"
                +"  gl_Position = u_MVPMatrix*a_Position;\n"
                +"}";
        String fShader = "precision mediump float;\n"
                +"varying vec4 v_Color;\n"
                +"void main(){ gl_FragColor = v_Color; }";
        int vertexShader=GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        if(vertexShader!=0){
            GLES20.glShaderSource(vertexShader,vShader);
            GLES20.glCompileShader(vertexShader);
            int[] compileStatus=new int[1];
            GLES20.glGetShaderiv(vertexShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
            if(compileStatus[0]==0){
                GLES20.glDeleteShader(vertexShader);
                vertexShader=0;
                throw new RuntimeException("Error creating vertex shader.");
            }
        }
        int fragShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        if(fragShader!=0){
            GLES20.glShaderSource(fragShader,fShader);
            GLES20.glCompileShader(fragShader);
            int[] compileStatus = new int[1];
            GLES20.glGetShaderiv(fragShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
            if(compileStatus[0]==0){
                GLES20.glDeleteShader(fragShader);
                fragShader=0;
                throw new RuntimeException("Error creating fragment shader.");
            }
        }
        int ProgramHandle=GLES20.glCreateProgram();
        if(ProgramHandle!=0){
            GLES20.glAttachShader(ProgramHandle,vertexShader);
            GLES20.glAttachShader(ProgramHandle,fragShader);
            GLES20.glBindAttribLocation(ProgramHandle,0,"a_Position");
            GLES20.glBindAttribLocation(ProgramHandle,1,"a_Color");
            GLES20.glLinkProgram(ProgramHandle);
            int[] linkStatus= new int[1];
            GLES20.glGetProgramiv(ProgramHandle,GLES20.GL_LINK_STATUS,linkStatus,0);
            if(linkStatus[0]==0){
                GLES20.glDeleteProgram(ProgramHandle);
                ProgramHandle=0;
                throw new RuntimeException("Error unable to link shaders.");
            }
        }
        matrix=GLES20.glGetUniformLocation(ProgramHandle,"u_MVPMatrix");
        position=GLES20.glGetAttribLocation(ProgramHandle,"a_Position");
        color=GLES20.glGetAttribLocation(ProgramHandle,"a_Color");
        GLES20.glUseProgram(ProgramHandle);
    }
}

网格类:

public class Grid {
    int size=50;
    float[] color={1.0f,1.0f,1.0f,1.0f};
    int positionHandle=0;
    int colorHandle=0;
    int matrix=0;
    public Grid(int pos){
        //for(int i=-(size+1);i<size;i++){
            float[] vertices={
                0.0f,0.0f,-1.0f,
                0.0f,0.0f,1.0f
            };
            ByteBuffer vertexBuffer=ByteBuffer.allocate(vertices.length*4);
                vertexBuffer.order(ByteOrder.nativeOrder());
            FloatBuffer fVertexBuffer=vertexBuffer.asFloatBuffer();
            fVertexBuffer.put(vertices);
        fVertexBuffer.position(0);
                //loadShaders(matrix,positionHandle,colorHandle);
            GLES20.glEnableVertexAttribArray(pos);
            GLES20.glVertexAttribPointer(pos,2,GLES20.GL_FLOAT,false,0,fVertexBuffer);
            GLES20.glDrawArrays(GLES20.GL_LINES,0,2);
            GLES20.glDisableVertexAttribArray(pos);
        //}
    }
}

1 个答案:

答案 0 :(得分:0)

发布的代码中有很多错误/缺失的东西。不确定这是否涵盖了所有内容,但它应该给你一个开始:

  1. Java按值传递方法参数。所以这个电话:

    int matrixHandle=0;
    int positionHandle=0;
    int colorHandle=0;
    ...
        loadShaders(matrixHandle,positionHandle,colorHandle);
    

    为3个变量赋值。这些值将分配给方法实现中的本地函数参数,但不会返回给调用者。

  2. onSurfaceChanged()中有些类似的问题。在这里计算投影矩阵:

    float[] projectionMatrix=new float[16];
    Matrix.frustumM(projectionMatrix,0,left,right,bottom,top,near,far);
    

    但它只存储在局部变量中。一旦方法返回,该值将丢失。

  3. 至少在发布的代码中,我没有在任何地方看到u_MVPMatrix制服的值设置。

  4. 没有为a_Color属性设置值。