public class MainActivity extends Activity {
private GLSurfaceView mEffectView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DemoTextureRenderer renderer = new DemoTextureRenderer(this);
mEffectView = new GLSurfaceView(this);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(renderer);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
setContentView(mEffectView);
}
}
class DemoTextureRenderer implements GLSurfaceView.Renderer{
private Bitmap bmp;
private int mProgram;
private int mTexSamplerHandle;
private int mTexCoordHandle;
private int mPosCoordHandle;
private FloatBuffer mTexVertices;
private FloatBuffer mPosVertices;
private int[] mTextures = new int[2];
public DemoTextureRenderer(Context c) {
bmp = BitmapFactory.decodeResource(c.getResources(), R.drawable.aa);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//纹理坐标屏幕右上角为原点(左下,右下,左上,右上)
float[] TEX_VERTICES = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
mTexVertices = ByteBuffer.allocateDirect(TEX_VERTICES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mTexVertices.put(TEX_VERTICES).position(0);
//顶点坐标屏幕中心点为原点(左下,右下,左上,右上)
float[] POS_VERTICES = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f };
mPosVertices = ByteBuffer.allocateDirect(POS_VERTICES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mPosVertices.put(POS_VERTICES).position(0);
//着色器程序
String VERTEX_SHADER_CODE =
"attribute vec4 a_position;\n" +
"attribute vec2 a_texcoord;\n" +
"varying vec2 v_texcoord;\n" +
"void main() {\n" +
" gl_Position = a_position;\n" +
" v_texcoord = a_texcoord;\n" +
"}\n";
String FRAGMENT_SHADER_CODE =
"precision mediump float;\n" +
"uniform sampler2D tex_sampler;\n" +
"varying vec2 v_texcoord;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(tex_sampler, v_texcoord);\n" +
"}\n";
mProgram = GLShaderToolbox.createProgram(VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE);
mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram,"tex_sampler");
mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord");
mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position");
//创建纹理并将图片贴入纹理
GLES20.glGenTextures(2, mTextures , 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
GLShaderToolbox.initTextureNeedParams();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
GLShaderToolbox.checkGlError("glViewport");
//调整AspectRatio 保证landscape和portrait的时候显示比例相同,图片不会被拉伸
if (mPosVertices != null) {
float imgAspectRatio = bmp.getWidth() / (float)bmp.getHeight();
float viewAspectRatio = width / (float)height;
float relativeAspectRatio = viewAspectRatio / imgAspectRatio;
float x0, y0, x1, y1;
if (relativeAspectRatio > 1.0f) {
x0 = -1.0f / relativeAspectRatio;
y0 = -1.0f;
x1 = 1.0f / relativeAspectRatio;
y1 = 1.0f;
} else {
x0 = -1.0f;
y0 = -relativeAspectRatio;
x1 = 1.0f;
y1 = relativeAspectRatio;
}
float[] coords = new float[] { x0, y0, x1, y0, x0, y1, x1, y1 };
mPosVertices.put(coords).position(0);
}
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
GLShaderToolbox.checkGlError("glUseProgram");
//将纹理坐标传递给着色器程序并使能属性数组
GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTexVertices);
GLES20.glEnableVertexAttribArray(mTexCoordHandle);
GLShaderToolbox.checkGlError("vertex attribute setup");
//将顶点坐标传递给着色器程序并使能属性数组
GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mPosVertices);
GLES20.glEnableVertexAttribArray(mPosCoordHandle);
GLShaderToolbox.checkGlError("vertex attribute setup");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLShaderToolbox.checkGlError("glActiveTexture");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLShaderToolbox.checkGlError("glBindTexture");
GLES20.glUniform1i(mTexSamplerHandle, 0);
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
class GLShaderToolbox {
public static int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
String info = GLES20.glGetShaderInfoLog(shader);
GLES20.glDeleteShader(shader);
shader = 0;
throw new RuntimeException("Could not compile shader " +
shaderType + ":" + info);
}
}
return shader;
}
public static int createProgram(String vertexSourceCode, String fragmentSourceCode) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSourceCode);
if (vertexShader == 0) return 0;
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSourceCode);
if (pixelShader == 0) return 0;
int program = GLES20.glCreateProgram();
if (program != 0) {
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
String info = GLES20.glGetProgramInfoLog(program);
GLES20.glDeleteProgram(program);
program = 0;
throw new RuntimeException("Could not link program: " + info);
}
}
return program;
}
public static void checkGlError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
throw new RuntimeException(op + ": glError " + error);
}
}
public static void initTextureNeedParams() {
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
}
}
Android之GLES2.0显示图片测试代码
最新推荐文章于 2023-11-19 09:23:07 发布