glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float)width / (float)height;
glOrtho(-aspect, aspect, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
更新:解释发生的事情
OpenGL是一个状态机,在OpenGL-2.1及以下版本中维护一组变换矩阵。一个顶点↑v首先与modelview矩阵相乘,得到一个眼坐标顶点↑v',用于光照计算。然后↑v'乘以projection矩阵,达到所谓的剪裁空间↑v'',在这里(名称暗示)执行剪裁操作(或者至少定义了它们的结果)。从剪裁空间到达所谓的“归一化设备坐标”(NDC),通过计算↑v#{x,y,z,w} = ↑v{x,y,z,w}/↑v_w。
↑v#被定义为 [-1 … 1] 范围内,并映射到填充所选的视口矩形。视口不影响变换矩阵!它只影响从NDC到窗口坐标的转换。
在上面的代码中,我将modelview矩阵设置为身份矩阵,即顶点按原样进入投影。投影本身是正交投影,将x值范围[-aspect...aspect]映射到[-1 … 1],将y值范围[-1…1]映射到[-1…1](即y没有变化)。因此,顶点通过窗口宽高比被转换为适合NDC到视口值范围的值。
那么我为什么要告诉你OpenGL是状态机呢?因为这意味着您可以随时切换投影和变换。因此,如果您需要渲染一个迷你地图,请不要试图在3D场景中放置它。只需为其切换视口和投影即可。通常,应该在绘制函数中设置所有渲染状态(也就是所有矩阵)。窗口事件处理程序(除了重新绘制处理程序)不应执行任何OpenGL操作。