2

我有一个使用 SDL 的 OpenGL 应用程序,并且在调整窗口大小时遇到​​了奇怪的行为。例如,这是一个 1400x900 的正常外观窗口: 正常分辨率

如果我将分辨率提高到 1600x900,我会看到屏幕尺寸实际上相同的黑条: 更高的分辨率

如果我将分辨率降低到 1280x1024,我只会得到图像的一部分: 较低的分辨率

但是,如果我退出应用程序并手动重新启动它,应用程序将正常运行,图像以正确的大小绘制。这里的数字是示例,无论初始和最终解决方案如何,问题仍然存在。

void App :: Load()
{
    int music = 100, effects = 100;

    XMLDoc settings("res/settings.xml");
    if(settings.ready())
    {
        rapidxml::xml_node<char> *node = settings.Doc()->first_node("settings");
        if(NodeValid(node))
        {
            if(NodeValid("screen",node))
                gScreenSettings.Load(node->first_node("screen"));

            if(NodeValid("volume",node))
            {
                rapidxml::xml_node<char> *volnode = node->first_node("volume");
                LoadNum(music,"music",volnode);
                LoadNum(effects,"effects",volnode);
            }

            gFilePath.Load(node->first_node("paths"));
        }
    }

    //Start the sound subsystem
    pyrodactyl::music::gMusicManager.Init(music, effects);
}

bool App :: Init(bool load)
{
    //Load all SDL subsystems and the TrueType font subsystem
    if( SDL_Init( SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) == -1 || TTF_Init() == -1)
    {
        fprintf(stderr,"Couldn't initialize SDL :(");
        return false;
    }

    if(load)
        Load();

    //Set the window caption
    SDL_WM_SetCaption("Unrest", "Unrest");

    //Set the window icon
    SDL_Surface *iconimage = SDL_LoadBMP(gFilePath.icon.c_str());
    Uint32 colorkey = SDL_MapRGB(iconimage->format, 255, 0, 255);
    SDL_SetColorKey(iconimage, SDL_SRCCOLORKEY, colorkey);
    SDL_WM_SetIcon(iconimage,NULL);

    //Initialize the music thread
    if(music == NULL)
        music = SDL_CreateThread(MusicThread, NULL);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,4);
    SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,1);

    //Set keyboard repeat rate
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY/4, SDL_DEFAULT_REPEAT_INTERVAL);

    //Store the default desktop values before starting our own screen
    gScreenSettings.desktop.w = SDL_GetVideoInfo()->current_w;
    gScreenSettings.desktop.h = SDL_GetVideoInfo()->current_h;

    //Set up the screen
    screen = SDL_SetVideoMode(gScreenSettings.cur.w, gScreenSettings.cur.h, gScreenSettings.bpp, gScreenSettings.videoflags);
    if(screen == NULL)
        return false;

    // initialize GLEW
    GLenum status = glewInit();
    if (status != GLEW_NO_ERROR)
    {
        fprintf(stderr, "Failed to initialize GLEW %d: %s\n", status, glewGetErrorString(status));
        return false;
    }

    //Initialize and load input
    pyrodactyl::input::gInput.Init();
    pyrodactyl::input::gInput.Load(gFilePath.controls);

    //Enable 2d textures
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_ARB_texture_non_power_of_two);

    //Enable transparency in textures, set the blend function
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glStencilOp(GL_KEEP,GL_REPLACE,GL_REPLACE);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearStencil(0);

    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(0.0f, gScreenSettings.cur.w, gScreenSettings.cur.h, 0.0f, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    //Disable the SDL stock cursor
    SDL_ShowCursor(SDL_DISABLE);

    //Enable Unicode for text input in text area
    SDL_EnableUNICODE( SDL_ENABLE );

    //Seed the random function
    srand(static_cast<unsigned int>(time(NULL)));

    //Apply vsync settings
    gScreenSettings.Vsync();

    return true;
}

void App :: Reset(bool load)
{
    using namespace pyrodactyl::image;

    //Delete stuff
    gImageManager.Quit();
    pyrodactyl::text::gTextManager.Reset();
    gLoadScreen.Quit();

    //Reload stuff
    Init(load);
    gLoadScreen.Load();
    gImageManager.Init();
    gImageManager.tileset.Reload();
}

每当我需要更改分辨率时,都会调用 Reset() 函数。请帮我解决这个问题。

4

1 回答 1

6

我的猜测是您需要glViewport重置功能。

于 2013-09-04T22:37:23.317 回答