OpenGL学习笔记1:绘制三角形
学习教程
零基础开始学习OpenGL的最佳教程learnOpenGL:https://learnopengl-cn.github.io/intro/
此笔记的学习章节:
OpenGL介绍
关键点:
- OpenGL仅仅是一个规范,具体实现方是显卡的生产商。所以常常需要升级显示的驱动程序。
- OpenGL自身是一个巨大的状态机(State Machine),OpenGL的上下文-Context管理这些状态,通过修改状态,改变渲染的图像
Xcode环境搭建
关键点:
- GLFW编译:
- 引入GLAD:因为OpenGL只是一个标准/规范,具体实现为显卡驱动,需要在运行时,进行动态的链接,GLAD封装了此过程。
- 打开GLAD的在线服务,进行如下配置:
- 将语言(Language)设置为C/C++,
- 在API选项中,选择3.3以上的OpenGL(gl)版本
- 之后将模式(Profile)设置为Core,并且保证生成加载器(Generate a loader)的选项是选中的。
- 点击生成(Generate)按钮来生成库文件
- 下载zip,提取文件:
- 头文件:include/
- 源码文件:glad.c
- 打开GLAD的在线服务,进行如下配置:
- Xcode的Demo:
- 通过xcode创建一个command line项目,c++
- 创建lib目录,把.a, .h文件拖到目录中
- GLFW的静态库:libglfw3.a
- GLAD的源文件:glad.c
- 引入libglfw3.a依赖的库,【Build Phases】–> 【Link Binary With Libraries】里添加库:Cocoa.framework, IOKit.framework, CoreVideo.framework
- 在本地创建libs/目录,把GLFW和GLAD的头文件移入,移入后的目录结构:
- 设置Xcode的头文件查找路径:【Build Settings】–> 【Header Search Paths】的Debug和Release里添加include的路径
- 引入方式:
1
2
3
4
Demo:绘制三角形
窗口
关键点:
- 通过GLFW实例化窗口
- 监听窗口变化,动态调整OpenGL的视口的大小
- 初始化GLAD,即绑定OpenGL的函数指针
- 创建渲染循环
1 | // 定义常量 |
绘制三角形
关键点:
- OpenGL的主要任务是:3D坐标转换为2D坐标,并转变为实际的有颜色的像素。
- 原因:在OpenGL中,任何事物处于3D空间中,但屏幕却是2D的
- 转换过程称为:图形渲染管线(Graphics Pipeline)
- 图形渲染管线:由几个独立的阶段组成,每个阶段将会把前一个阶段的输出做为输入,这些阶段可以称为着色器(Shader),Shader运行在GPU上,部分Shader可以由开发者自己配置,由OpenGL着色器语言(OpenGL Shading Language, GLSL)写成的,如下图所示:
- Vertex Shader:把3D坐标转为另一种3D坐标
- Primitive Assembly(图元装配)阶段:装配成指定图元的形状
- Geometry Shader(几何着色器):可以通过新的顶点,构建其他图元
- Rasterization Stage(光栅化阶段):图元映射为最终屏幕上相应的像素,同时对超出视图外的像素执行裁切(Clipping)
- Fragment Shader(片段着色器):计算一个像素的最终颜色,需要考虑光照、阴影、光的颜色等等因素
- Testing And Blending(测试与混合):通过Alpha考虑混合效果
- 默认情况下,OpenGL没有提供顶点着色器和一个片段着色器,需要自定义
- 项点坐标输入的显示流程:
- 输入的3D坐标可以任意的,但只有在标准化设备坐标(Normalized Device Coordinates)范围内的坐标才会最终呈现在屏幕上,即(x、y和z)上都为-1.0到1.0的范围内
- 标准化设备坐标转换为屏幕空间坐标(Screen-space Coordinates),即通过glViewport函数指定的
- 屏幕空间坐标又会被变换为片段,输入到片段着色器中
- 顶点数据传输给OpenGL的过程:
- 创建 VAO(Vertex Array Object), VBO(Vertex Buffer Object), EBO(Index Buffer Object):
- 创建VAO:glGenVertexArrays
- 创建VBO和EBO:glGenBuffers
- 绑定缓存类型,并传数据:
- 绑定VAO:glBindVertexArray
- 绑定VBO和EBO:glBindBuffer
- 传数据:glBufferData
- 设置顶点属性指针,顶点如何解析:
- 顶点属性指针:glVertexAttribPointer
- 开关:glEnableVertexAttribArray
- 创建 VAO(Vertex Array Object), VBO(Vertex Buffer Object), EBO(Index Buffer Object):
- 创建与编译着色器的过程:
- 创建着色器对象(Shader Object),绑定source,编译,判断:
- 创建:glCreateShader
- 使用着色器语言GLSL(OpenGL Shading Language)编写顶点着色器
- 绑定source:glShaderSource
- 编译:glCompileShader
- 判断:
- glGetShaderiv
- glGetShaderInfoLog
- 创建着色器程序(Shader Program), 绑定所有的着色器对象(shader object),链接着色器程序,对接每个输出与输入
- 创建:glCreateProgram
- 绑定:glAttachShader
- 链接:glLinkProgram
- 判断:
- glGetProgramiv
- glGetProgramInfoLog
- 删除着色器对象:glDeleteShader
- 创建着色器对象(Shader Object),绑定source,编译,判断:
- 绘制三角形的过程:
- 设置着色器程序:glUseProgram
- 设置顶点数组对象VAO:glBindVertexArray
- 调用画图形的API,设置图元着色器的状态:glDrawArrays
- 绘制距形的过程:
- 由多个三角形组成为距形
- 为了减少重复顶点数据,使用索引缓存数据来按顺序绘制三角形
- EBO,GL_ELEMENT_ARRAY_BUFFER
- 调用使用索引缓存数据的绘制方法:glDrawElements
- 设置绘制模式:
- 线框模式:glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1 | // 定义常量 |
C++的知识点
关键点:
- 编译后的机器码与操作系统和CPU的指令集有关,最佳的方式是从源代码编译生成二进制文件
- CMake是一个工程文件生成工具。用户可以使用预定义好的CMake脚本,根据自己的选择(像是Visual Studio, XCode, Eclipse)生成不同IDE的工程文件
- Linux下的静态库以.a结尾(Winodws下为.lib)
- Linux下的动态库以.so 或 .so.y结尾,其中y代表版本号(Windows下为.dll)
- C++的include:
- <> 系统目录空间
- “” 用户目录空间
- 宏定义:#define <宏名> <字符串>
- 指针,*,&的区别
- *,表示指针变量地址所指向的值
- & 表示取变量的地址