作者:じ☆ve不哭
发布时间:2023-08-21T09:41:49
应用程序编程接口
对图形硬件设备特性进行访问的软件库
与硬件无关,可以通过软件的方式实现OpenGL接口
不包含任何执行窗口任务,或者处理用户输入的函数
不提供三维物体,几何图元来创建三维空间物体
API是过程性
可以软件实现,也可以硬件实现
视频 图形 图片处理
2D/3D游戏引擎开发
科学可视化,医学软件的开发
CAD(计算机辅助技术)
虚拟实境(AR VR)
AI人工智能
OpenGL ES是一个在移动平台上能够支持 OpenGL 最基本功能的精简规范。
顶点着色器------- 将虚拟空间三维坐标 映射到 屏幕显示二维坐标 +Z-buffer深度信息
模型如下:
片元着色器 --------计算每个像素的颜色和其它属性 (如光照值,贴图,阴影)
模型如下:
标量----基本数据类型
向量----常用于表示颜色,纹理,坐标
矩阵----常用于位移,旋转,缩放操作
采样器----纹理采样 (用在片元着色器,在宿主(java)中初始化)
结构体----简化运算
struct info {
vec3 a;
vec2 b;
vec3 c
}
数组----float f[]
空类型 ----void
precision | 描述 | 位数(位) |
---|---|---|
lowp | 低精度 | 8 |
mediump | 中精度 | 10 |
highp | 高精度 | 16 |
绘制方式 | 说明 |
---|---|
GL_POINTS | 点类下唯一的绘制方式,用来绘制点。 |
GL_LINES | 将着色器传入的顶点按顺序两个一组来绘制成线段 |
GL_LINES_STRIP | 按照顶点顺序连接顶点。(不封口) |
GL_LINES_LOOP | 按照顶点顺序连接顶点,并将第一个顶点和最后一个顶点相连。(封口) |
GL_TRIANGLES | 按照顶点顺序每3个点组成三角形进行绘制 |
GL_TRIANGLE_STRIP | 顶点按照顺序依次组织成三角形进行绘制, 最后实际形成的是一个三角形带。若有 |
GL_TRIANGLE_FAN | 将第一个点作为中心点其他点作为边缘点,绘制一系列组成扇形的相邻三角形 |
//1=============================================================
重复拉伸
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D
,GLES20.GL_TEXTURE_WRAP_S
,GLES20.GL_REPEAT);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D
,GLES20.GL_TEXTURE_WRAP_T
,GLES20.GL_REPEAT);
//2=================================================================
截取拉伸
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);
最近点采样 | 线性采样 | |
---|---|---|
基本原理 | 对应像素点 | 加权平均 |
优点 | 简单 采样快 | 线性平滑 |
缺点 | 将小图映射到大图上,会产生锯齿 | 容易造成线条模糊 |
【1】最近点采样
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_NEAREST);
【2】线性采样
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
当纹理图中的一个像素对应到待映射图元上的多个片元时,采用MAG采样;反之则采用MIN采样。 通俗版:纹理比图元小,采用MAG采样纹理设置。纹理比图元大,用MIN采样纹理设置 配合:MIN与最近点,MAG与线性采样
环境光 = 材质反射系数*环境光强度
散射光 = 材质反射系数 * 散射光强度*max(cos(入射角),0)
vec4 pointLight(vec3 normal,vec3 lightLocation, vec4 lightDiffuse){
vec3 vp=normalize(lightLocation‐(vMatrix*vec4(vPosition,1)).xyz);
vec3 newTarget=normalize((vMatrix*vec4(normal+vPosition,1)).xyz
‐ (vMatrix*vec4(vPosition,1)).xyz);
return lightDiffuse* max(0.0,dot(newTarget,vp));
}
镜面光 = 材质反射系数 * 镜面光强度 * max(cos(入射角)^粗糙度 ,0)
void pointLight( //定位光光照计算的方法
in vec3 normal, //法向量
inout vec4 specular, //镜面反射光分量
in vec3 lightLocation, //光源位置
in vec4 lightSpecular //镜面光强度
){
vec3 normalTarget=aPosition+normal;
vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz‐(uMMatrix*vec4(aPosition,1)).xyz;
newNormal=normalize(newNormal);
vec3 eye= normalize(uCamera‐(uMMatrix*vec4(aPosition,1)).xyz);
vec3 vp= normalize(lightLocation‐(uMMatrix*vec4(aPosition,1)).xyz);
vp=normalize(vp);
vec3 halfVector=normalize(vp+eye);
float shininess=50.0;
float nDotViewHalfVector=dot(newNormal,halfVector);
float powerFactor=max(0.0,pow(nDotViewHalfVector,shininess));
specular=lightSpecular*powerFactor;
}
定位光
void directionalLight(
in vec3 normal,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular,
in vec3 lightDirection,
in vec4 lightAmbient,
in vec4 lightDiffuse,
in vec4 lightSpecular
){
ambient=lightAmbient; //环境光
//计算变之后的法向量
vec3 normalTarget=aPosition+normal;
vec3 newNormal=(uMMatrix*vec4(normalTarget,1)).xyz‐(uMMatrix*vec4(aPosition,1)).xyz;
newNormal=normalize(newNormal);
//计算表面点到照相机的向量
vec3 eye= normalize(uCamera‐(uMMatrix*vec4(aPosition,1)).xyz);
//规格化定向光方向向量
vec3 vp= normalize(lightDirection);
vec3 halfVector=normalize(vp+eye); //求视线与光线的半向量
float shininess=50.0; //粗糙度 ,越小越光滑
///散射光=材质反射系数 * 散射光强度*max(cos(入射角),0)
float nDotViewPosition=max(0.0,dot(newNormal,vp)); //求法向量vp的点积与0的最大值
diffuse=lightDiffuse*nDotViewPosition;
//镜面光=材质反射系数 * 镜面光强度 * max(cos(入射角)粗糙度 ,0)
float nDotViewHalfVector=dot(newNormal,halfVector); //点积(法线与半向量的点积)
float powerFactor=max(0.0,pow(nDotViewHalfVector,shininess));//镜面光反射强度的因子
specular=lightSpecular*powerFactor;
}
算法 | 原理 |
---|---|
灰度 | 1.浮点算法:Gray= R * 0.3+G * 0.59 +B * 0.114 2.整数算法:Gray=( R * 30+G * 59 +B * 11) 3.仅取绿色:Gray=G 4.平均值:Gray=( R+G +B )/3 5.位移算法:Gray=( R * 76+G * 59 +B * 28)>>8 |
冷暖 色调 | 冷色调:增加单一的蓝色分量 暖色调:增加单一的红色和绿色色分量 |
模糊 处理 | 普通模糊:平均 高斯模糊:加权平均 |
放大 | 纹理坐标范围变小 ( s/2.0,t/2.0) |
颠倒 | 1.0-T的坐标 |
扭曲 | 不同半径位置旋转角度不同 (-(r/R)*(r/R)+1.0) |
浮雕 | 当前点的RGB值减去相邻的RGB值然后加上128作为新的RGB值! |
马赛克 | 把图片的一个区域用同一个点的颜色来表示,(大规模降低分辨率,隐藏图像细节) |
对比度增强 | x(1-a)+ya(线性插值) |
膨胀 腐蚀 | 亮的更亮,反之 |
# | 说明 |
---|---|
v --vertex | 顶点坐标 |
vt --vertex texture | 纹理坐标 |
vn --vertex normal | 顶点法向量 |
g --group | 组 |
f --face | 面 1/2/3 分布代表 顶点索引 纹理索引 顶点法向量索引 |
# | 说明 |
---|---|
Ka /Kd/ Ks | 光照强度 a--环境光 d--散射光 s--镜面光 |
newmtl _5___Default | 材质名 |
illum | 材质光照模型 |
Ns | 材质反射系数 |
bump | 为材质指定凹凸的纹理文件 |
map_KA/map_KS/map_Kd | 为对应光匹配的指定纹理文件 a--环境光 d--散射光 s--镜面光 |
map_d | 为消隐指数指定标量纹理文件 |
refl | 指定一个球体区域,将指定的纹理反射到映射物体上 |
输入片元,当前存储在帧缓存中的像素颜色值和
源颜色(Rs,Gs,Bs,As)
目标颜色(Rd,Gd,Bd,Ad)
设源因子 为(Sr,Sg,Sb,Sa)
设目标因子 为(Dr,Dg,Db,Da)
混合表达式:
混合效果=(Rs * Sr + Rd * Dr , Gs * Sg+Gd * Db , Bs * Sb + Bd * Db,As * Sa + Ad * Da)
//开启混合
gl.glEnable(GL10.GL_BLEND);
//定义像素算法(源混合因子,目标混合因子)
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_DST_ALPHA);
数学模型
线性算法:f=max(min((end‐dist)/(end‐start),1.0),1.0)
f : 雾化因子(1不浓,0浓)
dist: 当前要绘制的片元到照相机的距离
start:特定距离,当前片元距离照相机距离小于start的时候 ,f=1
end: 特定距离,当前片元距离照相机距离大于end的时候 ,f=0
非线性算法:f=1.0‐smoothstep( start, end, dist )
smoothstep函数
如果:dist<=start 返回0.0
如果:dist>=end 返回1.0
如果:start < dist< end 执行0‐1之间的平滑埃尔米特插值
如果:start 》= end 没效果(未定应)
代码
float get(){
//计算顶点到照相机的距离
float fogDistance=length( uCamera‐(uMMatrix*vec4(aPosition,1.0)).xyz);
const float end=490.0;//雾的结束位置
const float start=350.0;//雾的开始位置
//计算雾因子
float tmp=1.0‐smoothstep(start,end,fogDistance);
return tmp;
}
(1)图片占用内存公式 内存大小=宽高每一个像素的位数 (2)核心代码
// 读取ZipInputStream 并且创建纹理( ETC1Util.ETC1Texture)
ETC1Util.ETC1Texture t = getNextTexture();
ETC1Util.ETC1Texture tAlpha = getNextTexture();
//加载ETC1纹理
ETC1Util.loadTexture(GLES20.GL_TEXTURE_2D
, 0//纹理层次
, 0//边框大小。通常为0.
, GLES20.GL_RGB//格式使用ETC1纹理压缩,如果不支持。必须gl_rgb。
//要使用的类型如果ETC1纹理压缩不支持。
// 可以gl_unsigned_short_5_6_5,
// 这意味着每个像素的16位或gl_unsigned_byte,这意味着每像素24位。
, GLES20.GL_UNSIGNED_SHORT_5_6_5
, t);//ETC1Util.ETC1Texture
ETC1Util.loadTexture(GLES20.GL_TEXTURE_2D, 0, 0, GLES20.GL_RGB, GLES20
.GL_UNSIGNED_SHORT_5_6_5, tAlpha);
(1)Frame Buffer和Render Buffer (2)核心代码
//创建缓冲帧
GLES20.glGenFramebuffers(1, fFrame, 0);
GLES20.glGenRenderbuffers(1, fRender, 0);
//绑定RenderBuffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, fRender[0]);
//为深度的Render Buffer,并传入大小
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER
, GLES20.GL_DEPTH_COMPONENT16,
mBitmap.getWidth(), mBitmap.getHeight());//渲染缓存图像的像素维度
//创建的渲染缓冲区挂载到帧缓冲区上
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT,
GLES20.GL_RENDERBUFFER, fRender[0]);
//解绑Render Buffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0);
//绑定FrameBuffer
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fFrame[0]);
GLES20.glFramebufferTexture2D(
GLES20.GL_FRAMEBUFFER
, GLES20.GL_COLOR_ATTACHMENT0
, GLES20.GL_TEXTURE_2D
// 附加的纹理对象ID
, fTexture[1]
, 0);
//为FrameBuffer挂载fRender[0]来存储深度
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,//帧缓冲类型的目标
GLES20.GL_DEPTH_ATTACHMENT,// 附着点
GLES20.GL_RENDERBUFFER,// 必须为GL_RENDERBUFFER
fRender[0]); // 渲染缓冲区对象
//设置视口
GLES20.glViewport(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
//绘制 帧缓存里读取一个像素块
draw();
GLES20.glReadPixels(0, 0//定义图像区域左下角点的坐标
//图像的高度和宽度
, mBitmap.getWidth(), mBitmap.getHeight()
//所读象素数据元素的格式
, GLES20.GL_RGBA,
//数据类型
GLES20.GL_UNSIGNED_BYTE,//每个元素的数据类型
mBuffer);//图片
//删除纹理
GLES20.glDeleteTextures(2, fTexture, 0);
//删除Render Buffer
GLES20.glDeleteRenderbuffers(1, fRender, 0);
//删除Frame Buffer
GLES20.glDeleteFramebuffers(1, fFrame, 0);