对不起,我的英语。我是OpenglES的初学者。我写了这段代码来画出曲棍球的简单表格。该代码摘自Android版《 OpenglES2》,我有点对其进行了修改。当我启动我的应用程序时,它崩溃了。其中没有出现错误。ShaderHandler.java中的代码
public class ShaderHandler {
private static int program;
private static final String TAG = "TAG";
public static int loadShader(int type, String shaderCode){
final int shader = GLES20.glCreateShader(type);
if(shader == 0){
if(LoggerConfig.ON) {
Log.w(TAG, "Could not create new shader");
}
}
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
//----------------------------------------------------------------------------------------
//check compile status. This is pattern
final int[] compileStatus = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
if (LoggerConfig.ON) {
Log.v(TAG, "Results of compiling source: " + "\n" + shaderCode + "\n:"
+ GLES20.glGetShaderInfoLog(shader));
}
if (compileStatus[0] == 0){
//if it failed, delete the shader object
GLES20.glDeleteShader(shader);
if (LoggerConfig.ON) Log.w(TAG, "Compilation of shader failed");
}
//----------------------------------------------------------------------------------------
return shader;
}
public static int makeProgram(int vertexShader, int fragmentShader) {
program = GLES20.glCreateProgram();
if (program == 0){
if (LoggerConfig.ON){
Log.w(TAG, "Could not create a program");
}
}
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
if(LoggerConfig.ON) validateProgram(program);
GLES20.glUseProgram(program);
return program;
}
}
以及来自myRenderer.java的代码
public class MyRenderer implements GLSurfaceView.Renderer {
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int BYTES_PER_FLOAT = 4;
private FloatBuffer vertexData;
private Context context;
private ShaderHandler shaderHandler;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private static final String U_COLOR = "u_Color";
private int uColorLocation;
private final String vertexShaderCode =
"attribute vec4 a_Position;" +
"void main() {" +
" gl_Position = a_Position;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 u_Color;" +
"void main() {" +
" gl_FragColor = u_Color;" +
"}";
float[] tableVertices = {
0f, 0f,
0f, 14f,
9f, 14f,
9f, 0f
};
float[] tableVerticesTriangles = {
//Triangle1
0f, 0f,
9f, 14f,
0f, 14f,
//Triangle2
0f, 0f,
9f, 0f,
9f, 14f,
//Line1
0f, 7f,
9f, 7f,
//Mallets
4.5f, 2f,
4.5f, 12f
};
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
vertexData = ByteBuffer
.allocateDirect(tableVerticesTriangles.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexData.put(tableVertices);
int compiledVertShader = shaderHandler.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int compiledFragShader = shaderHandler.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
int program = shaderHandler.makeProgram(compiledVertShader, compiledFragShader);
aPositionLocation = GLES20.glGetAttribLocation(program, "a_Position");
uColorLocation = GLES20.glGetUniformLocation(program, "u_Color");
vertexData.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
false, 0, vertexData);
GLES20.glEnableVertexAttribArray(aPositionLocation);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
GLES20.glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_LINES, 6, 2);
GLES20.glUniform4f(uColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_POINTS, 8, 1);
GLES20.glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_POINTS, 9, 1);
}
}
在应用崩溃后,我在logcat中看到此消息
A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 17311 (GLThread 891), pid 17264 (ockey.airhockey)
请帮助。我整天都在努力解决这个问题,但我不知道该怎么办。
创建缓冲区并填充缓冲区后,您错过了vertexData.flip()
。
vertexData.put(tableVertices);
vertexData.put(tableVertices).flip();
vertexData.put(tableVertices)
将数据从当前位置(在此情况下为缓冲区的开始)开始传输到缓冲区。缓冲区位置增加数据大小。因此,新的缓冲区位置在新数据的末尾。
[flip()
将缓冲区的限制(长度)设置为当前位置,然后将该位置设置为零。