目录
一、前言
二、概述
2.1 光学
2.2 三通道
2.3 上下文Context
2.4 渲染管线
2.5 着色器Shader
2.6 缓冲区和数组
三、安装
四、运行
五、库API
5.1 核心库GL
5.2 实用库GLUT
一、前言
渲染render是用软件从模型生成图像的过程,也表示编辑视频生成想达到的效果。模型是用特定的语言对三维物体的描述,不包括几何、视点、纹理及照明信息。
OpenGL不能开发程序、构建后台,它定义了2D、3D图像渲染接口。OpenGL ES (Embed System)是OpenGL子集,针对嵌入式设备设计。Metal苹果提出的框架,将3D性能提高10倍。VulKan针对即时3D程序设计,均衡CPU/GPU使用。
二、概述
OpenGL(Open Graphics Library)渲染架构师Client /Server模式,OpenGL Server负责驱动GPU(图形渲染管线),OpenGL Client是开发人员设计的一些调用API。
在线API docs.gl
OpenGL着色器编程语言是GLSL(OpenGL Shading language),开发人员自定义短小程序,在GPU上执行,代替固定的渲染管线。
2.1 光学
BGRA:blue ,green, red红绿蓝光学三原色,A表示透明度alpha。常见的图像颜色空间解释(RGB HSV YUV LAB CMYK)-次世代BUG池 (neucrack.com)
YUV: HVS(human visual system)人类视觉系统对色彩空间的感知能力,Y亮度(luminance)和色度(chrominance),色度包括 U色调(Hue)和 V色饱和度(Saturation)。色调:光波的峰值,描述光颜色;色饱和度:光波的谱宽,描述光的纯度。色度表示为 U(cb), V(cr) 坐标
2.2 三通道
什么是纹理:通常表示物体表面呈现凸凹不平的沟纹,一般表示物体表面的彩色图案。在渲染图形的时候,为使场景更加逼真,需要在其编码填充图片(纹理图片)。
纹理贴图:纹理贴图是一个二维图像文件,可以将其应用于的表面以添加颜色,纹理或其他表面细节(如光泽度,反射率或透明度)。纹理贴图被开发为直接对应于未包装3D模型的UV坐标。「3D建模」纹理贴图的基础 - 知乎 (zhihu.com)纹理贴图一般用来表达物体表面的显示细节,这些细节包括表面颜色,阴影,光照信息设置与显示无关的数据等纹理贴图 - 知乎 (zhihu.com)
纹理化:将选择或创建的纹理应用于图像
颗粒:使用多种方法并通过模拟不同种类的颗粒(常规、软化、喷洒、结块、强反差、扩大、点刻、水平、垂直和斑点)为图像添加多种噪波,使其产生一种纹理效果。
光照:日常生活发光的物体发出的光线,如太阳、灯。物体被光源照射发生反射,反射的光纤使我们看到物体的颜色。
法线:垂直于平面的向量,表示平面方向。法线可以判断一个平面是正对或背对光源,或其他角度
投影:将3D坐标转换为二维屏幕坐标,实际线条在将在二维坐标系进行绘制。
变换矩阵:OpenGL图像发生平移,缩放,旋转等变换需要使用变换需要使用变换矩阵。
渲染:将图像图形数据转换为3D空间图像操作,英文名是render。渲染是CG(Computer Graphic)最后一道工序,使图像符合3D场景的阶段。OpenGL中渲染管线由一系列着色器构成。
Attribute:属性通道,传递可变参数,如颜色数据、顶点数据,纹理坐标、光照法线
uniform: 统一变量通道,传递不变的参数,如变换矩阵,RGBA->YUV
Texture Data:纹理数据
2.3 上下文Context
OpenGL上下文表示OpenGL当前的各种状态,操作某一动作时所处的环境。在调用任何OpenGL指令前都要创建一个OpenGL上下文(上下文可以嵌套,如在A的环境下配置B),这是OpenGL指令执行的基础。
如glBink, 设置选项->操作缓冲->上下文渲染
OpenGL上下文是一个巨大的状态机,频繁切换上下文会产生较大开销,不同绘制模块可以使用完全独立的状态管理。因此,可 以在应用程序中分别创建多个不不同的上下文,在不同线程中使用不不同的上 下文,上下文之间共享纹理、缓冲区等资源。这样的方案,会⽐反复切换 上下⽂,或者⼤量修改渲染状态,更加合理⾼效。OpenGL状态机:
- 记忆功能,能够记住当前的状态(比如OpenGL可以记住当前所使用的颜色,是否开启了混合功能等)
- 接收输入,根据输入内容和自己原先的状态,修改自己当前状态,并且可以有对应的输出(比如调用OpenGL函数的时候,实际上就是在接收我们的输入)
- 进入特殊状态的时候(停机状态),便不再接收输入,停止工作。(OpenGL可以进入停止状态,不再接收输入,在程序退出前,OpenGL总是会先停止工作)
2.4 渲染管线
在屏幕上画一个图形,需要确定顶点坐标,点成线,线成面。图形渲染管线就是将一个一个状态切换(点、线、面)以及在不同状态中的渲染逻辑和数据处理。OpenGL渲染逻辑所使用的语言为类C语言,GLSL OpenGL Shading Language , OpenGL 着色语言。
渲染管线流程如下:
顶点着色器 → 图元装配 → 几何着色器 → 光栅化 → 片段着色器 → 测试与混合
OpenGL在处理shader期间,和其他编译器,通过编译、链接等步骤,首先生成着色器程序glProgram。着色器程序包含了顶点着色器和片段着色器的运算逻辑。
OpenGL绘制过程:
- 由顶点着色器对象传入的顶点数据进行运算,确定绘制的图形形状
- 通过图元进行装配,将顶点数据转换为图元(几何着色非必须阶段)
- 光栅化,将图元矢量图形,转化为栅格化数据,即若干个片段(位置、颜色、深度)
- 栅格化数据传入片元着色器中进行运算,片元着色器会对栅格化数据中的每一个像素进行运算片段的颜色
- 进行深度测试、模板测试、计算带有透明度片段混合后的最终颜色
2.5 着色器Shader
着色器程序是开发人员编写的渲染管线。OpenGL提供三种着色器:顶点着色器(vertex shader)、几何着色器(GeometryShader)、片段着色器(FragmentShader , 又叫片元着色器)/像素着色器(pixel Shader),其中顶点着色器和片段着色器为开发人员必须提供(OpenGL ES3.0),几何着色器为可选提供。曲面细分着色器(Tessellation Shader)。
(1)顶点着色器
输入:顶点数据、颜色值、纹理采样器
运算:旋转、平移、投影
输出:顶点数据给图元装配
顶点着色器是OpenGL用于计算顶点属性的程序。顶点着色器是逐顶点运算的程序,即每个顶点数据都会执行一次顶点着色器,逐顶点着色是并行运算,并且顶点着色器运算过程中无法访问其他顶点的数据。
典型的需要计算的顶点属性主要包括顶点坐标变换,逐顶点光照运算等。顶点坐标由自身坐标系转换成归一化坐标系的运算。
(2)图元装配
输入:顶点数据
运算:连接方式,如点、线、三角形、梯形灯基本几何图形(图元)
输出:图元数据(片段)
OpenGL支持的图元类型:
(3)光栅化
输入:图元数据
运算:将几何图元转化为一张二维图像
输出:带有位置、颜色和深度信息的片段
光栅化将几何图元变为二维图像的过程,包含了两部分:
- 决定窗口坐标中的哪些整形栅格区域被基本图元占用
- 分配一个颜色值和深度值到各个领域
把物体的数学描述以及与物体相关的颜色信息转换为屏幕上用于对应位置的像素用于填充像素的颜色,这个过程叫做光栅化,这是一个将模拟信号转化为离散信号的过程。
(4)片元着色器
输入:栅格化片段
运算:计算片段颜色
输出:着色后的片段
片元着色器用来处理图形中每一个像素点颜色计算和填充,是OpenGL中用于计算片段(像素)颜色的程序。片段着色器是逐像素运算的程序,也就是说每一个像素都会执行一次片段着色器(并行运算)。
(5)测试和混合
深度测试:对屏幕同一个位置片段比较,保留深度最小的片段
模板测试:与运算,控制屏幕需要显示的内容
混合(Blending):计算带有透明度片段最终颜色
2.6 缓冲区和数组
在OpenGL ES中有3中图元,点、线、三角形;顶点数据就是图像骨架, 顶点指的是我们在绘制图形的时候,它的顶点位置数据,而这个数据可以直接存储在数组中或者将其缓存到CPU内存中。顶点数据的存储类型是array或者Buffer。
Array和Buffer的区别:
在调用绘制方法时,直接由内存传入顶点数据,也就是说这部分数据之前是存储在内存之中的,被称为顶点数组。
性能更高的做法是提前分配一块显存,将顶点数据预先传入到显存当中,这部分的显存,叫做顶点缓冲区。
三、安装
Windows平台,opengl32.lib已经包含在Microsoft SDK里了,它在Visual Studio安装的时候就默认安装了。
glew(OpenGL Extension Wrangler Library):OpenGL2.0之后的扩展库,能自动识别当前平台支持的OpenGL高级扩展函数The OpenGL Extension Wrangler Library download | SourceForge.net
glut(OpenGL utility Toolkit):跨平台实用工具库,用于窗口界面。API包括窗口操作函数,消息回调函数(键盘、鼠标、刷写);3D物体函数。
freeglut Windows Development Libraries (transmissionzero.co.uk)
glfw(Graphics Library Framework):跨平台应用程序图形框架库,支持OpenGL 和 OpenGL ES,支持窗口创建、读取输入、处理事件等功能;替代glut。Download | GLFW
glad(OpenGL address):是glew的升级版https://glad.dav1d.de
OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现,导致大多数函数位置无法在编译时确定,需要在运行时查询。开发人员需要在运行时获取函数地址并将其保存在一个函数指针中供以后调用,而glad可以简化该过程。
Glad http://glad.dav1d.de在线设置C/C++,API选择3.3以上OpenGL版本,模式profile设置为core,点击Generate即可生成库文件khrplatform.h, glad.h , glad.c。
四、运行
Visual Studio环境下配置参考下图链接,但是原文中将x86和x64库混淆了。
opengl安装(win10, vs2019) - 这都几点了,该摸鱼了 - 博客园 (cnblogs.com)
OpenGL开发环境搭建(VS2015+GLFW+GLAD) - 知乎 (zhihu.com)
VSCode 下构建:
vscode配置OpenGL开发环境【详细】_CodeDog_wang的博客-CSDN博客
VSCode配置OpenGL环境(GLUT)及常见问题解决_vscode opengl_GE1228的博客-CSDN博客
按照第3节Visual Studio安装运行如下:
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h> // GLUT头文件
// 图形绘制函数
void myDrawing(void) {
//清除颜色缓冲区
printf("$\n");
glClearColor(0.1, 0.5, 0.3f, 0.0); //设置背景清除 绿色
glClear(GL_COLOR_BUFFER_BIT); //执行清除
//以线框形式绘制一个茶壶
glRotatef(45, 1.0f, 1.0f, 1.0f); //旋转 -- <缩放窗口>
glutWireTeapot(0.5f); //壶
//glutWireSphere(0.5f, 24, 24); //线框球面
//glutWireTorus(0.25f, 0.6, 30, 25); //线框球面
glFlush(); //强制绘图
}
// 主函数
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
//对GLUT进行初始化
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
//产生一个名为"Hello"的绘制窗口, //使用缺省值
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("OpenGL Hello World!");
//注册绘制函数
glutDisplayFunc(myDrawing);
//清除颜色缓冲区 ----- 放在这里不起作用
//glClearColor(0.0, 0.0, 1.0f, 0.0); //设置背景清除蓝色
//glClear(GL_COLOR_BUFFER_BIT);
//主消息循环
glutMainLoop(); //进入消息循环
return 0;
}
五、库API
核心库GL:核心图形处理函数,115个原始函数
实用库GLU:是对GL的封装,所有复杂绘图都是通过点线面开始,GLU调用核心库提供给开发者简单的用法以实现复杂的操作。
辅助库AUX:提供窗口管理,输入输出以及绘制一些简单的三位物体,被GLUT取代。
实用工具库GLUT:openGL utility toolkit隐藏不同平台API复杂接口,创建3D图形,窗口消息等
扩展库WGL:windows专用库,针对windows平台的扩展
扩展库GLX:用于Unix和Linux扩展函数
5.1 核心库GL
glClear | 用当前值清楚缓冲区 |
glColorMask | 允许或不允许写色彩组件帧缓冲区 |
glCopyTexImage2D | 将像素从帧缓冲区拷贝到一个双空间纹理图形中 |
glDeleteTextures | 删除命名的纹理 |
glDepthRange | 定义z值从标准的设备坐标映射到窗口坐标 |
glDrawElements | 渲染数组数据中的图元 |
glFinish | 等待直到OpenGL执行结束 |
glFlush | 在有限时间强制OpenGL执行 |
glGetColorTableEXT | 从当前目标纹理调色板得到颜色表数据 |
glLineWidth | 设置光栅线段宽 |
5.2 实用库GLUT
glutReshapeFunc | 指定当窗口的大小改变时调用的函数 |
glutMouseFunc | 注册当前窗口的鼠标回调函数 |
glutEntryFunc | 设置鼠标的进出窗口的回调函数 |
glutIdleFunc | 设置空闲回调函数 |
glutMenuStateFunc | 注册菜单状态回调函数 |
参考:
20分钟让你了解OpenGL ——OpenGL全流程详细解读 - 腾讯云开发者社区-腾讯云 (tencent.com)
2、OpenGL初探之OpenGL图形API及专有名词 - 简书 (jianshu.com)
一看就懂的 OpenGL 基础概念丨音视频基础 (qq.com)
OpenGL学习之API详解_OpenGL_积木网(gimoo.net)
OpenGL常用的API - 百度文库 (baidu.com)
OpenGL常用API (renrendoc.com)