我试图在Android上使用OpenGL ES集成创建应用
当我致电glVertexAttribPointer
时,我的应用似乎崩溃了。
渲染器类:
public class Renderer implements GLSurfaceView.Renderer {
int matrixHandle=0;
int positionHandle=0;
int colorHandle=0;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.7f,0.7f,0.7f,1.0f);
try{
loadShaders(matrixHandle,positionHandle,colorHandle);
}catch(RuntimeException ex){
ex.printStackTrace();
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO: Implement this method
GLES20.glViewport(0,0,width,height);
float ratio = (float)width/height;
float left=-ratio;
float right=ratio;
float bottom=-1.0f;
float top=1.0f;
float near=1.0f;
float far=10.0f;
float[] projectionMatrix=new float[16];
Matrix.frustumM(projectionMatrix,0,left,right,bottom,top,near,far);
}
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
float[] mVMatrix = new float[16];
float camX=0.0f;
float camY=1.0f;
float camZ=1.0f;
float lookX=0.0f;
float lookY=0.0f;
float lookZ=0.0f;
float upX=0.0f;
float upY=1.0f;
float upZ=0.0f;
Matrix.setLookAtM(mVMatrix,0,camX,camY,camZ,lookX,lookY,lookZ,upX,upY,upZ);
Grid floor =new Grid(positionHandle);
}
public void loadShaders(int matrix, int position,int color){
String vShader = "uniform mat4 u_MVPMatrix;\n"
+"attribute vec4 a_Position;\n"
+"attribute vec4 a_Color;\n"
+"varying vec4 v_color;\n"
+"void main(){\n"
+" v_color=a_Color;\n"
+" gl_Position = u_MVPMatrix*a_Position;\n"
+"}";
String fShader = "precision mediump float;\n"
+"varying vec4 v_Color;\n"
+"void main(){ gl_FragColor = v_Color; }";
int vertexShader=GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
if(vertexShader!=0){
GLES20.glShaderSource(vertexShader,vShader);
GLES20.glCompileShader(vertexShader);
int[] compileStatus=new int[1];
GLES20.glGetShaderiv(vertexShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0){
GLES20.glDeleteShader(vertexShader);
vertexShader=0;
throw new RuntimeException("Error creating vertex shader.");
}
}
int fragShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
if(fragShader!=0){
GLES20.glShaderSource(fragShader,fShader);
GLES20.glCompileShader(fragShader);
int[] compileStatus = new int[1];
GLES20.glGetShaderiv(fragShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0){
GLES20.glDeleteShader(fragShader);
fragShader=0;
throw new RuntimeException("Error creating fragment shader.");
}
}
int ProgramHandle=GLES20.glCreateProgram();
if(ProgramHandle!=0){
GLES20.glAttachShader(ProgramHandle,vertexShader);
GLES20.glAttachShader(ProgramHandle,fragShader);
GLES20.glBindAttribLocation(ProgramHandle,0,"a_Position");
GLES20.glBindAttribLocation(ProgramHandle,1,"a_Color");
GLES20.glLinkProgram(ProgramHandle);
int[] linkStatus= new int[1];
GLES20.glGetProgramiv(ProgramHandle,GLES20.GL_LINK_STATUS,linkStatus,0);
if(linkStatus[0]==0){
GLES20.glDeleteProgram(ProgramHandle);
ProgramHandle=0;
throw new RuntimeException("Error unable to link shaders.");
}
}
matrix=GLES20.glGetUniformLocation(ProgramHandle,"u_MVPMatrix");
position=GLES20.glGetAttribLocation(ProgramHandle,"a_Position");
color=GLES20.glGetAttribLocation(ProgramHandle,"a_Color");
GLES20.glUseProgram(ProgramHandle);
}
}
网格类:
public class Grid {
int size=50;
float[] color={1.0f,1.0f,1.0f,1.0f};
int positionHandle=0;
int colorHandle=0;
int matrix=0;
public Grid(int pos){
//for(int i=-(size+1);i<size;i++){
float[] vertices={
0.0f,0.0f,-1.0f,
0.0f,0.0f,1.0f
};
ByteBuffer vertexBuffer=ByteBuffer.allocate(vertices.length*4);
vertexBuffer.order(ByteOrder.nativeOrder());
FloatBuffer fVertexBuffer=vertexBuffer.asFloatBuffer();
fVertexBuffer.put(vertices);
fVertexBuffer.position(0);
//loadShaders(matrix,positionHandle,colorHandle);
GLES20.glEnableVertexAttribArray(pos);
GLES20.glVertexAttribPointer(pos,2,GLES20.GL_FLOAT,false,0,fVertexBuffer);
GLES20.glDrawArrays(GLES20.GL_LINES,0,2);
GLES20.glDisableVertexAttribArray(pos);
//}
}
}
答案 0 :(得分:0)
发布的代码中有很多错误/缺失的东西。不确定这是否涵盖了所有内容,但它应该给你一个开始:
Java按值传递方法参数。所以这个电话:
int matrixHandle=0;
int positionHandle=0;
int colorHandle=0;
...
loadShaders(matrixHandle,positionHandle,colorHandle);
将不为3个变量赋值。这些值将分配给方法实现中的本地函数参数,但不会返回给调用者。
onSurfaceChanged()
中有些类似的问题。在这里计算投影矩阵:
float[] projectionMatrix=new float[16];
Matrix.frustumM(projectionMatrix,0,left,right,bottom,top,near,far);
但它只存储在局部变量中。一旦方法返回,该值将丢失。
至少在发布的代码中,我没有在任何地方看到u_MVPMatrix
制服的值设置。
没有为a_Color
属性设置值。