安卓opengl基本使用

创建program

        //创建着色器对象
        //顶点着色器(GL_VERTEX_SHADER)/片段着色器(GL_FRAGMENT_SHADER)
        int shader = glCreateShader(type);
        if (shader == 0) return 0;//创建失败
        //加载着色器源
        glShaderSource(shader, shaderSource);
        //编译着色器
        glCompileShader(shader);
        //检查编译状态
        int[] compiled = new int[1];
        glGetShaderiv(shader, GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            Log.e(TAG, glGetShaderInfoLog(shader));
            glDeleteShader(shader);
            Log.e(TAG, "failed to compile shader");
            //编译失败
            return 0;
        }

        int program = glCreateProgram();
        if (program == 0){
            Log.e(TAG, "failed to create program");
        }
        //绑定着色器到程序
        glAttachShader(program, vertexShader);
        glAttachShader(program, fragmentShader);
        //连接程序
        glLinkProgram(program);
        //检查连接状态
        int[] linked = new int[1];
        glGetProgramiv(program,GL_LINK_STATUS, linked, 0);
        if (linked[0] == 0){
            glDeleteProgram(program);
            Log.e(TAG, "failed to link program");
            //link失败
            return 0;
        }

顶点shader source:

#version 300 es

layout (location = 0) in vec4 a_Position;
layout (location = 1) in vec2 a_texCoord;
uniform mat4 u_matrix;
uniform mat4 watermark_matrix;
out vec2 v_texCoord;
out vec2 watermark_texCoord;

void main()
{
    gl_Position = u_matrix * a_Position;
    watermark_texCoord = (watermark_matrix*vec4(a_texCoord.xy,1.0,1.0)).xy;
    v_texCoord = a_texCoord;
}

片段shader source:

#version 300 es
precision mediump float;

in vec2 v_texCoord;
in vec2 watermark_texCoord;
out vec4 outColor;
uniform sampler2D s_texture;
uniform sampler2D textureLUT;
uniform sampler2D bgtexture;
uniform sampler2D watermarktexture;
uniform int colorFlag;//滤镜类型
uniform int viewType;//绿布背景替换显示,水印显示,等

//rgb转hsl
vec3 rgb2hsl(vec3 color){
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g));
    vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

//hsl转rgb
vec3 hsl2rgb(vec3 color){
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www);
    return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y);
}

//灰度
void grey(inout vec4 color){
    float weightMean = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
    color.r = color.g = color.b = weightMean;
}

//黑白
void blackAndWhite(inout vec4 color){
    float threshold = 0.5;
    float mean = (color.r + color.g + color.b) / 3.0;
    color.r = color.g = color.b = mean >= threshold ? 1.0 : 0.0;
}

//反向
void reverse(inout vec4 color){
    color.r = 1.0 - color.r;
    color.g = 1.0 - color.g;
    color.b = 1.0 - color.b;
}

//亮度
void light(inout vec4 color){
    vec3 hslColor = vec3(rgb2hsl(color.rgb));
    hslColor.z += 0.15;
    color = vec4(hsl2rgb(hslColor), color.a);
}

void light2(inout vec4 color){
    color.r += 0.15;
    color.g += 0.15;
    color.b += 0.15;
}

//查找表滤镜
vec4 lookupTable(vec4 color){
    float blueColor = color.b * 63.0;

    vec2 quad1;
    quad1.y = floor(floor(blueColor) / 8.0);
    quad1.x = floor(blueColor) - (quad1.y * 8.0);
    vec2 quad2;
    quad2.y = floor(ceil(blueColor) / 8.0);
    quad2.x = ceil(blueColor) - (quad2.y * 8.0);

    vec2 texPos1;
    texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);
    texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);
    vec2 texPos2;
    texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);
    texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);
    vec4 newColor1 = texture(textureLUT, texPos1);
    vec4 newColor2 = texture(textureLUT, texPos2);
    vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
    return vec4(newColor.rgb, color.w);
}

//色调分离
void posterization(inout vec4 color){
    //计算灰度值
    float grayValue = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
    //转换到hsl颜色空间
    vec3 hslColor = vec3(rgb2hsl(color.rgb));
    //根据灰度值区分阴影和高光,分别处理
    if(grayValue < 0.3){
        //添加蓝色
        if(hslColor.x < 0.68 || hslColor.x > 0.66){
            hslColor.x = 0.67;
        }
        //增加饱和度
        hslColor.y += 0.3;
    }else if(grayValue > 0.7){
        //添加黄色
        if(hslColor.x < 0.18 || hslColor.x > 0.16){
            hslColor.x = 0.17;
        }
        //降低饱和度
        hslColor.y -= 0.3;
    }
    color = vec4(hsl2rgb(hslColor), color.a);
}
void filterBlue(inout vec4 tc){
    float r = tc.r * 255.0;
    float g = tc.g * 255.0;
    float b = tc.b * 255.0;

    if(g>140.0 && r<128.0 && b<128.0){
        tc.r =1.0;
        tc.g =1.0;
        tc.b =1.0;
         tc.a =0.0;
    }else{
     tc.a =1.0;
    }
}

vec4 replaceBlue(inout vec4 base , inout vec4 bg){
    vec4 tempColor;
    if(base.r == 1.0 && base.g == 1.0 && base.b == 1.0 && base.a == 0.0){
          //tempColor.r = base.a*base.r + bg.r * (1.0 - base.a);
          //tempColor.g = base.a*base.g + bg.g * (1.0 - base.a);
          //tempColor.b = base.a*base.b + bg.b * (1.0 - base.a);
          //tempColor.a = base.a;
       tempColor.r = bg.r;
       tempColor.g = bg.g;
       tempColor.b = bg.b;
       tempColor.a = bg.a;
    }else{
        tempColor.r = base.r;
        tempColor.g = base.g;
        tempColor.b = base.b;
        tempColor.a = base.a;
    }
    return tempColor;
}

vec4 addWaterMark(inout vec4 camera , inout vec4 watermark){
    float r = watermark.r + (1.0 - watermark.a) * camera.r;
    float g = watermark.g + (1.0 - watermark.a) * camera.g;
    float b = watermark.b + (1.0 - watermark.a) * camera.b;
    return vec4(r, g, b, 1.0);
}

void main(){
    vec4 tmpColor = texture(s_texture, v_texCoord);
    if (colorFlag == 1){ //灰度
        //filterBlue(tmpColor);
        if(viewType == 1){
                vec4 background = texture(bgtexture, v_texCoord);
                outColor = background;
                return;
        }else if(viewType == 2){
                 filterBlue(tmpColor);
                vec4 background = texture(bgtexture, v_texCoord);
                outColor = replaceBlue(tmpColor , background);
                return;
        }else if(viewType == 3){
                vec4 watermark = texture(watermarktexture, watermark_texCoord);
                outColor = addWaterMark( tmpColor , watermark);
                return;
        }else if(viewType == 4){
                outColor = tmpColor;
                return;
        }

        //vec4 background = texture(bgtexture, v_texCoord);
        //outColor = background;
        //outColor = replaceBlue(tmpColor , background);
        //vec4 watermark = texture(watermarktexture, watermark_texCoord);
        //outColor = addWaterMark( tmpColor , watermark);
        //outColor = watermark;
        return;
    } else if (colorFlag == 2){ //黑白
        blackAndWhite(tmpColor);
    } else if (colorFlag == 3){ //反向
        reverse(tmpColor);
    } else if (colorFlag == 4){ //亮度
        light(tmpColor);
    } else if(colorFlag == 5){ //亮度2
        light2(tmpColor);
    } else if(colorFlag == 6){//lut
        outColor = lookupTable(tmpColor);
        return;
    } else if(colorFlag == 7){//色调分离
        posterization(tmpColor);
    }

    outColor = tmpColor;
}

//将颜色值约束在[0.0-1.0] 之间
void checkColor(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);
}

关联属性值:

hVertex = glGetAttribLocation(program, VERTEX_ATTRIB_POSITION);
hMatrix = glGetUniformLocation(program, UNIFORM_MATRIX);
hTextureCoord = glGetAttribLocation(program, VERTEX_ATTRIB_TEXTURE_POSITION);
hTexture = glGetUniformLocation(program, UNIFORM_TEXTURE);

一些需要加载或设置的参数:

	    public static final float[] vertex ={
	            -1f,1f,0.0f,//左上
	            -1f,-1f,0.0f,//左下
	            1f,-1f,0.0f,//右下
	            1f,1f,0.0f//右上
	    };
	
	    public static final float[] textureCoord = {
	            0.0f,1.0f,
	            0.0f,0.0f,
	            1.0f,0.0f,
	            1.0f,1.0f
	    };
        bgTextureID = GLUtil.loadTextureFromFile("/sdcard/container.jpg");
        int[] nums =      GLUtil.loadTextureFromRes(R.drawable.icon_push_office);
        watermarkTextureID = nums[0];
        watermarkWidth = nums[1];//720
        watermarkHeight = nums[2];//1366
        xRatio = 720/(float)watermarkWidth;
        yRatio = 1366/(float)watermarkHeight;
        mWaterMarkMatrix = new float[]{
                xRatio,0,0,0,
                0,yRatio,0,0,
                0,0,1,0,
                0,0,0,1
        };
        //上面的
		public static int loadTextureFromFile(String path){
        //创建纹理对象
        int[] textureId = new int[1];
        //生成纹理:纹理数量、保存纹理的数组,数组偏移量
        glGenTextures(1, textureId,0);
        if(textureId[0] == 0){
            Log.e(TAG, "创建纹理对象失败");
        }
        //原尺寸加载位图资源(禁止缩放)
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        if (bitmap == null){
            //删除纹理对象
            glDeleteTextures(1, textureId, 0);
            Log.e(TAG, "加载位图失败");
        }
        //绑定纹理到opengl
        glBindTexture(GL_TEXTURE_2D, textureId[0]);
        //设置放大、缩小时的纹理过滤方式,必须设定,否则纹理全黑
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //将位图加载到opengl中,并复制到当前绑定的纹理对象上
        texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
        //释放bitmap资源(上面已经把bitmap的数据复制到纹理上了)
        bitmap.recycle();
        //解绑当前纹理,防止其他地方以外改变该纹理
        glBindTexture(GL_TEXTURE_2D, 0);
        //返回纹理对象
        return textureId[0];
    }

绘制:

    
	glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer[0]);
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, frameTexture[0], 0);

	glViewport(0,0,width,height);
    glUseProgram(program);
    glUniformMatrix4fv(hMatrix, 1, false, getMatrix(),0);
    glUniform1i(hColorFlag, COLOR_FLAG);
    glUniformMatrix4fv(watermatrixLoc, 1, false,getWaterMarkMatrix(),0);
    
    //bindTexture
    if (COLOR_FLAG == COLOR_FLAG_USE_LUT){
        glActiveTexture(GL_TEXTURE0 + 1);
        glBindTexture(GL_TEXTURE_2D, LUTTextureId);
        glUniform1i(hTextureLUT, 1);
    }
        if (COLOR_FLAG == 1) {
            /*glActiveTexture(GL_TEXTURE0 + 1);
            glBindTexture(GL_TEXTURE_2D, bgTextureID);
            glUniform1i(bgTexture, 1);*/
        glActiveTexture(GL_TEXTURE0+1);
        glBindTexture(GL_TEXTURE_2D , bgTextureID);
        glUniform1i(bgTexture , 1);

        glActiveTexture(GL_TEXTURE0+2);
        glBindTexture(GL_TEXTURE_2D , watermarkTextureID);
        glUniform1i(watermarkTextureLoc , 2);
    }
    
    glEnableVertexAttribArray(hVertex);
    glEnableVertexAttribArray(hTextureCoord);
    glVertexAttribPointer(hVertex,
            VERTEX_ATTRIB_POSITION_SIZE,
            GL_FLOAT,
            false,
            0,
            vertexBuffer);
    glVertexAttribPointer(hTextureCoord,
            VERTEX_ATTRIB_TEXTURE_POSITION_SIZE,
            GL_FLOAT,
            false,
            0,
            textureCoordBuffer);
            
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glDrawArrays(GL_TRIANGLE_FAN,0,vertex.length / 3);
    
    glDisableVertexAttribArray(hVertex);
    glDisableVertexAttribArray(hTextureCoord);

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

对Texture操作

    glGenTextures(exportTexture.length, exportTexture, 0);
    glBindTexture(GL_TEXTURE_2D, exportTexture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 		null);
    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);
    glBindTexture(GL_TEXTURE_2D, 0);

	//将显存中的数据回传到内存中
	ByteBuffer exportBuffer = ByteBuffer.allocate(width * height * 4);//8888存储格式
    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, exportBuffer);

附上网上的一些资料 opengl内嵌函数和变量

1、uint CreateShader(enum type) : 创建空的shader object; type:
VERTEX_SHADER,

2、void ShaderSource(uint shader, sizeicount, const **string, const int
*length):加载shader源码进shader object;可能多个字符串

3、void CompileShader(uint shader):编译shader object;

shader object有状态 表示编译结果

4、void DeleteShader( uint shader ):删除 shader object;

5、void ShaderBinary( sizei count, const uint *shaders, enum
binaryformat, const void *binary, sizei length ): 加载预编译过的shader 二进制串;

6、uint CreateProgram( void ):创建空的program object, programe
object组织多个shader object,成为executable;

7、void AttachShader( uint program, uint shader ):关联shader
object和program object;

8、void DetachShader( uint program, uint shader ):解除关联;

9、void LinkProgram( uint program ):program object准备执行,其关联的shader
object必须编译正确且符合限制条件;

10、void UseProgram( uint program ):执行program object;

11、void ProgramParameteri( uint program, enum pname, int value ):
设置program object的参数;

12、void DeleteProgram( uint program ):删除program object;

13、shader 变量的qualifier:

默认:无修饰符,普通变量读写, 与外界无连接;

const:常量 const vec3 zAxis = vec3(0.0, 0.0, 1.0);

attribute: 申明传给vertex shader的变量;只读;不能为array或struct;attribute vec4 position;

uniform: 表明整个图元处理中值相同;只读; uniform vec4 lightPos;

varying: 被差值;读写; varying vec3 normal;

in, out, inout;

14、shader变量的精度:

highp, mediump, lowp

15、shader内置变量:

gl_Position: 用于vertex shader, 写顶点位置;被图元收集、裁剪等固定操作功能所使用;

             其内部声明是:highp vec4 gl_Position;

gl_PointSize: 用于vertex shader, 写光栅化后的点大小,像素个数;

             其内部声明是:mediump float gl_Position;

gl_FragColor: 用于Fragment shader,写fragment color;被后续的固定管线使用;

              mediump vec4 gl_FragColor;

gl_FragData: 用于Fragment shader,是个数组,写gl_FragData[n] 为data n;被后续的固定管线使用;

              mediump vec4 gl_FragData[gl_MaxDrawBuffers];

gl_FragColor和gl_FragData是互斥的,不会同时写入;

gl_FragCoord: 用于Fragment shader,只读, Fragment相对于窗口的坐标位置 x,y,z,1/w; 这个是固定管线图元差值后产生的;z 是深度值; mediump vec4 gl_FragCoord;

gl_FrontFacing: 用于判断 fragment是否属于 front-facing primitive;只读;

                bool gl_FrontFacing;   

gl_PointCoord: 仅用于 point primitive; mediump vec2 gl_PointCoord;

16、shader内置常量:

const mediump int gl_MaxVertexAttribs = 8;

const mediump int gl_MaxVertexUniformVectors = 128;

const mediump int gl_MaxVaryingVectors = 8;

const mediump int gl_MaxVertexTextureImageUnits = 0;

const mediump int gl_MaxCombinedTextureImageUnits = 8;

const mediump int gl_MaxTextureImageUnits = 8;

const mediump int gl_MaxFragmentUnitformVectors = 16;

const mediump int gl_MaxDrawBuffers = 1;

17、shader内置函数:

一般默认都用弧度;

radians(degree) : 角度变弧度;

degrees(radian) : 弧度变角度;

sin(angle), cos(angle), tan(angle)

asin(x): arc sine, 返回弧度 [-PI/2, PI/2];

acos(x): arc cosine,返回弧度 [0, PI];

atan(y, x): arc tangent, 返回弧度 [-PI, PI];

atan(y/x): arc tangent, 返回弧度 [-PI/2, PI/2];



pow(x, y): x的y次方;

exp(x): 指数, log(x):

exp2(x): 2的x次方, log2(x):

sqrt(x): x的根号; inversesqrt(x): x根号的倒数



abs(x): 绝对值

sign(x): 符号, 1, 0 或 -1

floor(x): 底部取整

ceil(x): 顶部取整

fract(x): 取小数部分

mod(x, y): 取模, x - y*floor(x/y)

min(x, y): 取最小值

max(x, y): 取最大值

clamp(x, min, max):  min(max(x, min), max);

mix(x, y, a): x, y的线性混叠, x(1-a) + y*a;

step(edge, x): 如 edge>x 0.0,否则1.0

smoothstep(edge0, edge1, x): threshod  smooth transition时使用。 edge0<=edge0时为0.0, x>=edge1时为1.0



length(x): 向量长度

distance(p0, p1): 两点距离, length(p0-p1);

dot(x, y): 点积,各分量分别相乘 后 相加

cross(x, y): 差积,x[1]*y[2]-y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1]

normalize(x): 归一化, length(x)=1;

faceforward(N, I, Nref): 如 dot(Nref, I)< 0则N, 否则 -N

reflect(I, N): I的反射方向, I -2*dot(N, I)*N, N必须先归一化

refract(I, N, eta): 折射,k=1.0-eta*eta*(1.0 - dot(N, I) * dot(N, I)); 如k<0.0 则0.0,否则 eta*I - (eta*dot(N, I)+sqrt(k))*N



matrixCompMult(matX, matY): 矩阵相乘, 每个分量 自行相乘, 即 r[i][j] = x[i][j]*y[i][j];

                           矩阵线性相乘,直接用 *



lessThan(vecX, vecY): 向量 每个分量比较 x < y

lessThanEqual(vecX, vecY): 向量 每个分量比较 x<=y

greaterThan(vecX, vecY): 向量 每个分量比较 x>y

greaterThanEqual(vecX, vecY): 向量 每个分量比较 x>=y

equal(vecX, vecY): 向量 每个分量比较 x==y

notEqual(vecX, vexY): 向量 每个分量比较 x!=y

any(bvecX): 只要有一个分量是true, 则true

all(bvecX): 所有分量是true, 则true

not(bvecX): 所有分量取反



texture2D(sampler2D, coord): texture lookup

texture2D(sampler2D, coord, bias): LOD bias, mip-mapped texture

texture2DProj(sampler2D, coord):

texture2DProj(sampler2D, coord, bias):

texture2DLod(sampler2D, coord, lod):

texture2DProjLod(sampler2D, coord, lod):

textureCube(samplerCube, coord):

textureCube(samplerCube, coord, bias):

textureCubeLod(samplerCube, coord, lod):
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值