Приложение Android OpenGL вылетает при создании шейдера - PullRequest
0 голосов
/ 14 октября 2018

Я довольно новичок в Android OpenGL, поэтому я пытаюсь написать простое приложение для анимации, используя учебник, который я нашел в курсе.Я думаю, что это довольно простой код, но приложение вылетает с сообщением «К сожалению, приложение MovingSquare1 разбилось».Я не смог найти какой-либо сбой в Logcat, по крайней мере, для обычной последовательности сбоя линий в красном.После некоторой отладки я обнаружил, что приложение падает, когда строка "int vertexS = GLES20.glCreateShader (GLES20.GL_VERTEX_SHADER);"выполнен.Я думал о проблеме контекста, но видел, что переменная "con" в начале OGLRenderer не используется.

Может кто-нибудь дать мне подсказку?

Спасибо за вашвремя, ребята.

Это основное занятие:

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 голосов
/ 16 октября 2018

Спасибо всем, кто взглянул на это.Как я и подозревал, это была проблема контекста, решение состоит в том, чтобы создать класс, расширяющий GLSurfaceView, и поместить в конструктор следующую строку:

setEGLContextClientVersion(2);

Спасибо.

...