Need to re-construct all the textures after resizing window?

I am now developing my game using SDL2. All pictures are store in textures.
The problem is that if I resize the window, it stops updating images.
I turns out I can fix this problem by re-create the renderer and all textures. However, this is not a easy work because the textures are managed in many classes and I need to write a lot of code to do the re-creation (and this method is not elegant).

Is there better ways to handle window resizing issue? Thanks in advance.

Which function are you using to resize the window, or is it user-resizable?
Which platform and renderer are you using?

Jonny D

Hi Jonny,
I tried both (i.e. use SDL_SetWindowSize or create window with SDL_WINDOW_RESIZABLE flag). Both have the same problem.
I am in Win7, using default renderer (should be hardware renderer).

Jonny D wrote:> Which function are you using to resize the window, or is it user-resizable? ?Which platform and renderer are you using?

Jonny D

I did some tests for this problem.
Test 1: blitting order: surface -> texture -> window. Then SDL2 can handle resize automatically. When window resizes, image resizes too.
code of test1:
int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer, _mainpic);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Test 2: blitting order: surface -> texture -> another texture -> window. Then SDL2 can not handle resize. When window resizes, image stops updating. If I drag the window to smaller size, the image will be cut to the window size (not zoom), and will not restore even when I drag the window to original size.
code of test2:

Code:

int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer, _mainpic);
SDL_Texture *tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderTarget(renderer, tex);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, tex, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Jonny D wrote:> Which function are you using to resize the window, or is it user-resizable? ?Which platform and renderer are you using?

Jonny D

you need to
(a) Destroy the render target texture
(b) Resize Window
© Re-create render target texture.

If that is not possible then
(a) Resize Window
(b) Destroy Render Target Texture
© Reset device (Calling SDL_Clear() + SDL_RenderPresent() will do this.
(d) Re-create render target
(e) Ready to go.
(f) Problems sometimes occur in Resetting Video device, it does not
always work.

On 2/19/2014 11:01 AM, RunningOn wrote:> I did some tests for this problem.

Test 1: blitting order: surface -> texture -> window. Then SDL2 can
handle resize automatically. When window resizes, image resizes too.
code of test1:
int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer, _mainpic);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Test 2: blitting order: surface -> texture -> another texture ->
window. Then SDL2 can not handle resize. When window resizes, image
stops updating. If I drag the window to smaller size, the image will
be cut to the window size (not zoom), and will not restore even when I
drag the window to original size.
code of test2:

Code:

int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer,
_mainpic);
SDL_Texture *tex = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderTarget(renderer, tex);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, tex, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Jonny D wrote:
Which function are you using to resize the window, or is it
user-resizable? Which platform and renderer are you using?

Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Pallav Nawani
Game Designer/CEO
http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming

It’s a headache to destroy all the render target textures because there are many. But it is achievable at least.
If no better solutions I will do this.
Thanks.

Pallav Nawani wrote:> you need to

(a) Destroy the render target texture
(b) Resize Window
© Re-create render target texture.

If that is not possible then
(a) Resize Window
(b) Destroy Render Target Texture
© Reset device (Calling SDL_Clear() + SDL_RenderPresent() will do this.
(d) Re-create render target
(e) Ready to go.
(f) Problems sometimes occur in Resetting Video device, it does not
always work.

Try the latest SDL2 Hg version. There seems to be a fix for this
particular problem. The driver tries to automatically create & destroy
the render target textures and reset the device, then sends an event:
SDL_RENDER_TARGETS_RESET

On 2/19/2014 11:01 AM, RunningOn wrote:> I did some tests for this problem.

Test 1: blitting order: surface -> texture -> window. Then SDL2 can
handle resize automatically. When window resizes, image resizes too.
code of test1:
int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer, _mainpic);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Test 2: blitting order: surface -> texture -> another texture ->
window. Then SDL2 can not handle resize. When window resizes, image
stops updating. If I drag the window to smaller size, the image will
be cut to the window size (not zoom), and will not restore even when I
drag the window to original size.
code of test2:

Code:

int sdltest() {
SDL_Window* window;
SDL_Renderer* renderer;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
if (!IMG_Init(IMG_INIT_PNG)) return 1;
window = SDL_CreateWindow(“test”, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, “linear”);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *_mainpic = IMG_Load(“somepic.png”);
SDL_Texture *_maintx = SDL_CreateTextureFromSurface(renderer,
_mainpic);
SDL_Texture *tex = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_FreeSurface(_mainpic);
SDL_Event ev;
while (true){
while (SDL_PollEvent(&ev))
if (ev.type == SDL_QUIT) return 0;
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderTarget(renderer, tex);
SDL_RenderCopy(renderer, _maintx, NULL, NULL);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, tex, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
return 0;
}

Jonny D wrote:
Which function are you using to resize the window, or is it
user-resizable? Which platform and renderer are you using?

Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Pallav Nawani
Game Designer/CEO
http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming

Thanks.
One more question, if the render targets are automatically re-created, what must I do to response SDL_RENDER_TARGETS_RESET ?

Pallav Nawani wrote:> Try the latest SDL2 Hg version. There seems to be a fix for this

particular problem. The driver tries to automatically create & destroy
the render target textures and reset the device, then sends an event:
SDL_RENDER_TARGETS_RESET

The textures are re-allocated but the image data in them is lost. You can
re-create the data in the render target texture when you get the event.

On Sat, Feb 22, 2014 at 5:12 PM, RunningOn wrote:> Thanks.

One more question, if the render targets are automatically re-created,
what must I do to response SDL_RENDER_TARGETS_RESET ?

Pallav Nawani wrote:

Try the latest SDL2 Hg version. There seems to be a fix for this
particular problem. The driver tries to automatically create & destroy
the render target textures and reset the device, then sends an event:
SDL_RENDER_TARGETS_RESET


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Pallav Nawani
IronCode Gaming Private Limited
Website: http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming
Mobile: 9997478768