调整窗口大小时,如何将SDL窗口中的OpenGL视口保持静止?

时间:2011-06-24 22:30:28

标签: opengl sdl

我有一个包含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 个答案:

答案 0 :(得分:2)

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

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

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

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

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

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