Android
在 Android 平台有两种方法可以构建 OpenGL 环境:通过系统自带的 GLSurfaceView 组件和通过 EGL 。GLSurfaceView 内部自带了 OpenGL 的渲染线程,通过 EGL 需要自己创建渲染线程。
Android 平台通过 OpenGL 渲染图像的本质是通过一系列的 GPU 指令将绘制的图形或者获得的图像帧(本地/网络视频解码或摄像头采集)渲染到设备屏幕上的过程,这个屏幕在系统中被抽象为 Surface ,而图形和图像则被抽象为 Texture (纹理),纹理通过顶点和片段着色器映射到 Surface 上。顶点着色器可以简单理解为确定每个点在屏幕上的坐标,而片段着色器可以简单理解为确定每个点的颜色,即一个计算位置,一个计算颜色。OpenGL 的编程模式为线性编程,即上一段程序的输出是下一段程序的输入。
以绘制三角形为例:
GLSurfaceView
在 Android 的 OpenGL 环境中,用纹理 ID 来标识纹理 ,它实际上指向的是 GPU 中分配的一块内存区域,用于存储纹理数据, SurfaceTexture
将视频帧数据存储在这个内存区域中。
初始设置
1 | // 创建一个OpenGL ES 2.0的上下文 |
创建 Renderer
1 | public class MyGLRenderer implements GLSurfaceView.Renderer { |
编写着色器
1 | private final String vertexShaderCode = |
编译着色器
1 | public static int loadShader(int type, String shaderCode){ |
链接着色器
1 | int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); |
定义图形数据
1 | static float triangleCoords[] = { // 按逆时针方向顺序 |
绘制图形
1 | public void draw() { |
EGL
EGL (Embedded-System Graphics Library) 是一个接口层,连接了 OpenGL ES 等图形库和显示设备(Surface),GLSurfaceView 就是对 EGL 的封装。它有几个关键概念:
EGLDisplay:表示与本地窗口系统的连接。
EGLConfig:描述绘图表面的格式和类型的配置,包括颜色深度、缓冲区类型等。
EGLContext:表示OpenGL ES等图形库的渲染上下文。
EGLSurface:表示一个可以渲染的表面,例如窗口表面、Pixmap表面或Pbuffer表面。
它们的关系可以简单理解为 EGLSurface 和 EGLContext 通过 EGLDisplay 连接。
创建 EGL 显示和初始化
1 | EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); |
配置 EGL
1 | int[] configAttribs = { |
创建 EGL 上下文
1 | int[] contextAttribs = { |
创建 EGL Surface
1 | Surface surface = ...; // 获取或创建一个 Android Surface |
编写着色器
编译和链接着色器
定义图形数据
均同上
连接 EGL 上下文和显示设备
1 | // 绑定 EGL 上下文和 Surface |
释放 EGL 和 OpenGL 资源
1 | GLES20.glDeleteProgram(program); |
使用 GLSurfaceView 和 EGL 渲染本地视频帧的 Demo 地址:
https://github.com/cmder/Demos/tree/main/Mp4Player
Windows
IDE
下载安装 Visual Studio 2022
安装 OpenGL / GLSL
不需要安装,系统自带,可使用 GLView 查看版本。
准备 GLFW
用途:用于创建和管理 OpenGL 上下文、窗口和输入事件的库。
- 下载 GLFW 源代码:https://www.glfw.org/download.html
- 下载并安装 Cmake:https://cmake.org/
- 运行 CMake 的图形界面并选择GLFW源代码所在位置和期望的构建目标文件夹
- 单击Configure
- 单击Generate
CMake会在之前指定的“构建目标”文件夹中生成多个文件,该文件夹中有一个文件名为GLFW.sln,用Visual Studio打开并构建。构建生成后,在\build\src\Debug下找到glfw3.lib文件,在\include\GLFW下找到glfw3.h和glfw3native.h。
准备 GLEW
用途:用于加载 OpenGL 扩展函数的库。解决了不同平台、不同硬件上 OpenGL 版本和功能不一致的问题。确保能够使用最新的 OpenGL 功能。
从官网https://glew.sourceforge.net/下载64位二进制文件,解压后找到以下项目:
- lib/Release/x64 下的glew32.lib
- bin/Release/x64 下的glew32.dll
- include文件夹下的头文件
准备 GLM
用途:用于 OpenGL 程序中的数学计算库,特别是矩阵和向量操作。
从官网https://github.com/icaven/glm?tab=readme-ov-file下载,glm文件夹下的全部内容。
准备SOIL2
用途:用于加载图像纹理的库,主要用于将图片文件加载为 OpenGL 纹理。
下载并解压缩 premake :https://premake.github.io/
下载SOIL2:https://github.com/SpartanJ/SOIL2(使用界面中Code下的Download ZIP超链接),然后解压缩。
将premake5.exe文件复制到soil2文件夹中。
在soil2文件夹下打开命令提示符,运行命令:
1
premake5 --platform=x64 vs2012
在soil2文件夹中,打开make文件夹,然后打开windows文件夹。双击SOIL2.sln。
使用界面顶部的下拉菜单,从x86(或Win32)切换到x64,然后在“解决方案资源管理器”面板中,右键单击soil2-static-lib并选择“生成(Build)”。\lib\windows下可以发现soil2-debug.lib
准备共享的lib和include文件夹
创建库文件夹,放入glew32.dll,再创建两个子文件夹:lib 和 include,lib下放glew32.lib,glew32s.lib,glfw3.lib,glm.lib,soil2-debug.lib,include文件夹下创建glew,glfw,glm和SOIL2(\src\SOIL2)文件夹,放入各自头文件。
创建Visual Studio自定义项目模板
启动Visual Studio(假设为2019版本)。创建一个新的C++空项目。在界面顶部中心,菜单栏下方有两个相邻的下拉菜单。选择x64。先在Debug模式下(然后在Release模式下)进入“项目属性”并进行以下更改。
在“VC++目录”下(也可能写成“C/C++”),单击“常规”,然后在“包含目录”中添加你之前创建的include文件夹。
在“链接器”下,有以下两个更改:
单击“常规”,然后在“附加库目录”下添加先前创建的lib文件夹。
单击“输入”,然后在“附加依赖项”下添加以下4个文件名:glfw3.lib、glew32.lib、soil2-debug.lib和opengl32.lib(最后一个应该已经作为标准Windows SDK的一部分提供)。
对Debug和Release模式的项目属性都进行上述更改后,就可以开始创建模板了。
创建模板通过进入“项目”菜单并选择“导出模板”来完成。选择“项目模板”,并为模板提供有意义的名称,例如“OpenGL project”。
新建项目
安装库并设置好自定义模板后,创建一个新的OpenGL C++项目就很简单了。
- 启动Visual Studio,单击“新建项目”。
- 在左上方选择OpenGL模板,然后单击“下一步”。
- 给项目起一个名称,然后单击“下一步”。
- 使用界面顶部的下拉菜单,从x86切换到x64。
- 回到Windows中,导航到VS创建的和你新建项目名称相同的文件夹,其中应该还有另一个同名的子文件夹。
- 将应用程序文件复制到子文件夹中,包括应用程序用到的任何.cpp源文件、.h头文件、.glsl着色器文件、纹理图像文件和.obj 3D模型文件。不需要再指定任何在模板里已经内置的头文件。
- 将glew32.dll也放入同一个子文件夹。
- 在解决方案资源管理器中,右键单击“源文件”,选择“添加►现有项”加载main.cpp。重复这个过程添加其他的.cpp文件。
- 在解决方案资源管理器中,右键单击“头文件”,选择“添加►现有项”加载应用程序的头文件(.h文件)。
- 现在就准备好构建和执行应用程序了。
部署
在开发、测试和调试应用程序之后,程序可以作为一个独立的可执行文件进行部署。部署时需要在Release模式下构建项目,然后将以下文件放在同一个文件夹中:
- 项目生成的.exe文件;
- 应用程序使用的所有着色器文件;
- 应用程序使用的所有纹理图像和模型文件;
- glew32.dll。