美文网首页
2020-11-01

2020-11-01

作者: YeAh526 | 来源:发表于2020-11-01 23:41 被阅读0次

    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;

    }

    }

    }

    相关文章

      网友评论

          本文标题:2020-11-01

          本文链接:https://www.haomeiwen.com/subject/rzhpvktx.html