基础概念OpenGLES(一)

opengl es是什么?

  • opengl 是一个跨平台(不同的GPU类型,如电脑端NVIDIA,Intel,AMD的显卡,手机端PowerVR(苹果系列), Adreno(高通,安卓系列)等等)、跨编程语言(各个编程语言java,C,OC,js等等都有opengl的接口)的图形图像处理接口,opengl本身只是一组api接口规范,具体的实现一般是由具体的显卡(GPU)设备生产商编码实现的,比如苹果手机是由apple实现的,Linux系统则是由各个显卡生产商通过驱动程序导入的。

  • opengl es是opengl的一个子集,是专门用来针对手机,平板电脑等嵌入式设备的图形图像处理接口,接口设计中不涉及上下文环境和窗口的管理,这由各个平台自行实现。比如ios就是EAGL;安卓就是EGL;

tips:
libSDL是一个跨平台的图形处理库,其中有包含对opengl es的标准接口的封装及各个平台上下文,窗口管理的封装。
备注:opengl es 2.0 官方接口文档 https://www.khronos.org/registry/OpenGL-Refpages/es2.0/

基础概念

  • 应用端:
    即我们自己的程序端,相对于opengl es,我们属于应用端
  • 图元:
    要渲染的几何物体,或者形状。比如要渲染一个正方形的图片,就是一个图元,要渲染两条直线,这两条直线也是图元
  • 纹理:
    通俗点,可以理解为一张图片,在opengl es中纹理就是图片的另外一种叫法
  • 纹素:
    纹理的基础单元,也就是像素
  • 顶点数组
    顶点指的是组成图元的各个顶点的坐标数据(在3D笛卡尔坐标中即x,y,z坐标),这些坐标数据可以一起存到一个内存数组中,这个数组就叫做顶点数组
  • 顶点缓冲区
    在显存中专门分配一块显存来存储这个顶点数组,这个显存就称为顶点缓冲区
  • 顶点着色器
    顶点着⾊器(简称为VS)是opengl es中⽤于计算图形顶点属性(包括顶点坐标归一化、顶点光照运算等等)的程序。顶点着色器是逐顶点运算的程序,也就是说每个顶点数据都会执行⼀次顶点着⾊器,当然这是并行的
  • 片元着色器
    片元着色器(简称为PS)用来决定要渲染图形的每个像素的颜色的程序,它也是并行计算的

opengl es渲染管线

渲染管线也就是opengl es的工作流程,这里是opengl es2.0以后的版本的渲染管线

  • 1、opengl es接收API的输入
    通过 API 设定顶点的信息(一般包括顶点坐标,纹理坐标,颜色,变换矩阵等等),一般由顶点着色器接收这些信息作为输入
  • 2、顶点着色器处理顶点坐标
    前一阶段的输入将在 VS 中进行运算,以得到最终的顶点坐标。
  • 3、图元装配
    将顶点着色器计算出的最终顶点坐标进行图元装配,构建出最终想要渲染的图形。所有要渲染的图形都可以由三个基本的图元(点、线、三角形)组成,比如正方形或者长方形,就可以由两个三角形组成,圆形可以由无数个三角形组成,只是三角形的数量越多,圆形看上去越圆润
  • 4、光栅化
    通过计算,将要渲染的图形上所有的像素点找到,并根据插值或者其他方式计算出其颜色等信息的过程
  • 5、片元着色器计算像素颜色
    光栅化得到了要渲染图形的所有像素的信息,这些信息作为片元着色器的输入,那么在片元着色器中将计算像素颜色
  • 6、像素处理
    片元着色器计算的像素颜色还不是最终要渲染的颜色,这一步骤还包括Alpha Test、Depth/Stencil Test、Blend、Dither等几个步骤,经过这几个步骤后得到的就是最终的渲染颜色

备注:以上所有的操作都是并行处理

opengl es的相关坐标系

  • opengl es的坐标系原点位于要渲染区域的中心点,向右和向上分别为x轴和y轴的正向轴,取值范围为(-1,1)
    如下为正确渲染一张图片为例传递顶点坐标
    static float verData1[8] = {
    -1.0f, -1.0f, // 左下角
    1.0f,-1.0f, // 右下角
    -1.0f,1.0f, // 左上角
    1.0f,1.0f, // 右上角
    };
    一般按照如上的顺序传递坐标,取值也可以是其它值,比如
    static float verData1[8] = {
    -0.5f, -0.5f, // 左下角
    0.5f,-0.5f, // 右下角
    -0.5f,0.5f, // 左上角
    0.5f,0.5f, // 右上角
    };
    表示取中间的1/2区域;实际上就是压缩效果
    static float verData1[8] = {
    -2.0f, -2.0f, // 左下角
    2.0f,-2.0f, // 右下角
    -2.0f,2.0f, // 左上角
    2.0f,2.0f, // 右上角
    };
    表示将原来的坐标系放大了一倍后在基于原始的进行截取

  • 纹理坐标系
    在opengl 中,通常将纹理中的像素根据纹理坐标系来进行编址,纹理坐标系的横轴成为S轴,纵轴成为T轴,垂直于ST轴的成为R轴,在2D纹理中,没有
    R轴,横轴和纵轴又称为UV轴,所以2D纹理坐标系又称为UV坐标系,UV轴的取值范围都是(0,1)。与OpenGL 坐标系不同的是,纹理坐标系的原点位于左
    上角
    如下为正确渲染一张图片为例传递纹理坐标:
    static float uvData[8] = {
    0.0f, 1.0f,// 左下角
    1.0f, 1.0f, // 右下角
    0.0f, 0.0f,// 左上角
    1.0f, 0.0f, // 右上角
    };
    纹理坐标系一般不要去改变它的值,传这个就好,(当然也可该,前提是知道内部的转换原理),如果要实现压缩和裁剪效果,改变几何坐标系方便一些。

  • 设定opengl es渲染区域
    glViewPort(x,y,w,h) 函数窗口创建的渲染区域
    它以左下角作为原点的坐标系
    此函数的意思就是,基于当前视图左下角作为原点的坐标系,选取一个左下角坐标为x,y,长宽为w,h的区域作为渲染的区域

纹理映射

  • 1、缩放
    纹理的映射就是让物体的每个片元(每个颜色像素)都找到对应的纹理纹素点,在这个映射过程中,因为纹理和物体的不匹配,一般会出现两种情况
    第一种是拥有大量纹素的纹理被映射到只还有少量片元的物体中
    第二种是拥有少量纹素的纹理被映射到含有大量片元的物体中
    如下:
    glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
    glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
    GL_TEXTURE_MIN_FILTER:
    是多个纹素对应一个片元的解决方案。可以设置两个值,GL_NEAREST 和 GL_LINEAR ,这两个值分别对应了两种不同的解决方案。GL_LINEAR 会混合匹配的颜色来得到片元的颜色,产生的颜色可能是纹理中不存在的颜色。例如一个纹理是由交替的黑色和白色的纹素组成,那个线性取样会使最终的片元颜色为灰色。GL_NEAREST 会拾取与片元 U,V 坐标最相近的颜色。
    GL_TEXTURE_MAG_FILTER:
    是没有足够的纹素来映射片元的解决方案。可以设置的值同 GL_TEXTURE_MIN_FILTER 一样。GL_LINEAR 会告诉OpenGL ES 混合附近纹素的颜色来计算片元的颜色。GL_LINEAR会有一个放大纹理的效果,当没有足够的纹素来映射片元时,会让纹理模糊的出现在要渲染的图形上。
    GL_NEAREST 仅仅会拾取片元的 U ,V 位置接近的纹素的颜色,并放大纹理,会使其像素化的出现在要渲染的图形上。
    GL_LINEAR:
    线性插值,取最近的点的线性平均值 (性能消耗较大)
    mipmaps
    它也是一种纹理过滤算法,按我的理解它是以空间换时间的一种技巧,具体原理就是事先根据纹理生成长和宽逐渐除以2的小纹理,比如原始纹理大小128x128,
    采用此方法后,会生成64x64 32x32 16x16 8x8 4x4 2x2 1x1的一系列纹理,如果需要20x18的纹理,则取最近的32x32 16x16进行平均
    该方法很好的解决了如下问题:
    1、当纹理很大,但是屏幕区域很小,渲染出现的闪烁问题,因为根据最邻近插值和线性插值都无法很快计算出合理的像素
    它可以取的值如下:
    GL_NEAREST_MIPMAP_NEAREST 选择最近的mipmap层,然后再用最邻近过滤插值
    GL_LINEAR_MIPMAP_NEAREST 选择最近mipmap层,然后再用线性插值
    GL_NEAREST_MIPMAP_LINEAR 选择最近的2层mipmap用最邻近过滤插值
    GL_LINEAR_MIPMAP_LINEAR 选择最邻近的2层mipmap用线性插值
    使用如下函数生成mipmaps
    glGenerateMipmap(GLenum target);

  • 2、warp
    另外一种在映射时可能出现的情况是纹理的四个顶点坐标不是1.0时,将采用如下方式:
    glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_WARP_S,GL_REPEAT) S轴方向
    glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_WARP_T,GL_REPEAT) T轴方向
    GL_REPEAT:纹理没有覆盖的部分重复之前的纹理,当纹理大小大于物体大小时,纹理采样会出错。
    GL_MIRRODED_REPEAT:将原来的纹理先颠倒再重复,当纹理大小大于物体大小时,纹理采样会出错。
    GL_CLAMP_TO_EDGE:延续结束时的纹理

顶点着色器中顶点坐标的顺序规则

open gl 中顶点坐标
static float verData1[8] = {
-1.0f,-1.0f, // 左下角
1.0f,-1.0f, // 右下角
-1.0f,1.0f, // 左上角
1.0f,1.0f, // 右上角
};
对应的纹理坐标
static float uvData[8] = {
0.0f, 1.0f, // 左下角
1.0f, 1.0f, // 右下角
0.0f, 0.0f, // 左上角
1.0f, 0.0f, // 右上角
};
对应的为glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 可以渲染出一张图片

VBO

GPU中专门开辟的一块内存用于存储图元的顶点数据,这样每次调用glDrawArrays()函数时,GLSL就是直接从GPU中获取
顶点数据,而不是每次都有cpu拷贝到GPU(cpu拷贝到gpu肯定效率不如直接从GPU中取),这样对于顶点数据比较多时,
可以加快效率;

FBO

帧缓冲,也就是通过glGenFramebuffers()函数生成的对象,它主要用于存储opengl es最终的渲染结果。

离屏渲染

当需要对纹理进行多次渲染采样时(也就是对一个纹理进行多个着色器程序去处理),而这些渲染采样中间过程是不需要
展示给用户看的,所以就可以额外创建一个FBO对象来专门做这个事情,这个FPO对象就成为为离屏渲染帧缓冲,这个
过程叫做离屏渲染

渲染缓冲区

通过glGenRenderbuffers()生成的缓冲区,他用于将渲染的结果呈现到屏幕上,需要与FBO绑定

opengl es api和EGL api

opengl es api是用来进行图像渲染操作的,
egl api是由各个操作系统实现的系统api,它主要的作用就是创建窗口,创建opengl 上下文环境等。可以由各自厂商自行定义,使用通用的EGL接口。
如苹果就是EAGL,安卓就可以用EGL来自行管理,也可以用GLSurface系统创建opengl 环境

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容