Изменение разрешения в OpenGL не меняет фактический размер нарисованных текстур.

У меня есть приложение 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 () вызывается всякий раз, когда мне нужно изменить разрешение. Пожалуйста, помогите мне решить эту проблему.

2

Решение

Я думаю, что вам нужно glViewport в вашей функции сброса.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]