如何在调整窗口大小时保持SDL窗口中的OpenGL视区不变? [英] How to keep the OpenGL viewport in an SDL window stationary when a window is resized?

查看:11
本文介绍了如何在调整窗口大小时保持SDL窗口中的OpenGL视区不变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含OpenGL视区的SDL窗口。当用户通过拖动窗口边缘来调整窗口大小时,我希望(1)展开视区以填充窗口,(2)使视区的内容保持不变。

例如:

------------------------
|          |           |
|  <------ |           |
|          |        X  |
|  <------ |           |
|          |           |
------------------------

如果进一步向左拖动窗口的左边缘,则OpenGL视口中的对象X应保持静止。

我发现我对SDL_VIDEORESIZE事件调用的代码不仅没有做到这一点,而且还导致了一些可怕的闪烁:

SDL_FreeSurface(window);
window = SDL_SetVideoMode(_w, _h, 32, SDL_OPENGL | SDL_RESIZABLE);

glViewport(0, 0, _w, _h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

const double w_2 = _w/2.0;
const double h_2 = _h/2.0;

gluOrtho2D(-w_2, w_2, -h_2, h_2);

// adjust model matrix
const double s_cosT = _scale*cos(_theta);
const double s_sinT = _scale*sin(_theta);

model[ 0] =  s_cosT;
model[ 1] =  s_sinT;
model[ 4] = -s_sinT;
model[ 5] =  s_cosT;
model[12] =  s_cosT*_x - s_sinT*_y;
model[13] =  s_sinT*_x + s_cosT*_y;

glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(model);

调整窗口大小时,此代码的作用似乎是将位于旧视区中心的内容转换为位于新视区中心的内容。当使用GLUT而不是SDL时,代码的行为与我预期的一样-使用GLUT时,通过拖动边缘来调整窗口大小不会导致视区的内容重新居中。

造成这种差异的原因是什么?我如何修复它?

推荐答案

执行此操作的唯一方法是也让视图矩阵随窗口一起移动。这意味着,除了在调整大小时更改变换矩阵外,还必须在单击并拖动窗口时对其进行调整。为了演示移动窗口和重复调整大小的等价性,考虑一下如果进行一系列增量大小调整会发生什么:

|---------------|                   1.  Starting window

        |-------|                   2.  Resize left edge

        |---------------|           3.  Resize right edge

因此,为了获得所需的行为,您应该在每次窗口移动/调整大小时(或者在绘制所有内容的帧的开头)将您的glOrtho2D矩阵设置为下列值:

int wind_x, wind_y;
SDL_GetWindowPosition(window, &wind_x, &wind_y);
gluOrtho2D(wind_x, wind_x + w, wind_y, wind_y + h);

这篇关于如何在调整窗口大小时保持SDL窗口中的OpenGL视区不变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆