OpenGLES画一张图片

本文详细介绍了一个使用OpenGL ES进行图片渲染的实例,包括顶点着色器和片段着色器的编写,以及如何在Android平台上创建纹理并将其应用于全屏矩形,实现图片的实时显示。

在这里插入图片描述

//.glsl文件
//pic_vertex.glsl
attribute vec4 vPosition;
attribute vec2 vCoord;
varying vec2 aCoord;
void main(){
    gl_Position = vPosition;
    aCoord = vCoord;
}
//.glsl文件
//pic_fragment.glsl
precision mediump float;
varying vec2 aCoord;
uniform sampler2D vPicture;
void main(){
    gl_FragColor = texture2D(vPicture,aCoord);
}
public class PicRender implements RenderInterface {
    private Context context;
    private FloatBuffer vertexBuffer;
    private FloatBuffer coorBuffer;
    private int mProgram;
    private int vPositionHandle;
    private int vCoordHandle;
    private int picHandle;
    private int[] picHandleArray;
    private int width;
    private int height;

    public PicRender(Context con){
        context = con;
        vertexBuffer = ByteBuffer.allocateDirect(verTexArray.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        vertexBuffer.put(verTexArray);
        vertexBuffer.position(0);
        coorBuffer = ByteBuffer.allocateDirect(picCoorArray.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        coorBuffer.put(picCoorArray);
        coorBuffer.position(0);
    }
    //全屏矩形
    private float[] verTexArray = new float[]{
            -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 float[] picCoorArray = new float[]{
            0.0f,0.0f,//左上角
            0.0f,1.0f,//左下角
            1.0f,0.0f,//右上角
            1.0f,1.0f//右下角
    };

    @Override
    public void onCreate(Context context) {
        mProgram = GLES20.glCreateProgram();
        int vertexShader = Utils.createShader(GLES20.GL_VERTEX_SHADER,Utils.getRawShader(context,R.raw.pic_vertex));
        int fragmentShader = Utils.createShader(GLES20.GL_FRAGMENT_SHADER,Utils.getRawShader(context,R.raw.pic_fragment));
        GLES20.glAttachShader(mProgram,vertexShader);
        GLES20.glAttachShader(mProgram,fragmentShader);
        GLES20.glLinkProgram(mProgram);
        vPositionHandle = GLES20.glGetAttribLocation(mProgram,"vPosition");
        vCoordHandle = GLES20.glGetAttribLocation(mProgram,"vCoord");
        picHandle = GLES20.glGetUniformLocation(mProgram,"vPicture");

        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.a2);
        //产生贴图纹理句柄数组
        picHandleArray = new int[1];
        //给纹理句柄分配资源(产生贴图)
        GLES20.glGenTextures(1,picHandleArray,0);
        //绑定纹理句柄以便给她设置参数
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,picHandleArray[0]);
        //设置颜色最大的过滤器算法
        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);
        //设置横向超出范围处理方式
        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);
//        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,bitmap,0);
        ByteBuffer buffer = ByteBuffer.allocate(bitmap.getWidth()*bitmap.getHeight()*4);
        bitmap.copyPixelsToBuffer(buffer);
        buffer.position(0);
        GLES20.glTexImage2D(
                GLES20.GL_TEXTURE_2D,
                0,
                GLES20.GL_RGBA,
                bitmap.getWidth(),
                bitmap.getHeight(),
                0,
                GLES20.GL_RGBA,
                GLES20.GL_UNSIGNED_BYTE,
                buffer
        );

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
        bitmap.recycle();

    }

    @Override
    public void onSizeChange(int width, int height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public void onDrawFrame() {
        GLES20.glUseProgram(mProgram);
        GLES20.glEnableVertexAttribArray(vPositionHandle);
        GLES20.glVertexAttribPointer(vPositionHandle,3,GLES20.GL_FLOAT,false,3*4,vertexBuffer);
        GLES20.glEnableVertexAttribArray(vCoordHandle);
        GLES20.glVertexAttribPointer(vCoordHandle,2,GLES20.GL_FLOAT,false,2*4,coorBuffer);

        GLES20.glEnable(picHandle);
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,picHandleArray[0]);
        GLES20.glUniform1i(picHandle,0);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);
//        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
        GLES20.glDisable(picHandle);
        GLES20.glDisableVertexAttribArray(vCoordHandle);
        GLES20.glDisableVertexAttribArray(vPositionHandle);

    }
}
//自定义的控件
public class MyGLView extends GLSurfaceView implements GLSurfaceView.Renderer {
    private Context context;
//    private TriangleRender render;
    private PicRender picRender;
//    private RectRender rectRender;
//    private CameraRender cameraRender;
//    private CameraInterface camera;
//    private WaterRender waterRender;


    public MyGLView(Context context) {
        this(context,null);
    }
//    public void closeCamera(){
//        if(camera!=null){
//            camera.closeCamera();
//        }
//    };
//    public void setRotation(int dugress){
//        if(cameraRender!=null){
//            cameraRender.setRotation(dugress);
//        }
//    }

    public MyGLView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        setEGLContextClientVersion(2);//设置当前openjl版本
        setRenderer(this);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//设置渲染模式 自动和手动
//        requestRender();//要求重绘 在onDrawFrame中调用
//        render = new TriangleRender(context);
//        rectRender = new RectRender(context);
        picRender = new PicRender(context);
//        cameraRender = new CameraRender(context,this);
//        camera = new OldCamera(context);
//        waterRender = new WaterRender(context);
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
//        render.onCreate(context);
//        rectRenderr.onCreate(context);
        picRender.onCreate(context);
//        cameraRender.onCreate(context);
//        waterRender.onCreate(context);
    }


    @Override
    public void onSurfaceChanged(GL10 gl10, int i, int i1) {
        //i 宽
        //i1 高
        GLES20.glViewport(0,0,i,i1);//控制glView的大小
//        render.onSizeChange(i,i1);
//        rectRender.onSizeChange(i,i1);
        picRender.onSizeChange(i,i1);
//        cameraRender.onSizeChange(i,i1);
//        waterRender.onSizeChange(i,i1);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        //清除屏幕设置默认颜色为黑色
        GLES20.glClearColor(0.0f,0.0f,0.0f,1.0f);
        //清除深度缓存和颜色缓存
        GLES20.glClear(GLES20.GL_DEPTH_BITS|GLES20.GL_COLOR_BUFFER_BIT);
//        render.onDrawFrame();
//        rectRender.onDrawFrame();
        picRender.onDrawFrame();
//        cameraRender.onDrawFrame();
//        waterRender.onDrawFrame();
    }

//    public void normalFilter(){
//        if(cameraRender!=null){
//            cameraRender.setFilterType(0);
//        }
//    }
//    //黑白滤镜
//    public void blackWhiteFilter(){
//        if(cameraRender!=null){
//            cameraRender.setFilterType(1);
//        }
//    }
//    //模糊滤镜效果
//    public void blurFilter(){
//        if(cameraRender!=null){
//            cameraRender.setFilterType(2);
//        }
//    }
//    @Override
//    public void setSurface(SurfaceTexture texture) {
//
//        camera.openCamera(texture);
//        texture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
//            @Override
//            public void onFrameAvailable(SurfaceTexture surfaceTexture) {
//                requestRender();
//            }
//        });
//    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值