紋理
紋理是物體表面的一幅或幾幅二維圖形,也是紋理貼圖。
原理
紋理映射的坐标系,紋理映射坐标系和頂點着色器的坐标系不一樣
頂點坐标系:

紋理坐标系:紋理坐标用浮點數來表示,範圍一般從0.0到1.0,左上角坐标為(0.0,0.0),右上角坐标為(1.0,0.0),左下角坐标為(0.0,1.0),右下角坐标為(1.0,1.0),具體如下:
顯示圖檔
主要是修改頂點着色器和片元着色器。比正方形多了一個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);
}
}