2014-05-05 70 views
0

我遇到問題。我的應用程序總是崩潰。代碼是從this網站...這是一個非常好的教程,我做了他寫的所有內容,但無論如何它崩潰了......我是openGlES的新手,所以這可能是我犯的一個非常簡單的錯誤...Android OpenGLES致命異常:GLThread 10

這是我的代碼:

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); 

在此先感謝...

回答

4

您能否嘗試將ByteBuffer.allocate()更換爲ByteBuffer.allocateDirect()

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

感謝它的工作:) – emyaz

+0

歡迎您! –

+0

@SergioMartinez你能解釋爲什麼這會有所作爲嗎? –