У меня есть приложение OpenGL, использующее SDL, и я испытываю странное поведение при изменении размера окна. Например, вот нормально выглядящее окно с разрешением 1400×900:
Если я увеличу разрешение до 1600×900, я получу черные полосы с размером экрана, который будет практически одинаковым:
Если я уменьшу разрешение до 1280×1024, я получу только часть изображения:
Однако, если я выйду из приложения и перезапущу его вручную, приложение будет работать как обычно с изображением, нарисованным в правильном размере. Цифры здесь приведены для примера, проблема остается вне зависимости от того, какие исходные и окончательные решения.
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 () вызывается всякий раз, когда мне нужно изменить разрешение. Пожалуйста, помогите мне решить эту проблему.
Я думаю, что вам нужно glViewport
в вашей функции сброса.
Других решений пока нет …