基于归一化设备坐标的视图旋转时如何校正宽高比?
OpenGL 2D视图旋转时的宽高比校正方案
核心思路
通过在视图变换流程中加入宽高比校正逻辑,将坐标先转换到与物理屏幕等比例的逻辑空间,确保旋转前后线段的物理显示长度一致,代价是超出原归一化设备坐标(NDC)范围的内容会被裁剪。
具体实现步骤
实时计算宽高比缩放因子
- 每次窗口尺寸变化或绘制前,获取当前窗口的像素宽度
w和高度h,计算宽高比:aspect_ratio = (float)w / h; - 以水平方向的物理长度为基准,垂直方向需要乘以
aspect_ratio来匹配水平方向的单位物理长度;若以垂直方向为基准,则水平方向乘以1/aspect_ratio。
- 每次窗口尺寸变化或绘制前,获取当前窗口的像素宽度
构建校正变换矩阵
- 在平移、缩放、旋转变换之前,先应用宽高比校正。2D场景下的校正矩阵(仅缩放垂直轴)如下:
mat4 correction_matrix = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, aspect_ratio, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - 变换顺序需遵循:校正 → 旋转 → 平移 → 缩放 → 投影,最终MVP矩阵为:
projection * scale * translation * rotation * correction * model
- 在平移、缩放、旋转变换之前,先应用宽高比校正。2D场景下的校正矩阵(仅缩放垂直轴)如下:
适配交互逻辑
- 鼠标平移、缩放操作需基于校正后的逻辑空间计算,保证交互手感一致。例如鼠标拖动的位移转换:
float dx = mouse_delta_x / w * 2.0f; // 原NDC水平位移 float dy = mouse_delta_y / h * 2.0f * aspect_ratio; // 校正后的垂直位移
- 鼠标平移、缩放操作需基于校正后的逻辑空间计算,保证交互手感一致。例如鼠标拖动的位移转换:
效果验证
绘制水平方向从(-1,0)到(1,0)的线段,其物理长度为屏幕宽度的一半;旋转90度后,线段变为从(0,-1/aspect_ratio)到(0,1/aspect_ratio),物理长度与原水平线段一致,超出原NDC垂直范围(-1到1)的部分会被自动裁剪。
内容的提问来源于stack exchange,提问作者DavidH
相关产品推荐
相关产品推荐

