原因是加了下面2句:
"attribute vec2 aTextureCoord;\n" + 光加这个不会崩溃,
mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord"); 这句崩溃了
public class MyRenderer implements Renderer {
private Bitmap mBitmap = null;
private float[] mVMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
bulidProgram();
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
GLES20.glUseProgram(mProgram);
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config .ARGB_8888);
mBitmap.eraseColor(Color.BLUE);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
// GLES20.glUseProgram(mProgram);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);// 应用投影和视口变换
drawImage();
drawSquare();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static final int COORDS_PER_IMAGE_VERTEX = 2;
private FloatBuffer mImageCubeVertices;
private FloatBuffer mTTextureVertices;
final float cubePosition[] = {
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
};
final float cubeColor[] = {
0.0f, 0.0f, 1.0f, 1.0f};
final float cubeTextureCoordinate[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f};
private void drawImage() {
GLES20.glEnable(GLES20.GL_TEXTURE_2D);// 启用2D纹理贴图
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
if (null == mBitmap || mBitmap.isRecycled()) {
return;
}
else {
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mBitmap, 0);
}
GLES20.glDeleteTextures(1, textures, 0);
mImageCubeVertices = ByteBuffer.allocateDirect(cubePosition.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
mImageCubeVertices.put(cubePosition).position(0);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_IMAGE_VERTEX, GLES20.GL_FLOAT, false, cubePosition.length * COORDS_PER_IMAGE_VERTEX, mImageCubeVertices);
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, cubeColor, 0);
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
mTTextureVertices = ByteBuffer.allocateDirect(cubeTextureCoordinate.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
mTTextureVertices.put(cubeTextureCoordinate).position(0);
GLES20.glVertexAttribPointer(mTextureHandle, 2, GLES20.GL_FLOAT, false, COORDS_PER_IMAGE_VERTEX * BYTES_PER_FLOAT, mTTextureVertices);
GLES20.glEnableVertexAttribArray(mTextureHandle);
GLES20.glDisableVertexAttribArray(mPositionHandle);// Disable vertex array
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static final int COORDS_PER_SQUARE_VERTEX = 2;
private FloatBuffer mSquareVertexBuffer;
private ShortBuffer mSquareIndexBuffer;
private void drawSquare() {
createRectangle();
float squareColor[] = { 0.0f, 1.0f, 0.0f, 1.0f };
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_SQUARE_VERTEX, GLES20.GL_FLOAT, false, COORDS_PER_SQUARE_VERTEX * BYTES_PER_FLOAT, mSquareVertexBuffer);// 每个顶点只有(x,y)2个点
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, squareColor, 0);
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, squareCoords.length * COORDS_PER_SQUARE_VERTEX);// Draw the triangle
// Draw the square
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, squareIndex.length,
GLES20.GL_UNSIGNED_SHORT, mSquareIndexBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);// Disable vertex array
}
private void createRectangle() {
ByteBuffer vbb = ByteBuffer.allocateDirect(squareCoords.length * BYTES_PER_FLOAT);
vbb.order(ByteOrder.nativeOrder());
mSquareVertexBuffer = vbb.asFloatBuffer();
mSquareVertexBuffer.put(squareCoords);
mSquareVertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(squareIndex.length * 2);
ibb.order(ByteOrder.nativeOrder());
mSquareIndexBuffer = ibb.asShortBuffer();
mSquareIndexBuffer.put(squareIndex);
mSquareIndexBuffer.position(0);
}
short squareIndex[] = { 0, 1, 2, 0, 2, 3 };// 设置顶点的绘制顺序
static float squareCoords[] = {
-0.4f, 0.4f,// 左上
-0.4f, -0.4f,// 左下
0.4f, -0.4f,// 右下
0.4f, 0.4f };// 右上
private int mProgram = 0;
private int mMVPMatrixHandle = -1;
private int mPositionHandle = -1;
private int mColorHandle = -1;
private int mTextureHandle;
private boolean bulidProgram() {
mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
if (0 == mProgram) {
return false;
}
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
if (-1 == mPositionHandle) {
throw new RuntimeException("Could not get attrib location for aPosition");
}
mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
if (-1 == mTextureHandle) {
throw new RuntimeException("Could not get attrib location for aTextureCoord");
}
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
if (-1 == mColorHandle) {
throw new RuntimeException("Could not get attrib location for vColor");
}
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
if (-1 == mMVPMatrixHandle) {
throw new RuntimeException("Could not get attrib location for uMVPMatrix");
}
return true;
}
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (0 == vertexShader) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (0 == pixelShader) {
return 0;
}
int program = GLES20.glCreateProgram();
if (0 != program) {
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, pixelShader);
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (GLES20.GL_TRUE != linkStatus[0]) {// 链接失败
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (0 != shader) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (0 == compiled[0]) {
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
private final String VERTEX_SHADER =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"void main() {\n" +
// the matrix must be included as a modifier of gl_Position
" gl_Position = uMVPMatrix * aPosition;\n" +
"}\n";
private final String FRAGMENT_SHADER =
"precision mediump float;\n" +
"uniform vec4 vColor;\n" +
"void main() {\n" +
" gl_FragColor = vColor;\n" +
"}\n";
}