我有问题。我的应用程序总是崩溃。代码来自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);
提前致谢...
答案 0 :(得分:4)
您可以尝试将ByteBuffer.allocate()
替换为ByteBuffer.allocateDirect()
吗?
mTriangle1 = ByteBuffer.allocateDirect(triangle1Data.length*mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();