使用OpenGL和SDL处理窗口大小调整 [英] Handling window resizing using OpenGL and SDL

查看:329
本文介绍了使用OpenGL和SDL处理窗口大小调整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我在程序中绘制并在应用程序窗口周围移动正方形的程序的代码,在调整应用程序窗口大小时遇到​​了麻烦.当我处理调整大小并相应地更改状态时,应该在调整大小之前绘制的屏幕上的所有内容都消失了.我不知道为什么,因为在调整窗口大小时,所有对象的内部坐标都没有更改.

From the code I have of a program that draws and moves a square around an application window, I'm having trouble when resizing the application window. When I handle a resize and alter states accordingly, everything on the screen that should be drawn and was before the resize vanishes. I have no idea why because none of the objects internal coordinates are changed during the window resizing.

我的问题是,任何人都可以指出正确的方向来解决我的问题.(代码可以很好地编译)

My question is can anyone point me in the right direction to solve my problem.(The code compiles fine)

void ResizeWindow()
{
    screen_width = event.resize.w;
    screen_height = event.resize.h;

    SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF);

    glViewport(0, 0, screen_width, screen_height);
    glMatrixMode(GL_PROJECTION);
    glOrtho(0, screen_width, 0, screen_height, -1, 1);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
}

主循环:

while (running == true)

{

    while(SDL_PollEvent(&event))

    {

        switch(event.type)

        {

            case SDL_VIDEORESIZE: ResizeWindow(); break; // resizing called here
            case SDL_QUIT: running = false; break;
            case SDL_KEYDOWN: square.Handle_Input(down); break;
            case SDL_KEYUP: square.Handle_Input(up); break;

        }

    }

    square.Move();
    square.Check_Collision();

    glClear(GL_COLOR_BUFFER_BIT);

    square.Draw();

    SDL_GL_SwapBuffers();

}

在调整窗口大小之前,一切运行正常.

It all runs perfectly until the window is resized.

推荐答案

我已经复制粘贴了您的代码,并且将逐行解释发生了什么.它不仅可以帮助您了解调整大小后屏幕为何变黑,而且还可以帮助您删除不需要的内容.

I've copy pasted your code and I'll explain what is going on line by line. It should help you see not only why the screen is going blank after a resize, but also help you remove stuff that you don't really need.

void ResizeWindow()
{

接下来的几行很好!您已经从resize事件中获得了新的屏幕宽度和高度.我假设您现在可以在您的代码中访问该事件.

These next lines are good! You've obtained the new screen width and height from the resize event. I'm assuming that the event is accessible at this point in your code.

    screen_width = event.resize.w;
    screen_height = event.resize.h;

我怀疑您需要此呼叫SDL_SetViedoMode.我希望只能在设置OpenGL窗口时使用它.我目前没有使用SDL的经验,所以不能确定.我确实对文档进行了快速查找,这似乎支持按我期望的方式使用它.

I doubt you need this call to SDL_SetViedoMode. I'd expect it to be used only while setting up the OpenGL window. I have no experience with using SDL currently, so I can't be certain. I did do a quick look up of the documentation and that seems to support using it the way I expected.

SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF);

现在,我们来了解有趣的GL东西.您已经调整了视口的大小,这是必需的.

Now we get to the interesting GL stuff. You've resized the viewport, which is necessary.

    glViewport(0, 0, screen_width, screen_height);

现在,您正在制作一个新的投影矩阵以保持纵横比(除非我弄错了).您已切换矩阵模式并设置了正交投影矩阵,这很明智.

Now, you're making a new projection matrix to maintain the aspect ration (unless I'm mistaken). You've switched the matrix mode and set up an Orthographic projection matrix, which is sensible.

    glMatrixMode(GL_PROJECTION);
    glOrtho(0, screen_width, 0, screen_height, -1, 1);

现在,您将投影矩阵设置为Identity,覆盖旧的OpenGL投影矩阵,并撤消所做的所有出色工作.这就是屏​​幕变黑的原因.

Now, you set the projection matrix to identity, overwriting the old OpenGL projection matrix and undoing all the good work you did. This is the reason the screen went blank.

    glLoadIdentity();

现在,您切换到模型视图矩阵并将其设置为identity,只要您在其他地方正确设置了它,就没有必要了.

Now, you switch to the model-view matrix and set it to identity, which isn't really necessary, so long as you are setting it correctly elsewhere.

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

我怀疑您是否真的需要下一行.无论如何,为什么要在调整大小后清除屏幕?您确实想重新绘制它,但是我确定您的绘制函数将清除屏幕并绘制刷新完成后将自动调用的对象.

I doubt you really need this next line. Why would you want to clear the screen after a resize, anyway? You do want to redraw it, but I'm sure your draw function will clear the screen and draw the object that will be called automatically after the refresh is done.

    glClear(GL_COLOR_BUFFER_BIT);

您绝对不需要第二次将当前的模型视图矩阵重新设置为身份. OpenGL仍处于模型视图模式,该矩阵已设置为恒等!请记住,OpenGL是状态机!

And you definitely don't need to re-set the current model-view matrix to identity for a second time. OpenGL is still in model-view mode and that matrix was already set to identity! Remember that OpenGL is a state machine!

    glLoadIdentity();
}

这篇关于使用OpenGL和SDL处理窗口大小调整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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