2020-11-01

2020-11-01  本文已影响0人  YeAh526

package yeah.test.opengl.view;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.opengl.GLES20;

import android.opengl.GLSurfaceView;

import android.util.AttributeSet;

import android.util.Log;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

import jp.co.cyberagent.android.gpuimage.util.OpenGlUtils;

import yeah.test.R;

import yeah.test.util.LogTag;

/**

* @author: heweiyan

* @date : 2020/11/1

*/

public class OpenGLTestSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {

// 测试用的顶点着色器

    public static final String TEST_VERTEX_SHADER ="" +

// 含四个浮点型数据的向量,顶点坐标

            "attribute vec4 vPosition;\n" +

// 纹理坐标,从图片上采集像素的位置

            "attribute vec2 vCoord;\n" +

" \n" +

// 易变坐标,通过varing传给片元着色器varing修饰的变量

            "varying vec2 aCoord;\n" +

" \n" +

"void main()\n" +

"{\n" +

"    gl_Position = vPosition;\n" +

"    aCoord = vCoord;\n" +

"}";

// 测试用的片元着色器

    public static final String TEST_FRAGMENT_SHADER ="" +

// 跟顶点着色器的aCoord对应起来,一定要有

            "varying highp vec2 aCoord;\n" +

// 2D纹理采样器(代表一层纹理,一般就是一张图片)

            "uniform sampler2D vTexture;\n" +

"uniform highp float red;\n" +

"uniform highp float green;\n" +

"uniform highp float blue;\n" +

"\n" +

"void main()\n" +

"{\n" +

// 采集vTexutre画布的aCoord位置的像素

            "      highp vec4 textureColor = texture2D(vTexture, aCoord);\n" +

"      \n" +

"      gl_FragColor = vec4(textureColor.r * red, textureColor.g * green, textureColor.b * blue, 1.0);\n" +

"}";

public OpenGLTestSurfaceView(Context context) {

this(context,null);

}

public OpenGLTestSurfaceView(Context context,AttributeSet attrs) {

super(context, attrs);

init();

}

// 片元着色器的纹理变量ID

    private int vTexture;

private int[]colorsID =new int[3];

// 用于绑定画布的纹理变量ID

    private int mBitmapTextureID;

private void init() {

// OpenGL ES版本设为2

        setEGLContextClientVersion(2);

// 设置渲染器

        setRenderer(this);

//        // 按需渲染,当requestRender()时才会回调Renderer的onDrawFrame()

//        setRenderMode(RENDERMODE_WHEN_DIRTY);

        // 连续渲染

        setRenderMode(RENDERMODE_CONTINUOUSLY);

}

@Override

    public void onSurfaceCreated(GL10 gl,EGLConfig config) {

Log.e(LogTag.TEST_OPENGL,"onSurfaceCreated()");

// 先清空画布

        glClear();

initGLSL();

}

/**

    * 清空一下OpenGL画布

    */

    private void glClear() {

GLES20.glClearColor(0,0,0,0);

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

}

/**

    * 初始化OpenGL的GLSL(着色器语言)

    * GLSL是面向过程的语言

    */

    private void initGLSL() {

// 根据顶点着色器和片元着色器创建一个着色器程序ID

        int program =OpenGlUtils.loadProgram(TEST_VERTEX_SHADER,TEST_FRAGMENT_SHADER);

// 应用该程序

        GLES20.glUseProgram(program);

// 获取顶点着色器的参数ID

        int vPosition =GLES20.glGetAttribLocation(program,"vPosition");

int vCoord =GLES20.glGetAttribLocation(program,"vCoord");

// 获取片元着色器的图片参数ID

        vTexture =GLES20.glGetUniformLocation(program,"vTexture");

colorsID[0] =GLES20.glGetUniformLocation(program,"red");

colorsID[1] =GLES20.glGetUniformLocation(program,"green");

colorsID[2] =GLES20.glGetUniformLocation(program,"blue");

mBitmapTextureID =OpenGlUtils.NO_TEXTURE;

initCoord(vPosition,vCoord);

}

/**

    * 设置顶点和纹理坐标数据

    *

    * @param vPositon 顶点坐标变量ID

    * @param vCoord  纹理坐标变量ID

*/

    private void initCoord(int vPositon,int vCoord) {

// 给vPosition赋值

        FloatBuffer vertexBuffer =ByteBuffer.allocateDirect(VERTEX.length *4)

.order(ByteOrder.nativeOrder())

.asFloatBuffer()

.put(VERTEX);

vertexBuffer.position(0);

GLES20.glVertexAttribPointer(vPositon,2,GLES20.GL_FLOAT,false,0,vertexBuffer);

GLES20.glEnableVertexAttribArray(vPositon);

// 给vCoord赋值

        FloatBuffer textureBuffer =ByteBuffer.allocateDirect(TEXTURE.length *4)

.order(ByteOrder.nativeOrder())

.asFloatBuffer()

.put(TEXTURE);

textureBuffer.position(0);

GLES20.glVertexAttribPointer(vCoord,2,GLES20.GL_FLOAT,false,0,textureBuffer);

GLES20.glEnableVertexAttribArray(vCoord);

}

@Override

    public void onSurfaceChanged(GL10 gl,int width,int height) {

Log.e(LogTag.TEST_OPENGL,"onSurfaceChanged()");

GLES20.glViewport(0,0, width, height);

}

private float VERTEX[] = {

-1.0f,1.0f,

1.0f,1.0f,

-1.0f, -1.0f,

1.0f, -1.0f,

};

private float TEXTURE[] = {

0.0f,0.0f,

1.0f,0.0f,

0.0f,1.0f,

1.0f,1.0f,

};

private Bitmap mBitmap;

private int[]rgbArry =new int[]{100,0,0};

@Override

    public void onDrawFrame(GL10 gl) {

Log.e(LogTag.TEST_OPENGL,"onDrawFrame()");

if (mBitmap ==null ||mBitmap.isRecycled()) {

Log.e(LogTag.TEST_OPENGL,"Create bitmap.");

mBitmap =BitmapFactory.decodeResource(getResources(),R.drawable.beauty);

// 根据Bitmap创建一个纹理ID

            mBitmapTextureID =OpenGlUtils.loadTexture(mBitmap,mBitmapTextureID,false);

}

// 清空一下画布

        glClear();

for (int i =0; i

if (rgbArry[i] !=0) {

rgbArry[i] -=1;

if (rgbArry[i] ==0) {

rgbArry[(i +1) %rgbArry.length] =100;

}

break;

}

}

for (int i =0; i

GLES20.glUniform1f(colorsID[i],rgbArry[i] /100f);

}

// 激活一个0号画布

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

// 把创建好的图片画到画布上去

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mBitmapTextureID);

// 把画好东西的画布赋值给片元着色器的vTexture

        // 第二个参数是画布的序号,和上面激活的画布序号要对应

        GLES20.glUniform1i(vTexture,0);

// 通知GLSL画画

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);

}

@Override

    protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

if (mBitmap !=null && !mBitmap.isRecycled()) {

mBitmap.recycle();

mBitmap =null;

}

}

}

上一篇下一篇

猜你喜欢

热点阅读