OpenGL之图片色彩处理(三)

一、OpenGL图片绘制的一般步骤:

    1、编写顶点着色器和片元着色器;

    2、编写需要绘制的图形类,包括:加载着色器脚本内容,加载图片数据,图片绘制;

    3、配置绘制环境,绘制图片。

二、具体如下:

   1、 编写顶点着色器程序(glsl语言):

attribute vec4 vPosition;
attribute vec2 vCoordinate;//纹理数据
uniform mat4 vMatrix;
//给片元传递数据(纹理,变换前的顶点,变换后的顶点)
varying vec2 aCoordinate;
varying vec4 aPos;
varying vec4 gPosition;

void main(){
    gl_Position=vMatrix*vPosition;
    aPos=vPosition;
    aCoordinate=vCoordinate;
    gPosition=vMatrix*vPosition;
}

  2、 编写片元着色器程序(glsl语言):

precision mediump float;

uniform sampler2D vTexture;
uniform int vChangeType;
uniform vec3 vChangeColor;
uniform int vIsHalf;
uniform float uXY;

//给片元传递的数据(纹理数据,变换前顶点,变换后顶点)
varying vec2 aCoordinate;
varying vec4 aPos;
varying vec4 gPosition;

//修改颜色(防止颜色值超过一)
void modifyColor(vec4 color){
     color.r=max(min(color.r,1.0),0.0);
     color.g=max(min(color.g,1.0),0.0);
     color.b=max(min(color.b,1.0),0.0);
     color.a=max(min(color.a,1.0),0.0);
 }
void main() {
   vec4 nColor=texture2D(vTexture,aCoordinate);
   if(aPos.x>0.0 || vIsHalf == 0){
        if(vChangeType==1){
            //浮点算法     Gray=R * 0.3+G * 0.59+B * 0.114
            float gray=(nColor.r*0.3+nColor.g*0.59+nColor.b*0.114);
            gl_FragColor=vec4(gray,gray,gray,nColor.a);
        }else if(vChangeType==2){
            vec4 colorWarm=nColor+vec4(0.1,0.1,0.0,0.0);
            modifyColor(colorWarm);
            gl_FragColor=colorWarm;
        }else if(vChangeType==3){
            vec4 colorCold=nColor+vec4(0.0,0.0,0.1,0.0);
            modifyColor(colorCold);
            gl_FragColor=colorCold;
        }else if(vChangeType==4){
            vec2 texSize = vec2(1500.0f,1500.0f);
            vec2 upTex=vec2(aCoordinate.x-1.0/texSize.x,aCoordinate.y-1.0/texSize.y);
            vec4 newTex=texture2D(vTexture,upTex);
            vec4 delTex=nColor-newTex;
            gl_FragColor=delTex;
        }else if(vChangeType==5){
            gl_FragColor=texture2D(vTexture,vec2(1.0-aCoordinate.x,1.0-aCoordinate.y));
        }else{
            gl_FragColor=nColor;
        }
   }else{
        gl_FragColor=nColor;
   }
}

 3、编写绘制图像类(java)

public class Image extends ShaderUtils {

    private FloatBuffer bPos;
    private FloatBuffer bCoord;

    //图片四个角的坐标
    public final float[] sPos = {
            -1.0f, 1.0f,
            -1.0f, -1.0f,
            1.0f, 1.0f,
            1.0f, -1.0f

    };
    //图片四个角的纹理坐标
    public final float[] sCoord = {
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,
    };

    private int mProgram;
    private int glHPosition;
    private int glHTexture;
    private int glHCoordinate;
    public int glHMatrix;
    private int hIsHalf;
    public int glHUxy;
    private int hChangeType;
    private int hChangeColor;

    public Image(GLSurfaceView mView) {
        initData();
        initShader(mView);
    }

    private void initShader(GLSurfaceView mv) {
        /*//加载顶点着色器的脚本内容
        String mVertexShader = loadFromAssetsFile("filter/vertex.glsl", mv.getResources());
        //加载片元着色器的脚本内容
        String mFragmentShader = loadFromAssetsFile("filter/fragment.glsl", mv.getResources());
        mProgram=createProgram(mVertexShader,mFragmentShader);*/
        mProgram=createProgram(mv.getResources(),"filter/vertex.glsl","filter/fragment.glsl");
        glHPosition= GLES20.glGetAttribLocation(mProgram,"vPosition");
        glHCoordinate=GLES20.glGetAttribLocation(mProgram,"vCoordinate");
        glHTexture=GLES20.glGetUniformLocation(mProgram,"vTexture");
        glHMatrix=GLES20.glGetUniformLocation(mProgram,"vMatrix");
        hIsHalf=GLES20.glGetUniformLocation(mProgram,"vIsHalf");
        glHUxy=GLES20.glGetUniformLocation(mProgram,"uXY");
        hChangeType=GLES20.glGetUniformLocation(mProgram,"vChangeType");
        hChangeColor=GLES20.glGetUniformLocation(mProgram,"vChangeColor");
    }

    private void initData() {
        bPos = getFloatBuffer(sPos);
        bCoord = getFloatBuffer(sCoord);
    }

    private int count=1;
    public float[][] images = new float[][]{
            {0.0f, 0.0f, 0.0f}//原图
            , {0.299f, 0.587f, 0.114f}//灰度
            , {0.1f, 0.1f, 0.0f}//暖色调
            , {0.0f, 0.0f, 0.1f}//冷色调
            , {0.2125f, 0.7154f, 0.0721f}//浮雕
            , {0.0f, 0.0f, 0.0f}
            , {0.0f, 0.0f, 0.0f}
            , {0.0f, 0.0f, 0.0f}
    };
    public void drawSelf(int textureId) {
        GLES20.glUseProgram(mProgram);
        GLES20.glUniform1i(hChangeType,count);
        GLES20.glUniform3fv(hChangeColor,1,images[count],0);
        GLES20.glUniform1i(hIsHalf,0);
        GLES20.glEnableVertexAttribArray(glHPosition);
        GLES20.glEnableVertexAttribArray(glHCoordinate);
        GLES20.glUniform1i(glHTexture,0);
        GLES20.glVertexAttribPointer(glHPosition,2,GLES20.GL_FLOAT,false,0,bPos);
        GLES20.glVertexAttribPointer(glHCoordinate,2,GLES20.GL_FLOAT,false,0,bCoord);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);
    }
}

这个里面的ShaderUtils是编写好的工具类,作用是加载着色器程序。

4、编写渲染类SGLView(java)

public class SGLView extends GLSurfaceView implements GLSurfaceView.Renderer{

    private Image image;
    private int textureId;
    private Bitmap mBitmap;
    private float uXY;

    private float[] mViewMatrix = new float[16];
    private float[] mProjectMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];

    public SGLView(Context context) {
        super(context);
        init();
    }

    private void init() {
        setEGLContextClientVersion(2);
        setRenderer(this);
        setRenderMode(RENDERMODE_CONTINUOUSLY);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
        GLES20.glEnable(GLES20.GL_TEXTURE_2D);
        image = new Image(this);
        textureId = createTexture();
    }

    //创建纹理
    private int createTexture() {
        mBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.girl);
        int[] texture = new int[1];
        if(mBitmap != null && !mBitmap.isRecycled()){
            //生成纹理
            GLES20.glGenTextures(1,texture,0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,texture[0]);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
            GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_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,mBitmap,0);

            return texture[0];
        }
        return 0;
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0,0,width,height);

        int w = mBitmap.getWidth();
        int h = mBitmap.getHeight();
        float swh = (float)w/h;
        float sWH = (float)width/height;
        uXY = sWH;
        if(sWH > swh){
            Matrix.orthoM(mProjectMatrix,0,-1,1,-swh/sWH,swh/sWH,3,5);
        }else{
            Matrix.orthoM(mProjectMatrix,0,-1,1,-sWH/swh,sWH/swh,3,5);
        }
        //设置相机的位置
        Matrix.setLookAtM(mViewMatrix,0,0,0,5.0f,0,0,0,0,1.0f,0);
        //计算变换矩阵
        Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);

        GLES20.glUniform1f(image.glHUxy, uXY);
        GLES20.glUniformMatrix4fv(image.glHMatrix, 1, false, mMVPMatrix, 0);
        image.drawSelf(textureId);
    }
}

  5、在Activity中加载SGLView

public class Main2Activity extends AppCompatActivity {

  
    private SGLView sView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sView = new SGLView(this);
        setContentView(sView);
    }

    @Override
    protected void onResume() {
        super.onResume();
        sView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        sView.onPause();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33275597/article/details/80869913