Android OpenGLES FATAL EXCEPTION:GLThread 10

时间:2014-05-05 15:39:12

标签: java android opengl-es

我有问题。我的应用程序总是崩溃。代码来自this网站...这是一个非常好的教程,我做了他写的所有内容,但无论如何它都崩溃了...我是openGlES的新手,所以它可能是我犯的一个非常简单的错误......

这是我的代码:

package com.emyaz.opengltest;

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.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.os.SystemClock;

public class GameRenderer implements Renderer
{
    private FloatBuffer mTriangle1;
    private FloatBuffer mTriangle2;
    private FloatBuffer mTriangle3;

    private float[] mViewMatrix = new float[16];
    private float[] mProjectionMatrix = new float[16];
    private float[] mModelMatrix = new float[16]; 
    private float[] mMVPMatrix = new float[16];

    private int mMVPMatrixHandle;
    private int mPositionHandle;
    private int mColorHandle;

    private final int mBytesPerFloat = 4;

    private final int mStrideBytes = 7*mBytesPerFloat;
    private final int mPositionOffset = 0;
    private final int mPositionDataSize = 3;
    private final int mColorOffset = 3;
    private final int mColorDataSize = 4;

    GameRenderer()
    {
        final float[] triangle1Data = 
            {
                -0.5f, -0.25f, 0.0f,
                1.0f, 0.0f, 0.0f, 1.0f,

                0.5f, -0.25f, 0.0f,
                0.0f, 0.0f, 1.0f, 1.0f,

                0.0f, 0.559016994f, 0.0f,
                0.0f, 1.0f, 0.0f, 1.0f
            };

        mTriangle1 = ByteBuffer.allocate(triangle1Data.length*mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
        mTriangle1.put(triangle1Data).position(0);

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config)
    {
        GLES20.glClearColor(0f, 0f, 0f, 0f);

        final float eyeX = 0.0f; 
        final float eyeY = 0.0f;
        final float eyeZ = 1.5f;

        final float lookX = 0.0f; 
        final float lookY = 0.0f;
        final float lookZ = -5.0f;

        final float upX = 0.0f; 
        final float upY = 1.0f;
        final float upZ = 0.0f;

        Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);

        final String vertexShader =
                "uniform mat4 u_MVPMatrix;      \n"          
                        + "attribute vec4 a_Position;     \n"
                        + "attribute vec4 a_Color;        \n"   
                        + "varying vec4 v_Color;          \n"      
                        + "void main()                    \n"
                        + "{                              \n"
                        + "   v_Color = a_Color;          \n"
                        + "   gl_Position = u_MVPMatrix   \n"
                        + "               * a_Position;   \n"
                        + "}                              \n";

        final String fragmentShader =
                "precision mediump float;       \n"
                        + "varying vec4 v_Color;          \n"
                        + "void main()                    \n"
                        + "{                              \n"
                        + "   gl_FragColor = v_Color;     \n"
                        + "}                              \n";

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

        if(vertexShaderHandle != 0)
        {
            GLES20.glShaderSource(vertexShaderHandle, vertexShader);
            GLES20.glCompileShader(vertexShaderHandle);

            final int[] compileStatus = new int[1];

            GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

            if(compileStatus[0] == 0)
            {
                GLES20.glDeleteShader(vertexShaderHandle);
                vertexShaderHandle = 0;
            }
        }

        if(vertexShaderHandle == 0)
        {
            throw new RuntimeException("Shader fail");
        }

        int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

        if(fragmentShaderHandle != 0)
        {
            GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
            GLES20.glCompileShader(fragmentShaderHandle);

            final int[] compileStatus = new int[1];

            GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

            if(compileStatus[0] == 0)
            {
                GLES20.glDeleteShader(fragmentShaderHandle);
                fragmentShaderHandle = 0;
            }
        }

        if(fragmentShaderHandle == 0)
        {
            throw new RuntimeException("Shader fail");
        }

        int programHandle = GLES20.glCreateProgram();

        if(programHandle != 0)
        {
            GLES20.glAttachShader(programHandle, vertexShaderHandle);
            GLES20.glAttachShader(programHandle, fragmentShaderHandle);

            GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
            GLES20.glBindAttribLocation(programHandle, 1, "a_Color");

            GLES20.glLinkProgram(programHandle);

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

            if(linkStatus[0] == 0)
            {
                GLES20.glDeleteProgram(programHandle);
                programHandle = 0;
            }
        }

        if(programHandle == 0)
        {
            throw new RuntimeException("Error creating program");
        }

        mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");
        mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
        mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");

        GLES20.glUseProgram(programHandle);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, 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(mProjectionMatrix, 0, left, right, bottom, top, near, far);
    }

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

        long time = SystemClock.uptimeMillis() % 10000L;
        float angle = (360f / 10000f) * time;

        Matrix.setIdentityM(mModelMatrix, 0);
        Matrix.rotateM(mModelMatrix, 0, angle, 0f, 0f, 1f);
        drawTriangle(mTriangle1);
    }

    private void drawTriangle(final FloatBuffer aTriangleBuffer)
    {
        aTriangleBuffer.position(mPositionOffset);
        GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mStrideBytes, aTriangleBuffer);
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        aTriangleBuffer.position(mColorOffset);
        GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, mStrideBytes, aTriangleBuffer);
        GLES20.glEnableVertexAttribArray(mColorHandle);

        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false,mMVPMatrix, 0);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
    }
}

这是我收到的错误消息:

FATAL EXCEPTION: GLThread 10
java.lang.IllegalArgumentException: Must use a native order direct Buffer
at android.opengl.GLES20.glVertexAttribPointerBounds(Native Method)
at android.opengl.GLES20.glVertexAttribPointer(GLES20.java:1921)
at com.emyaz.opengltest.GameRenderer.drawTriangle(GameRenderer.java:208)
at com.emyaz.opengltest.GameRenderer.onDrawFrame(GameRenderer.java:202)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1364)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1119)

第208行是这一行:

GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mStrideBytes, aTriangleBuffer);

提前致谢...

1 个答案:

答案 0 :(得分:4)

您可以尝试将ByteBuffer.allocate()替换为ByteBuffer.allocateDirect()吗?

mTriangle1 = ByteBuffer.allocateDirect(triangle1Data.length*mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();