目录
纹理坐标相当于:srcRect
顶点坐标相当于:dstRect
vertex_shader.glsl
//vec4使用4个向量xyzw
attribute vec4 av_Position;
//这里绘制2D图形,所以使用vec2两个向量的即可xy
attribute vec2 af_Position;
varying vec2 v_texPo;
void main() {
v_texPo = af_Position;
gl_Position = av_Position;
}
注: attribute 只能在vertex中使用
varying 用于vertex和fragment之间传递值
fragment_shader.glsl
//精度
precision mediump float;
varying vec2 v_texPo;
uniform sampler2D sTexture;
void main() {
gl_FragColor=texture2D(sTexture, v_texPo);
}
注: uniform 用于在application中向vertex和fragment中传递值。
GLTestView.java
package com.jianji.delogo.Test.MediaCodec;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.util.AttributeSet;
import com.jianji.delogo.R;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class GLTestView extends GLSurfaceView implements GLSurfaceView.Renderer {
private Context context;
//绘制坐标范围
float[] vertexData = {
-1f, -1f,
1f, -1.0f,
-1f, 1.0f,
1f, 1f
};
float[] textureData = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
//为坐标分配本地内存地址,不受jvm的影响
FloatBuffer vertexBuffer;
FloatBuffer textureBuffer;
public GLTestView(Context context) {
this(context, null);
}
public GLTestView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
//设置OpenGL的版本
setEGLContextClientVersion(2);
setRenderer(this);
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())//对齐,加快处理速度
.asFloatBuffer()
.put(vertexData);
//指向0的位置
vertexBuffer.position(0);
textureBuffer = ByteBuffer.allocateDirect(textureData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(textureData);
textureBuffer.position(0);
}
private int program;
private int avPosition;
private int afPosition;
private int textureId;
/**
* Called when the surface is created or recreated.
*/
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
String vertexSource = ShaderUtil.readRawTxt(context, R.raw.vertex_shader);
String fragmentSource = ShaderUtil.readRawTxt(context, R.raw.fragment_shader);
program = ShaderUtil.createProgram(vertexSource, fragmentSource);
if (program > 0) {
avPosition = GLES20.glGetAttribLocation(program, "av_Position");
afPosition = GLES20.glGetAttribLocation(program, "af_Position");
int[] textureIds = new int[1];
//生成纹理
GLES20.glGenTextures(1, textureIds, 0);
if (textureIds[0] == 0) {
return;
}
textureId = textureIds[0];
//绑定纹理
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
//环绕方式
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);
//过滤方式
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.default_banner_chat);
if (bitmap == null) {
return;
}
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
/**
* Called when the surface changed size.
*/
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//设置大小位置
GLES20.glViewport(0, 0, width, height);
}
/**
* Called to draw the current frame.
*/
@Override
public void onDrawFrame(GL10 gl) {
//清屏,清理掉颜色的缓冲区
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//设置清屏的颜色,这里是float颜色的取值范围的[0,1]
GLES20.glClearColor(1.0f, 0f, 0f, 1.0f);
//使用program
GLES20.glUseProgram(program);
//设置为可用的状态
GLES20.glEnableVertexAttribArray(avPosition);
//size 指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a))
//stride 指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。
//size 2 代表(x,y),stride 8 代表跨度 (2个点为一组,2个float有8个字节)
GLES20.glVertexAttribPointer(avPosition, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer);
GLES20.glEnableVertexAttribArray(afPosition);
GLES20.glVertexAttribPointer(afPosition, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
正常显示一张图片
只显示左下三角
//这里只需要绘制三个点
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 3);
只显示图片的右上1/4
//坐标区域
float[] vertexData = {
-1f, -1f,
1f, -1.0f,
-1f, 1.0f,
1f, 1f
};
//纹理区域
float[] textureData = {
// 0f, 1f,
// 1f, 1f,
// 0f, 0f,
// 1f, 0f
0.5f, 0.5f,
1f, 0.5f,
0.5f, 0f,
1f, 0f
};
整个图片,放在显示区域的右上1/4
//坐标区域
float[] vertexData = {
// -1f, -1f,
// 1f, -1.0f,
// -1f, 1.0f,
// 1f, 1f
0f, 0f,
1f, 0f,
0f, 1f,
1f, 1f
};
//纹理区域
float[] textureData = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};