创建着色器时Android OpenGL应用程序崩溃

时间:2018-10-14 10:15:27

标签: android opengl-es opengl-es-2.0

我对Android OpenGL还是很陌生,所以我尝试使用在课程中找到的教程编写一个简单的动画应用程序。 我认为这是一个非常简单的代码,但是该应用程序崩溃并显示为“不幸的是MovingSquare1应用程序已崩溃”。 我在Logcat中找不到任何崩溃,至少到正常的红色崩溃行序列为止。 经过一些调试后,我发现当行“ int vertexS = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);”行时,应用程序崩溃了。被执行。我曾考虑过上下文问题,但我发现OGLRenderer开头的“ con”变量未被使用。

有人可以给我一个提示吗?

谢谢您的时间,伙计们。

这是主要活动:

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    GLSurfaceView glsv = new GLSurfaceView(this);
    glsv.setRenderer(new OGLRenderer());

    setContentView(glsv);
}

}

这是OGLRenderer类:

public class OGLRenderer implements GLSurfaceView.Renderer {
//    Context con;
private float[] mModelMatrix = new float[16];
private float[] mViewMatrix = new float[16];
private float[] projectionMatrix = new float[16]; 
private float[] mVPMatrix = new float[16]; 

private final FloatBuffer squareVert;
private final FloatBuffer mColor;
private int mvpMatrixHandle;
private int positionHandle;
private int colorHandle;
private final int mBytesPerFloat = 4;
ShortBuffer indexBuffer = null;
short[] indeces = {
        0, 1, 2,
        0, 3, 2
};

float i;
public int sens;

public OGLRenderer() {

    i = 0;
    sens = 1;


    final float[] square = {
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            1.0f, 1.0f, 0.0f
    };


    final float[] colors = {1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0
    };
    // Initialize the buffers.
    squareVert = ByteBuffer.allocateDirect(square.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();

    squareVert.put(square).position(0);
    indexBuffer = ByteBuffer.allocateDirect(indeces.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
    indexBuffer.put(indeces).position(0);

    mColor = ByteBuffer.allocateDirect(colors.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mColor.put(colors).position(0);
}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {

    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);


    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5, 0, 0, 0, 0, 1, 0);


    final String vertexShader =
            "uniform mat4 un_MVPMatrix;      \n"
                    + "attribute vec4 attribute_Position;     \n"
                    + "attribute vec4 attribute_Color;        \n"

                    + "varying vec4 var_Color;            \n"

                    + "void main()                        \n"
                    + "{                                  \n"
                    + "   var_Color = attribute_Color;          \n"

                    + "   gl_Position = un_MVPMatrix      \n"
                    + "               * attribute_Position;   \n"
                    + "}                                 \n";



    final String fragmentShader =
            "precision mediump float;       \n"

                    + "varying vec4 var_Color;          \n"

                    + "void main()                    \n"
                    + "{                              \n"
                    + "   gl_FragColor = var_Color;     \n"
                    + "}                              \n";


    int vertexS = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

    if (vertexS != 0) {

        GLES20.glShaderSource(vertexS, vertexShader);


        GLES20.glCompileShader(vertexS);


        final int[] compile_Status = new int[1];
        GLES20.glGetShaderiv(vertexS, GLES20.GL_COMPILE_STATUS, compile_Status, 0);


    }


    {
        try {
            throw new Exception("Vertex shader is not created.");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    int fragmentS = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    if (fragmentS != 0) {

        GLES20.glShaderSource(fragmentS, fragmentShader);


        GLES20.glCompileShader(fragmentS);


        final int[] compileStatus = new int[1];
        GLES20.glGetShaderiv(fragmentS, GLES20.GL_COMPILE_STATUS, compileStatus, 0);


    }


    if (fragmentS == 0) {
        try {
            throw new Exception("Fragment shader is not created.");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    int program = GLES20.glCreateProgram();

    if (program != 0) {

        GLES20.glAttachShader(program, vertexS);


        GLES20.glAttachShader(program, fragmentS);


        GLES20.glBindAttribLocation(program, 0, "attribute_Position");
        GLES20.glBindAttribLocation(program, 1, "attribute_Color");


        GLES20.glLinkProgram(program);


        final int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);

    }

    if (program == 0) {
        try {
            throw new Exception("Program error");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    mvpMatrixHandle = GLES20.glGetUniformLocation(program, "un_MVPMatrix");
    positionHandle = GLES20.glGetAttribLocation(program, "attribute_Position");
    colorHandle = GLES20.glGetAttribLocation(program, "attribute_Color");


    GLES20.glUseProgram(program);
}


public void onSurfaceChanged(GL10 glUnused, int width, int height) {

    GLES20.glViewport(0, 0, width, height);



    final float ratio = (float) width / height;
    final float left = -ratio;
    final float right = ratio;
    final float bottom = -1.0f;
    final float top = 1.0f;
    final float near = 1.0f;
    final float far = 10.0f;


    Matrix.frustumM(projectionMatrix, 0, left, right, bottom, top, near, far);

}

@Override
public void onDrawFrame(GL10 glUnused) {
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    if (i > 1) {
        sens = -1;
    }
    if (i < -1) {
        sens = 1;

    }
    i += 0.05 * sens;

    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, i, 0.0f, 0.0f);

    drawTriangle(squareVert, indexBuffer);
}


private void drawTriangle(final FloatBuffer aTriangleBuffer, ShortBuffer sb) {
    int a = Float.SIZE;


    aTriangleBuffer.position(0);
    GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, aTriangleBuffer);

    GLES20.glEnableVertexAttribArray(positionHandle);


    mColor.position(0);
    GLES20.glVertexAttribPointer(colorHandle, 3, GLES20.GL_FLOAT, false, 0, mColor);

    GLES20.glEnableVertexAttribArray(colorHandle);


    Matrix.multiplyMM(mVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);


    Matrix.multiplyMM(mVPMatrix, 0, projectionMatrix, 0, mVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mVPMatrix, 0);

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indeces.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

}
}

1 个答案:

答案 0 :(得分:0)

感谢所有看过这个的人。 正如我所怀疑的,这是一个上下文问题,解决方案是创建一个扩展GLSurfaceView的类,并将此行放入构造函数中:

setEGLContextClientVersion(2);

谢谢。