创建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):