我正在尝试为一些纹理渲染设置我的OpenGL视图。根据论坛上的一些建议,我将视口和矩阵设置如下:
首先,我尝试计算可以使用的屏幕宽度和高度,同时保持图像的纵横比:
void resize(int w, int h)
{
float target_aspect_ratio = image_width / image_height;
width = w;
height = (int)(width / target_aspect_ratio + 0.5f);
if (height > h) {
height = h;
width = (int)(height * target_aspect_ratio + 0.5f);
}
off_x = (w - width)/2.f;
off_y = (h - height)/2;
// I want to center my image. So I have these offsets
glViewport(off_x, off_y, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, 0.0f, 1.0f);
现在,当我想要渲染纹理时,我会这样做:
void paint()
{
// texture binding etc.
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(width, 0);
glTexCoord2f(1, 1); glVertex2f(width, height);
glTexCoord2f(0, 1); glVertex2f(0, height);
}
但是,这并未按预期显示图像。当我调整屏幕大小时,它不会保持纵横比。这几乎就像glViewport没有效果,我可以验证每次调整窗口大小时都会调用此函数。
更新
很奇怪。几乎好像这些调用没有效果。我甚至做了一些事情:
_off_x = _off_y = 0;
_width = 500;
_height = 500;
所以我希望视口是我屏幕的左下方框,但是基本上使用整个屏幕作为视口,正在绘制图像。
更新2:
好的,如果我打电话
glViewport(_off_x, _off_y, _width, _height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, _width, 0, _height, 0, 1);
在我的绘画活动中,它按预期工作!但是,我认为将它放入resize事件处理程序就足够了。
答案 0 :(得分:1)
在开始绘图之前,您需要将矩阵模式切换为GL_MODELVIEW。您不需要在每个帧的渲染函数中设置投影矩阵。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
这是我写的关于glMatrixMode()函数模式的详细分析: OpenGL glMatrixMode(GL_PROJECTION) vs glMatrixMode(GL_MODELVIEW)