Search code examples
c++openglsdlscreen-resolution

Changing resolution in OpenGL doesn't change the actual size of textures drawn


I have an OpenGL application using SDL, and I'm experiencing strange behavior when resizing a window. For example, here is a normal looking window at 1400x900: Normal resolution

If I increase the resolution to 1600x900, I get black bars with the screen size being effectively the same: Higher resolution

If I reduce the resolution to 1280x1024, I only get a part of the image: Lower resolution

However, if I exit the application and restart it manually, the application behaves as normal with the image being drawn at the correct size. The numbers here are for examples, the problem remains no matter what the initial and final resolutions.

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

The Reset() function is called whenever I need to change resolution. Please help me solve this problem.


Solution

  • My guess is that you need glViewport in your reset function.