Opengl贴图

public class ImageFilter {

static final float COORD1[] = {

-1.0f, -1.0f,

            1.0f, 1.0f,

            -1.0f, 1.0f,

            1.0f, -1.0f,

    };

    static final float BOOK_COORD1[] = {

0.0f, 0.0f,

            1.0f, 1.0f,

            0.0f, 1.0f,

            1.0f, 0.0f,

    };

    static final float TEXTURE_COORD1[] = {

0.0f, 1.0f,

            1.0f, 1.0f,

            0.0f, 0.0f,

            1.0f, 0.0f,

    };

//世界坐标系

    static final float COORD_REVERSE[] = {

-1.0f, 1.0f,

            1.0f, 1.0f,

            -1.0f, -1.0f,

            1.0f, -1.0f,

    };

    //    纹理坐标系

    static final float TEXTURE_COORD_REVERSE[] = {

1.0f,0f,

            0.0f,0.0f,

            1.0f,1.0f,

            0.0f,1.0f

    };

    private StringmVertexShader;

    private StringmFragmentShader;

    private FloatBuffermPositionBuffer;

    private FloatBuffermTextureCubeBuffer;

    protected int mProgId;

    protected int mPosition;

    protected int inputTextureBuffer;

    protected int mInputTexture;

    public ImageFilter(Context context) {

this(OpenGLUtils.readRawTextFile(context,R.raw.base_vert), OpenGLUtils.readRawTextFile(context,R.raw.base_frag));

    }

public ImageFilter(String vertexShader, String fragmentShader) {

mVertexShader = vertexShader;

        mFragmentShader = fragmentShader;

    }

public void loadVertex() {

float[] coord =COORD1;

        float[] texture_coord =BOOK_COORD1;

        mPositionBuffer = ByteBuffer.allocateDirect(coord.length *4)

.order(ByteOrder.nativeOrder())

.asFloatBuffer();

        mPositionBuffer.put(coord).position(0);

        mTextureCubeBuffer = ByteBuffer.allocateDirect(texture_coord.length *4)

.order(ByteOrder.nativeOrder())

.asFloatBuffer();

        mTextureCubeBuffer.put(texture_coord).position(0);

    }

public void initShader() {

mProgId = OpenGLUtils.loadProgram(mVertexShader, mFragmentShader);

        mPosition = GLES20.glGetAttribLocation(mProgId, "position");

        mInputTexture = GLES20.glGetUniformLocation(mProgId, "inputImageTexture");

        inputTextureBuffer = GLES20.glGetAttribLocation(mProgId,

                "inputTextureCoordinate");

    }

public int  init(Bitmap bitmap) {

loadVertex();

        initShader();

        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

        return  initTexture(bitmap);

    }

private int initTexture( Bitmap bitmap) {

int[] textures =new int[1];

        GLES20.glGenTextures(1, textures, 0);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);

        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

        return textures[0];

    }

public void drawFrame(int glTextureId) {

GLES20.glUseProgram(mProgId);

        mPositionBuffer.position(0);

        GLES20.glVertexAttribPointer(mPosition, 2, GLES20.GL_FLOAT, false, 0, mPositionBuffer);

        GLES20.glEnableVertexAttribArray(mPosition);

        mTextureCubeBuffer.position(0);

        GLES20.glVertexAttribPointer(inputTextureBuffer, 2, GLES20.GL_FLOAT, false, 0,

                mTextureCubeBuffer);

        GLES20.glEnableVertexAttribArray(inputTextureBuffer);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, glTextureId);

        GLES20.glUniform1i(mInputTexture, 0);

//      这句话 来进行渲染

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

        GLES20.glDisableVertexAttribArray(mPosition);

        GLES20.glDisableVertexAttribArray(inputTextureBuffer);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

        GLES20.glDisable(GLES20.GL_BLEND);

    }

}


public class MainActivityextends AppCompatActivity {

private GLSurfaceViewmSurfaceView;

    private int mTextureId =-1;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        ViewGroup container = (ViewGroup) findViewById(R.id.main);

        mSurfaceView =new GLSurfaceView(this);

        mSurfaceView.setEGLContextClientVersion(2);

        container.addView(mSurfaceView);

        final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.demo);

        final ImageFilter filter =new ImageFilter(this);

        mSurfaceView.setRenderer(new GLSurfaceView.Renderer() {

@Override

            public void onSurfaceCreated(GL10 gl, EGLConfig config) {

mTextureId =filter.init(bitmap);

            }

@Override

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

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

            }

@Override

            public void onDrawFrame(GL10 gl) {

filter.drawFrame(mTextureId);

            }

});

    }

}


public class OpenGLUtils {

private static final StringTAG ="OpenGLUtils";

    public static final float[]VERTEX = {

-1.0f, -1.0f,

            1.0f, -1.0f,

            -1.0f, 1.0f,

            1.0f, 1.0f

    };

    public static final float[]TEXURE = {

0.0f, 1.0f,

            1.0f, 1.0f,

            0.0f, 0.0f,

            1.0f, 0.0f

    };

    public static final float[]TEXTURE_NO_ROTATION = {

0.0f, 1.0f,

            1.0f, 1.0f,

            0.0f, 0.0f,

            1.0f, 0.0f

    };

    public static void glGenTextures(int[] textures) {

GLES20.glGenTextures(textures.length, textures, 0);

        for (int i =0; i < textures.length; i++) {

//与摄像头不同,摄像头是外部纹理external oes

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[i]);

            /**

            *  必须:设置纹理过滤参数设置

            */

            /*设置纹理缩放过滤*/

            // GL_NEAREST: 使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色

            // 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_MIN_FILTER,

                    GLES20.GL_LINEAR);//缩小过滤

            /**

            * 可选:设置纹理环绕方向

            */

            //纹理坐标的范围是0-1。超出这一范围的坐标将被OpenGL根据GL_TEXTURE_WRAP参数的值进行处理

            //GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T 分别为x,y方向。

            //GL_REPEAT:平铺

            //GL_MIRRORED_REPEAT: 纹理坐标是奇数时使用镜像平铺

            //GL_CLAMP_TO_EDGE: 坐标超出部分被截取成0、1,边缘拉伸

//            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);

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);

        }

}

public static StringreadRawTextFile(Context context, int rawId) {

InputStream is = context.getResources().openRawResource(rawId);

        BufferedReader br =new BufferedReader(new InputStreamReader(is));

        String line;

        StringBuilder sb =new StringBuilder();

        try {

while ((line = br.readLine()) !=null) {

sb.append(line);

                sb.append("\n");

            }

}catch (Exception e) {

e.printStackTrace();

        }

try {

br.close();

        }catch (IOException e) {

e.printStackTrace();

        }

return sb.toString();

    }

public static int loadProgram(String vSource, String fSource) {

/**

        * 顶点着色器

        */

        int vShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

        //加载着色器代码

        GLES20.glShaderSource(vShader, vSource);

        //编译(配置)

        GLES20.glCompileShader(vShader);

        //查看配置 是否成功

        int[] status =new int[1];

        GLES20.glGetShaderiv(vShader, GLES20.GL_COMPILE_STATUS, status, 0);

        if (status[0] != GLES20.GL_TRUE) {

//失败

            throw new IllegalStateException("load vertex shader:" + GLES20.glGetShaderInfoLog

                    (vShader));

        }

/**

        *  片元着色器

        *  流程和上面一样

        */

        int fShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

        //加载着色器代码

        GLES20.glShaderSource(fShader, fSource);

        //编译(配置)

        GLES20.glCompileShader(fShader);

        //查看配置 是否成功

        GLES20.glGetShaderiv(fShader, GLES20.GL_COMPILE_STATUS, status, 0);

        if (status[0] != GLES20.GL_TRUE) {

//失败

            throw new IllegalStateException("load fragment shader:" + GLES20.glGetShaderInfoLog

                    (vShader));

        }

/**

        * 创建着色器程序

        */

        int program = GLES20.glCreateProgram();

        //绑定顶点和片元

        GLES20.glAttachShader(program, vShader);

        GLES20.glAttachShader(program, fShader);

        //链接着色器程序

        GLES20.glLinkProgram(program);

        //获得状态

        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);

        if (status[0] != GLES20.GL_TRUE) {

throw new IllegalStateException("link program:" + GLES20.glGetProgramInfoLog(program));

        }

GLES20.glDeleteShader(vShader);

        GLES20.glDeleteShader(fShader);

        return program;

    }

public static void copyAssets2SdCard(Context context, String src, String dst) {

try {

File file =new File(dst);

            if (!file.exists()) {

InputStream is = context.getAssets().open(src);

                FileOutputStream fos =new FileOutputStream(file);

                int len;

                byte[] buffer =new byte[2048];

                while ((len = is.read(buffer)) != -1) {

fos.write(buffer, 0, len);

                }

is.close();

                fos.close();

            }

}catch (IOException e) {

e.printStackTrace();

        }

}

public static final int NO_TEXTURE = -1;

    public static int loadShader(String shaderStr, int type) {

int[] compiled =new int[1];

        int iShader = GLES20.glCreateShader(type);

        checkGlError("");

        GLES20.glShaderSource(iShader, shaderStr);

        checkGlError("");

        GLES20.glCompileShader(iShader);

        checkGlError("");

        GLES20.glGetShaderiv(iShader, GLES20.GL_COMPILE_STATUS, compiled, 0);

        checkGlError("");

        if (compiled[0] ==0) {

Log.d("Load Shader Failed", "Compilation\n" + GLES20.glGetShaderInfoLog(iShader));

            return 0;

        }

return iShader;

    }

public static int loadTexture(final Bitmap bitmap, final int usedTextureId) {

int[] textures =new int[1];

        if (usedTextureId ==NO_TEXTURE) {

GLES20.glGenTextures(1, textures, 0);

            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);

            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

        }else {

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTextureId);

            GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bitmap);

            textures[0] = usedTextureId;

        }

return textures[0];

    }

public static void checkGlError(String op) {

int error;

        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {

Log.e("GLES20_ERROR", op +": glError " + error);

            throw new RuntimeException(op +": glError " + error);

        }

}

}


varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

//片元      纹理坐标系2

void main(){

gl_FragColor = texture2D(inputImageTexture, textureCoordinate);

}


attribute vec4 position;

attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main(){

//内置变量: 把坐标点赋值给gl_position 就Ok了。  4 个元素  gl_Position  世界坐标系 为基础

    gl_Position = position;

    textureCoordinate = inputTextureCoordinate.xy;

}

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

推荐阅读更多精彩内容