开发者

How to keep the OpenGL viewport in an SDL window stationary when a window is resized?

I have an SDL window containing an OpenGL viewport. When the user resizes the window by dragging a window edge, I'd like for (1) the viewport to expand to fill the window, and (2) for the contents of the viewport to remain stationary.

For example:

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

If the left edge of the window is dragged further left, then the object X in the OpenGL viewport should remain stationary.

I'm finding that the code I'm calling on SDL_VIDEORESIZE events is not only not doing this, but also causing some awful flickering:

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);

What this code seems to do when a window is resized is to translate what was at the center of the old viewport to be at the center o开发者_如何学编程f the new viewport. The same code behaved as I expected when used with GLUT instead of SDL---with GLUT, resizing the window by dragging the edges did not cause the contents of the viewport to recenter.

What accounts for this difference? How can I fix it?


The only way to do this is to also have view matrix move with the window. This means that in addition to changing your transformation matrix when you resize, you must also adjust it when you click and drag the window. To demonstrate the equivalence of moving a window and repeated resizing, consider what would happen if you do a bunch of incremental resizings like so:

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

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

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

Thus, to get the desired behavior you should set your gluOrtho2D matrix to the following value every time your window moves/gets resized (or alternatively at the start of the frame where you draw everything):

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜