可能考的OpenGL
1. 纹理映射(Texture Mapping)
GLuint texture;
glGenTextures(1, &texture); // 生成纹理对象
glBindTexture(GL_TEXTURE_2D, texture); // 绑定为2D纹理
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 加载纹理数据(假设 imageData 已加载图片)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, imageData);
glGenerateMipmap(GL_TEXTURE_2D); // 自动生成 mipmap
// 使用纹理坐标(在绘制图元时)
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(...);
glTexCoord2f(1.0, 0.0); glVertex3f(...);
glTexCoord2f(1.0, 1.0); glVertex3f(...);
glTexCoord2f(0.0, 1.0); glVertex3f(...);
glEnd();
2. 投影相关
(1)正交投影(glOrtho)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, bottom, top, nearVal, farVal);
示例:
glOrtho(-1, 1, -1, 1, 1, 10); // 正交视见体,深度区间 [1, 10]
(2)透视投影(gluPerspective 或 glFrustum)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fovy, aspect, zNear, zFar);
示例:
gluPerspective(60.0, 1.0, 1.0, 100.0); // fovy=60°, 近1远100
(3)标准化视见体(由 glFrustum / gluPerspective 自动生成)
- OpenGL 会自动将透视投影映射为标准视见体 [ − 1 , 1 ] 3 [-1, 1]^3 [−1,1]3
- 不需要手写标准化矩阵,glFrustum/gluPerspective 内部完成
(4)归一化视见体到屏幕(viewport 映射)
glViewport(x, y, width, height);
例如:
glViewport(0, 0, 800, 600); // 将 NDC 区域 [-1,1] 映射到窗口像素
3. 相机平移/旋转/缩放(模型视图变换)
OpenGL 中常用 gluLookAt
定义相机,或使用 glTranslatef/glRotatef/glScalef
。
示例 1:使用 gluLookAt 设置相机
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ,
centerX, centerY, centerZ,
upX, upY, upZ);
例如:
gluLookAt(0.0, 0.0, 5.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0); // 相机看向原点,Y 轴为上
示例 2:手动平移、旋转、缩放
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(tx, ty, tz); // 平移
glRotatef(angle, x, y, z); // 旋转(角度制)
glScalef(sx, sy, sz); // 缩放
4. Z-buffer 开启及使用
glEnable(GL_DEPTH_TEST); // 开启深度测试
glDepthFunc(GL_LESS); // 默认:较小的深度值覆盖
// 初始化窗口时设置深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
你还需要在窗口初始化时要求深度缓冲:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
5. 双缓冲机制代码
设置双缓冲显示模式:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
在 display 回调中绘图并交换缓冲区:
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 绘制命令
...
glutSwapBuffers(); // 显示结果
}
6.隐藏面去除(back-face)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
CG01
Modeling
NURBS(Non-Uniform Rational B-Splines)非均匀有理B样条
一种非常强大的数学曲线/曲面表示方法,可以同时表示:
- 规则形状(如圆、椭圆)
- 自由形状(如复杂汽车曲面、动画人物皮肤)
NURBS曲线由以下几个要素定义:
控制点(Control Points):一系列的点,用来影响曲线的形状,但通常不位于曲线上。
节点向量(Knot Vector):一个非减序列,定义了曲线段之间的连接方式。
权重(Weights):与每个控制点关联的实数,影响曲线与控制点的接近程度。
度数(Degree):一个整数,表示曲线的平滑度。
NURBS曲线的数学表达式为:
C ( u ) = ∑ i = 0 n w i P i N i , k ( u ) ∑ i = 0 n w i N i , k ( u ) C(u)=\frac{\sum_{i=0}^n w_i P_i N_{i, k}(u)}{\sum_{i=0}^n w_i N_{i, k}(u)} C(u)=∑i=0nwiNi,k(u)∑i=0nwiPiNi,k(u)
其中:- C ( u ) C(u) C(u) 是曲线上的点。
- P i P_i Pi 是控制点。
- w i w_i wi 是与控制点 P i P_i Pi 关联的权重。
- N i , k ( u ) N_{i, k}(u) Ni,k(u) 是第 i i i 个 k k k 阶(度数)的 B − S p l i n e B-S p l i n e B−Spline 基函数,由节点向量决定。
Parametric(参数化)建模
表示形状为参数 u , v u, ~ v u, v 的函数形式:
- 曲线: C ( u ) = ( x ( u ) , y ( u ) , z ( u ) ) C(u)=(x(u), y(u), z(u)) C(u)=(x(u),y(u),z(u))
- 曲面: S ( u , v ) = ( x ( u , v ) , y ( u , v ) , z ( u , v ) ) S(u, v)=(x(u, v), y(u, v), z(u, v)) S(u,v)=(x(u,v),y(u,v),z(u,v))
2D图像和3D模型(3D模型由顶点、边和面(通常是三角形)组成)
- 2D:像素,颜色,插值算法
- 3D:非规则坐标,三角网络,参数化方法(用于计算顶点位置的方法,如UV映射。)
Animation
Rendering(渲染)
- 从一个简单的线框模型开始,通过应用材质、纹理、光照和环境等元素,生成逼真的3D图像。渲染的目标是使计算机生成的图像尽可能接近真实世界的视觉效果。
Interaction
CG02
图像形成
**物理成像系统:**相机,显微镜,望远镜,人类视觉系统等
**图像形成的元素:**物体,观察者,光源,材质属性
**光线追踪:**通过追踪从光源发出的光线,计算哪些光线进入相机镜头来形成图像。光线可能与物体多次交互(如反射、折射),最终被吸收或射向无穷远。
RGB理论,加色法和减色法
合成相机模型(Synthetic Camera Model)
- 投影中心(Center of projection):相机的位置。
- 图像平面(Image plane):光线投影的平面。
- 投影点(Projection of p):物体在图像平面上的投影。
输入和交互
基本输入设备:
物理设备(Physical Devices):实际的硬件设备。鼠标,键盘,轨迹球
逻辑设备(Logical Devices):通过API定义的设备。
- 位置(Position):如鼠标的坐标。
- 对象标识符(Object identifier):如选择的对象ID。
输入模式(Input Modes):输入的获取方式和时机。
触发机制:输入设备包含一个触发器,用于向操作系统发送信号:
- 鼠标按钮:点击鼠标按钮。
- 键盘按键:按下或释放按键。
当触发时,输入设备将信息(测量值)返回给系统:
- 鼠标:返回位置信息。
- 键盘:返回ASCII码。
请求模式(Request mode):程序主动请求输入。
事件模式(Event mode):输入设备触发事件,程序响应事件。用户可以随时触发多个输入设备,每个触发生成一个事件,事件的测量值放入事件队列,用户程序可以检查事件队列。
glutMainLoop()
图形系统交互
- 用户输入设备:用户通过输入设备(如鼠标、键盘)发送指令。
- 图形系统:接收输入并更新图像。
- 显示设备:显示更新后的图像。
- 用户反应:用户看到变化后的图像并做出进一步操作。
事件驱动输入
- 定义:事件驱动输入是一种输入模式,程序通过事件循环监听和处理输入事件。
- 事件类型:
- 鼠标事件:点击、移动、滚动等。
- 键盘事件:按键按下、释放等。
- 窗口事件:窗口大小改变、焦点变化等。
- 事件处理:
- 事件监听:程序监听特定类型的事件。
- 事件分发:将事件分发给相应的处理函数。
- 事件响应:根据事件类型执行相应的操作。
光线追踪和辐射度方法等物理方法虽然在生成高质量图像方面表现出色,但由于计算复杂度高,不适合实时应用。实用方法通过顺序处理和图形管道架构,利用局部光照模型和硬件加速,实现了高效的实时渲染。
光线追踪(Ray Tracing)
- 定义:光线追踪是一种通过追踪从投影中心发出的光线,直到它们被物体吸收或射向无穷远来生成图像的技术。
辐射度(Radiosity)
- 定义:辐射度是一种基于能量守恒的光照模型,主要用于模拟漫反射光照。
顺序处理(Process objects one at a time)
- 定义:按照应用程序生成的顺序逐个处理对象。/仅考虑直接光照,忽略间接光照和全局光照效果。
图形管道(Pipeline architecture)
- 定义:图形管道是一种流水线架构,将渲染过程分解为多个阶段,每个阶段由专门的硬件单元处理(如顶点着色、片元着色等)。
图形流水线中的关键概念
顶点处理(Vertex Processing)
顶点处理是图形流水线的第一步,主要任务是将顶点从一个坐标系统转换到另一个坐标系统。这涉及到以下步骤:
- 坐标变换:
- 对象坐标(Object Coordinates):顶点在对象本地坐标系中的位置。
- 相机坐标(Camera Coordinates):顶点在相机坐标系中的位置,通过模型视图变换实现。
- 屏幕坐标(Screen Coordinates):顶点在屏幕坐标系中的位置,通过投影变换实现。
- 矩阵变换:每个坐标变换都等价于一个矩阵乘法操作。
- 顶点着色:计算顶点的颜色,可能涉及光照模型。
- 坐标变换:
投影(Projection)
投影是将3D场景转换为2D图像的过程,主要分为两种类型:
- 透视投影(Perspective Projection):所有投影线汇聚于投影中心,模拟人眼观察效果。
- 平行投影(Parallel Projection):投影线平行,投影中心被投影方向替代,常用于技术制图。
图元组装(Primitive Assembly)
图元组装是将顶点组合成几何对象的过程,为后续的裁剪和光栅化做准备。常见的几何对象包括:
- 线段(Line Segments)
- 多边形(Polygons)
- 曲线和曲面(Curves and Surfaces)
裁剪(Clipping)
裁剪是移除不在视锥体内的物体的过程,类似于真实相机的视野限制。视锥体外的物体被裁剪掉,不在渲染范围内。
光栅化(Rasterization)
光栅化是将三角形转换为片段(Fragments)的过程,每个片段对应一个像素。主要步骤包括:
- 片段生成:为每个三角形生成潜在的像素片段。
- 深度测试:确定片段是否可见。
- 属性插值:在三角形内插值顶点属性(如颜色、纹理坐标)。
片段处理(Fragment Processing)
片段处理是确定片段颜色的过程,主要任务包括:
- 纹理映射:将纹理图像映射到片段上。
- 光照计算:进一步计算光照效果。
- 隐藏面消除:通过深度测试移除被遮挡的片段。
API(应用程序编程接口)
API是程序员与图形系统交互的接口,提供了以下功能:
- 对象规范:定义场景中的几何对象。
- 相机规范:定义虚拟相机的位置和方向。
- 光源和材质:定义光源类型和材质属性。
对象规范(Object Specification)
API支持多种几何图元,包括:
- 点(Points):0D对象。
- 线段(Line Segments):1D对象。
- 多边形(Polygons):2D对象。
- 二次曲面(Quadrics):如球体、圆锥等。
- 参数多项式(Parametric Polynomials):如B样条曲线。
相机规范(Camera Specification)
相机规范包括以下参数:
- 位置:镜头中心的位置。
- 方向:相机的朝向。
- 镜头参数:如视野角度、焦距等。
- 胶片尺寸:输出图像的尺寸。
- 胶片平面方向:图像平面的朝向。
光源和材质(Lights and Materials)
- 光源类型:
- 点光源(Point Sources):如灯泡。
- 分布式光源(Distributed Sources):如日光。
- 聚光灯(Spot Lights):方向性光源。
- 远近光源(Near and Far Sources):模拟不同距离的光源。
- 颜色属性(Color Properties):光源的颜色。
- 材质属性:
- 吸收属性(Absorption):材质的颜色属性。
- 散射属性(Scattering):
- 漫反射(Diffuse):均匀散射。
- 镜面反射(Specular):方向性反射。
- 光源类型:
ep:
glBegin(GL_POLYGON) glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glEnd( );
CG03
图元是图形渲染的基本单元,OpenGL 支持以下类型:
- 点:0 维对象,仅表示空间中的一个位置。
- 线段:1 维对象,连接两个顶点。
- 多边形:2 维对象,如三角形或四边形,用于构建平面图形。
- 曲线和曲面:包括二次曲面(如球体、圆柱)和参数多项式曲面(如贝塞尔曲面),用于更复杂的建模。
相机(或观察者)决定了场景如何被渲染到屏幕上,其属性包括:
- 六个自由度:相机在 3D 空间中的位置(x, y, z)和方向(俯仰、偏航、滚转)。
- 镜头中心的位置:相机的空间坐标。
- 方向:相机朝向的向量,决定观察的方向。
- 镜头:模拟相机的焦距,影响视角(广角或长焦)。
- 胶片大小:对应视口的大小,决定渲染区域的分辨率。
- 胶片平面的方向:决定投影平面如何对齐,通常与方向垂直。
OpenGL 的函数类型:
- 图元生成:如 glVertex(传统)或 VBO,用于定义点、线段、三角形。
- 属性设置:设置颜色、纹理等渲染属性。
- 变换:
- 视图变换:设置相机视角(如视图矩阵)。
- 模型变换:调整物体位置、旋转、缩放(如模型矩阵)。
- 控制和输入:通过 GLFW 管理窗口和用户交互。
- 查询:获取 OpenGL 状态(如 glGetString 获取版本)。
函数分为两类:
- 图元生成:
- 如果图元可见,可能产生输出
- 顶点处理和图元外观由状态控制
- 状态更改:
- 变换函数
- 属性函数
- 图元生成:
OpenGL 的图形渲染管线:
- 顶点着色器:处理顶点数据,转换坐标。
- 形状装配:将顶点组装成图元(如三角形)。
- 几何着色器:可选,生成或修改图元。
- 光栅化:将图元转为屏幕像素(片段)。
- 片段着色器:计算每个片段的颜色。
- 测试与混合:执行深度测试、Alpha 混合等,生成最终像素。
GLFW 的事件驱动模型:
- 事件循环:
- 持续运行,处理用户输入(如键盘、鼠标)和窗口事件(如关闭)。
- 步骤:
- 初始化:调用 glfwInit。
- 窗口和上下文:创建窗口,设置 OpenGL 上下文。
- 事件回调:注册处理函数(如键盘回调)。
- 主循环:
- 渲染场景。
- 处理事件(glfwPollEvents)。
- 交换缓冲区(glfwSwapBuffers)。
- 终止:清理资源(glfwTerminate)。
- 事件循环: