2020-11-01

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;

}

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355