纹理是物体表面的一幅或几幅二维图形,也是纹理贴图。
纹理映射的坐标系,纹理映射坐标系和顶点着色器的坐标系不一样
主要是修改顶点着色器和片元着色器。比正方形多了一个vec2的参数。
图片着色器
正方形着色器
public class SquareRenderer extends BackgroundRender implements GLSurfaceView.Renderer {
private FloatBuffer vertexBuffer;
private ShortBuffer indexBuffer;
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"uniform mat4 vMatrix;" +
"void main() {" +
" gl_Position = vMatrix*vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private int mProgram;
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f // top right
};
static short index[] = {
0, 1, 2, 0, 2, 3
};
private int mPositionHandle;
private int mColorHandle;
private float[] mViewMatrix = new float[16];
private float[] mProjectMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
//顶点个数
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
//顶点之间的偏移量
private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节
private int mMatrixHandler;
//设置颜色,依次为红绿蓝和透明通道
float color[] = {0.0f, 1.0f, 0.0f, 1.0f ,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f};
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
ByteBuffer bb = ByteBuffer.allocateDirect(
triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
ByteBuffer cc = ByteBuffer.allocateDirect(index.length * 2);
cc.order(ByteOrder.nativeOrder());
indexBuffer = cc.asShortBuffer();
indexBuffer.put(index);
indexBuffer.position(0);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
//创建一个空的OpenGLES程序
mProgram = GLES20.glCreateProgram();
//将顶点着色器加入到程序
GLES20.glAttachShader(mProgram, vertexShader);
//将片元着色器加入到程序中
GLES20.glAttachShader(mProgram, fragmentShader);
//连接到着色器程序
GLES20.glLinkProgram(mProgram);
}
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
//计算宽高比
float ratio = (float) width / height;
//设置透视投影
Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
//设置相机位置
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
//计算变换矩阵
Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0);
}
@Override
public void onDrawFrame(GL10 gl10) {
//将程序加入到OpenGLES2.0环境
GLES20.glUseProgram(mProgram);
//获取变换矩阵vMatrix成员句柄
mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix");
//指定vMatrix的值
GLES20.glUniformMatrix4fv(mMatrixHandler, 1, false, mMVPMatrix, 0);
//获取顶点着色器的vPosition成员句柄
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
//启用正方形顶点的句柄
GLES20.glEnableVertexAttribArray(mPositionHandle);
//准备正方形的坐标数据
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
//获取片元着色器的vColor成员的句柄
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
//设置绘制正方形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//索引法绘制正方形
GLES20.glDrawElements(GLES20.GL_TRIANGLES, index.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
//禁止顶点数组的句柄
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}