OpenGl 简易触摸放大器

效果如下 

 主要代码

GLSurfaceView 
 mGLView = (GLSurfaceView) findViewById(R.id.mGLView);
        mGLView.setEGLContextClientVersion(2);
        mGLView.setRenderer(mRender);
        mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        mGLView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        x = event.getX();
                        y = event.getY();
                        mRender.setXY(x, y);
                        mGLView.requestRender();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (dis(event.getX() - x, event.getY() - y) > MIN_DISTANCE) {
                            mRender.setXY(x, y);
                            mGLView.requestRender();
                        }
                        x = event.getX();
                        y = event.getY();
                        break;

                    case MotionEvent.ACTION_UP:
                        x = event.getX();
                        y = event.getY();
                        break;

                }
                return true;
            }
        });

Render 纹理

/*
 *
 * FBORender.java
 *
 * Created by tyearlin on 2019/03/01
 */
package qt.lin.opengl.zoom;

import java.nio.ByteBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.util.Log;

import qt.lin.opengl.filter.AFilter;
import qt.lin.opengl.filter.NoFilter;

import static android.opengl.GLES20.*;


public class Render implements GLSurfaceView.Renderer {

    private String TAG = "Render";
    public static final int RADIS = 80; //r
    private float x, y;
    private int width, hegith;
    private Callback mCallback;
    private Bitmap mBitmap;
    private AFilter mFilter;
    private int[] mTextureIds = new int[1];
    private ByteBuffer mScaleBuffer;

    public Render(Resources res) {
        mFilter = new NoFilter(res);
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        mFilter.create();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        Log.d(TAG, "onSurfaceChanged:" + width + "h:" + height);
        GLES20.glViewport(0, 0, width, height);
        this.width = width;
        this.hegith = height;


    }

    @Override
    public void onDrawFrame(GL10 gl) {
        if (mBitmap != null) {
            setUp();
            //渲染到纹理
            mFilter.setTextureId(mTextureIds[0]);
            mFilter.draw();
            //获取采样数据
            //y反向取
            int centX = (int) (x - RADIS / 2);
            int centY = (int) ((hegith - y) - RADIS / 2);
            Log.d(TAG, "x:" + centX + "y:" + centY);
            glReadPixels(centX, centY, RADIS, RADIS, GL_RGBA,
                    GL_UNSIGNED_BYTE, mScaleBuffer);
            if (mCallback != null) {
                mCallback.onCall(mScaleBuffer);
            }
            release();
        }
    }

    public void setCallback(Callback callback) {
        this.mCallback = callback;
    }

    public void setBitmap(Bitmap bitmap) {
        this.mBitmap = bitmap;
    }

    public void setUp() {
        //create texture
        glGenTextures(1, mTextureIds, 0);
        glBindTexture(GL_TEXTURE_2D, mTextureIds[0]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mBitmap, 0);
        //buffer
        mScaleBuffer = ByteBuffer.allocate(RADIS * RADIS * 4);
    }

    public void release() {
        mScaleBuffer.clear();
        mScaleBuffer = null;
        glBindTexture(GL_TEXTURE, 0);
        glDeleteTextures(1, mTextureIds, 0);
    }

    public void setXY(float x, float y) {
        this.x = x;
        this.y = y;
    }


    interface Callback {
        void onCall(ByteBuffer data);
    }
}

//AFliter  顶点 纹理坐标

 //顶点坐标
    private float pos[] = {
        -1.0f,  1.0f,
        -1.0f, -1.0f,
        1.0f, 1.0f,
        1.0f,  -1.0f,
    };

    //纹理坐标
    private float[] coord={
        0.0f, 0.0f,
        0.0f,  1.0f,
        1.0f,  0.0f,
        1.0f, 1.0f,
    };

加载shader

 protected final void createProgram(String vertex,String fragment){
        mProgram= uCreateGlProgram(vertex,fragment);
        mHPosition= GLES20.glGetAttribLocation(mProgram, "vPosition");
        mHCoord=GLES20.glGetAttribLocation(mProgram,"vCoord");
        mHMatrix=GLES20.glGetUniformLocation(mProgram,"vMatrix");
        mHTexture=GLES20.glGetUniformLocation(mProgram,"vTexture");
    }

 绘制

//Afilter draw
 public void draw(){
        //清屏
        onClear();
        //加载shader
        onUseProgram();
        //绑定纹理
        onBindTexture();
        //绘制纹理
        onDraw();
    }
//激活纹理单元       
 GLES20.glActiveTexture(GLES20.GL_TEXTURE0+textureType);
//绑定纹理
 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,getTextureId());
 GLES20.glUniform1i(mHTexture,textureType);
  protected void onDraw(){
        GLES20.glEnableVertexAttribArray(mHPosition);
        GLES20.glVertexAttribPointer(mHPosition,2, GLES20.GL_FLOAT, false, 0,mVerBuffer);
        GLES20.glEnableVertexAttribArray(mHCoord);
        GLES20.glVertexAttribPointer(mHCoord, 2, GLES20.GL_FLOAT, false, 0, mTexBuffer);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);
        GLES20.glDisableVertexAttribArray(mHPosition);
        GLES20.glDisableVertexAttribArray(mHCoord);
    }
glReadPixels(centX, centY, RADIS, RADIS, GL_RGBA,
        GL_UNSIGNED_BYTE, mScaleBuffer); 

获取的图像是上下翻转和左右镜像的 该方法中 起点是 屏幕左下角(纹理坐标系)

                Matrix matrix = new Matrix();
                Bitmap bitmap = Bitmap.createBitmap(RADIS, RADIS, Bitmap.Config.ARGB_8888);
                matrix.postRotate(180);
                matrix.postScale(-1, 1);
                bitmap.copyPixelsFromBuffer(data);

最好的方法是处理 data 

Guess you like

Origin blog.csdn.net/TyearLin/article/details/119971617