package com.example.datalibrary.view;
|
|
import android.graphics.Bitmap;
|
import android.opengl.GLES20;
|
import android.opengl.GLSurfaceView;
|
import android.opengl.GLUtils;
|
import android.util.Log;
|
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.nio.FloatBuffer;
|
import java.nio.ShortBuffer;
|
|
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.opengles.GL10;
|
|
public class PicoRenderer implements GLSurfaceView.Renderer {
|
private static final String TAG = "PicoRenderer";
|
private int mProgram;
|
|
Bitmap mBitmap;
|
int mPositionHandle = 0;
|
int mTexCoordHandle = 0;
|
int mTexSamplerHandle = 0;
|
|
float[] vertices = {1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f};
|
|
private static final float[] TEX_VERTEX = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
|
private static final short[] VERTEX_INDEX = {0, 1, 2, 0, 2, 3};
|
|
ShortBuffer mVertexIndexBuffer;
|
FloatBuffer vertexBuf;
|
FloatBuffer mTexVertexBuffer;
|
|
public void setBuf(Bitmap bitmap) {
|
this.mBitmap = bitmap;
|
}
|
|
public PicoRenderer() {
|
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
|
vbb.order(ByteOrder.nativeOrder());
|
vertexBuf = vbb.asFloatBuffer();
|
vertexBuf.put(vertices);
|
vertexBuf.position(0);
|
|
mTexVertexBuffer = ByteBuffer.allocateDirect(TEX_VERTEX.length * 4)
|
.order(ByteOrder.nativeOrder())
|
.asFloatBuffer()
|
.put(TEX_VERTEX);
|
mTexVertexBuffer.position(0);
|
|
mVertexIndexBuffer = ByteBuffer.allocateDirect(VERTEX_INDEX.length * 2)
|
.order(ByteOrder.nativeOrder())
|
.asShortBuffer()
|
.put(VERTEX_INDEX);
|
mVertexIndexBuffer.position(0);
|
}
|
|
private int loadShader(int shaderType, String sourceCode) {
|
int shader = GLES20.glCreateShader(shaderType);
|
if (shader != 0) {
|
GLES20.glShaderSource(shader, sourceCode);
|
GLES20.glCompileShader(shader);
|
int[] compiled = new int[1];
|
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
|
if (compiled[0] == 0) {
|
Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");
|
Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));
|
GLES20.glDeleteShader(shader);
|
shader = 0;
|
}
|
}
|
return shader;
|
}
|
|
private int createProgram(String vertexSource, String fragmentSource) {
|
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
|
if (vertexShader == 0) {
|
return 0;
|
}
|
|
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
|
if (pixelShader == 0) {
|
return 0;
|
}
|
|
mProgram = GLES20.glCreateProgram();
|
if (mProgram != 0) {
|
GLES20.glAttachShader(mProgram, vertexShader);
|
GLES20.glAttachShader(mProgram, pixelShader);
|
GLES20.glLinkProgram(mProgram);
|
|
GLES20.glUseProgram(mProgram);
|
int[] linkStatus = new int[1];
|
GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0);
|
if (linkStatus[0] != GLES20.GL_TRUE) {
|
Log.e("ES20_ERROR", "Could not link mProgram: ");
|
Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(mProgram));
|
GLES20.glDeleteProgram(mProgram);
|
mProgram = 0;
|
}
|
}
|
return mProgram;
|
}
|
|
@Override
|
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
|
mProgram = createProgram(VERTICES_SHADER, FRAGMENT_SHADER);
|
GLES20.glClearColor(0.0f, 0, 0, 0.0f);
|
|
int[] texNames = new int[1];
|
GLES20.glGenTextures(1, texNames, 0);
|
int mTexName = texNames[0];
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexName);
|
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);
|
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);
|
// GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, m_cameraPreview.GetBitmap(), 0);
|
// mBitmap.recycle();
|
|
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
|
mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texCoord");
|
mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram, "s_texture");
|
|
GLES20.glEnableVertexAttribArray(mPositionHandle);
|
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false,
|
12, vertexBuf);
|
|
GLES20.glEnableVertexAttribArray(mTexCoordHandle);
|
GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false, 0,
|
mTexVertexBuffer);
|
|
}
|
|
@Override
|
public void onSurfaceChanged(GL10 gl10, int width, int height) {
|
GLES20.glViewport(0, 0, width, height);
|
}
|
|
public void onDrawFrame(GL10 gl10) {
|
GLES20.glUniform1i(mTexSamplerHandle, 0);
|
if (mBitmap != null) {
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mBitmap, 0);
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, VERTEX_INDEX.length,
|
GLES20.GL_UNSIGNED_SHORT, mVertexIndexBuffer);
|
} else {
|
Log.e(TAG, "Bitmap is null");
|
}
|
}
|
|
private static final String VERTICES_SHADER
|
= "uniform mat4 uMVPMatrix;" +
|
"attribute vec4 vPosition;" +
|
"attribute vec2 a_texCoord;" +
|
"varying vec2 v_texCoord;" +
|
"void main() {" +
|
" gl_Position = vPosition;" +
|
" v_texCoord = a_texCoord;" +
|
"}";
|
|
private static final String FRAGMENT_SHADER
|
= "precision mediump float;" +
|
"varying vec2 v_texCoord;" +
|
"uniform sampler2D s_texture;" +
|
"void main() {" +
|
"vec4 nColor=texture2D(s_texture,v_texCoord);" +
|
" gl_FragColor = vec4(nColor.r,nColor.g,nColor.b,nColor.a);" +
|
"}";
|
}
|