[SDL2] Resize issues

I have some issue when resizing window, under Windows I have not repaint and under Linux I have flickers like one frame on two.

Under linux, when I remove double-buffering flickers disappears.

I think you’re supposed to repaint on resizing always since the
display contents aren’t guaranteed to be there anymore. If they stay
there it’s pure coincidence and you shouldn’t rely on it.

2013/3/17, Flamaros <flamaros.xavier at gmail.com>:> I have some issue when resizing window, under Windows I have not repaint and

under Linux I have flickers like one frame on two.

Under linux, when I remove double-buffering flickers disappears.

Sik wrote:

I think you’re supposed to repaint on resizing always since the
display contents aren’t guaranteed to be there anymore. If they stay
there it’s pure coincidence and you shouldn’t rely on it.

2013/3/17, Flamaros <@Flamaros>:

I have some issue when resizing window, under Windows I have not repaint and
under Linux I have flickers like one frame on two.

Under linux, when I remove double-buffering flickers disappears.


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

Yes I had try to force repaint, by calling explicitly my draw method on resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

Yes I had try to force repaint, by calling explicitly my draw method on
resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

I’m quite sure yoy don’t need to redraw on the resize event, I think it’s
enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you’ll receive once the
resize is occurred.

You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get your
new surface size.>

Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150 Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)

Gabriele Greco wrote:

Yes I had try to force repaint, by calling explicitly my draw method on resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

I’m quite sure yoy don’t need to redraw on the resize event, I think it’s enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you’ll receive once the resize is occurred.

You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get your new surface size.


Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150 ?Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)

Add a draw call on SDL_WINDOWEVENT_EXPOSE event don’t change anything.
You may notice I am using Opengl and after the SDL_PollEvent loop I always call my draw method.

Maybe try to draw, swap buffers, then draw again? If disabling
double-buffering helped, then this is probably what you need to do.

Jonny DOn Mon, Mar 18, 2013 at 3:14 PM, Flamaros <flamaros.xavier at gmail.com> wrote:

**

Gabriele Greco wrote:

Quote:

Yes I had try to force repaint, by calling explicitly my draw method on
resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

I’m quite sure yoy don’t need to redraw on the resize event, I think it’s
enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you’ll receive once the
resize is occurred.

You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get
your new surface size.


Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150 Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)

Add a draw call on SDL_WINDOWEVENT_EXPOSE event don’t change anything.
You may notice I am using Opengl and after the SDL_PollEvent loop I always
call my draw method.


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

Don’t forget to call glViewport also, with the new size.On 03/18/2013 12:21 PM, Jonathan Dearborn wrote:

Maybe try to draw, swap buffers, then draw again? If disabling double-buffering helped, then this is probably what you need to do.

Jonny D

On Mon, Mar 18, 2013 at 3:14 PM, Flamaros <flamaros.xavier at gmail.com <mailto:flamaros.xavier at gmail.com>> wrote:

__



Gabriele Greco wrote:	




Quote:	

Yes I had try to force repaint, by calling explicitly my draw method on resize event with no effect. I know it's necessary to do it with win32 API.
I really need that feature as I am not doing a game.

	



I'm quite sure yoy don't need to redraw on the resize event, I think it's enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you'll receive once the resize is occurred.


You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get your new surface size.



-- 
Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150  Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)
	





Add a draw call on SDL_WINDOWEVENT_EXPOSE event don't change anything.
You may notice I am using Opengl and after the SDL_PollEvent loop I always call my draw method.

_______________________________________________
SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

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


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

Certainly, for the moment I call glViewport each frame.

Forest Hale wrote:> Don’t forget to call glViewport also, with the new size.

On 03/18/2013 12:21 PM, Jonathan Dearborn wrote:

Maybe try to draw, swap buffers, then draw again? If disabling double-buffering helped, then this is probably what you need to do.

Jonny D

On Mon, Mar 18, 2013 at 3:14 PM, Flamaros <@Flamaros mailto:Flamaros> wrote:

__

Gabriele Greco wrote:

Quote:

Yes I had try to force repaint, by calling explicitly my draw method on resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

I’m quite sure yoy don’t need to redraw on the resize event, I think it’s enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you’ll receive once the resize is occurred.

You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get your new surface size.


Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150 Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)

Add a draw call on SDL_WINDOWEVENT_EXPOSE event don’t change anything.
You may notice I am using Opengl and after the SDL_PollEvent loop I always call my draw method.


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


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


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


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

Certainly, for the moment I call glViewport each frame.

I’ll investigate more on this issue later, for the moment I have some points with a higher priority to work.

Thank for your help, everybody.

Forest Hale wrote:> Don’t forget to call glViewport also, with the new size.

On 03/18/2013 12:21 PM, Jonathan Dearborn wrote:

Maybe try to draw, swap buffers, then draw again? If disabling double-buffering helped, then this is probably what you need to do.

Jonny D

On Mon, Mar 18, 2013 at 3:14 PM, Flamaros <@Flamaros mailto:Flamaros> wrote:

__

Gabriele Greco wrote:

Quote:

Yes I had try to force repaint, by calling explicitly my draw method on resize event with no effect. I know it’s necessary to do it with win32 API.
I really need that feature as I am not doing a game.

I’m quite sure yoy don’t need to redraw on the resize event, I think it’s enough to redraw on the SDL_WINDOWEVENT_EXPOSE that you’ll receive once the resize is occurred.

You have to use the resize event (SDL_WINDOWEVENT_RESIZED) only to get your new surface size.


Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150 Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)

Add a draw call on SDL_WINDOWEVENT_EXPOSE event don’t change anything.
You may notice I am using Opengl and after the SDL_PollEvent loop I always call my draw method.


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


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


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


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

I am back on this particular issue since I made progress on other primary parts.

I add some outputs to be able to understand what is happening. While I am resizing the window I don’t get the “SDL_PollEvent” text in the console, it’s only when I release the mouse button that all “SDL_WINDOWEVENT_RESIZED” messages are printed.

For the move event I receive only once when I release the mouse button.

Here is my loop code :

Code:

while (!mQuit)
{
	SDL_Event	event;
	while (SDL_PollEvent(&event) && !mQuit)
	{
		writeln("SDL_PollEvent");
		switch (event.type)
		{
			case SDL_QUIT:
				mQuit = true;
				break;
			case SDL_WINDOWEVENT:
				switch (event.window.event)
				{
					case SDL_WINDOWEVENT_SHOWN:	// Called at window creation (need update opengl context size)
						writeln("SDL_WINDOWEVENT_SHOWN");
						if (event.window.windowID in GuiApplication.mWindows)
							GuiApplication.mWindows[event.window.windowID].setSize(GuiApplication.mWindows[event.window.windowID].size());
						break;
					case SDL_WINDOWEVENT_HIDDEN:
						writeln("SDL_WINDOWEVENT_HIDDEN");
						break;
					case SDL_WINDOWEVENT_EXPOSED:
						writeln("SDL_WINDOWEVENT_EXPOSED");
						if (event.window.windowID in GuiApplication.mWindows)
							GuiApplication.mWindows[event.window.windowID].onPaint();
						break;
					case SDL_WINDOWEVENT_MOVED:
						writeln("SDL_WINDOWEVENT_MOVED");
						if (event.window.windowID in GuiApplication.mWindows)
							GuiApplication.mWindows[event.window.windowID].setPosition(Vector2s32(event.window.data1, event.window.data2));
						break;
					case SDL_WINDOWEVENT_RESIZED:
						writeln("SDL_WINDOWEVENT_RESIZED");
						if (event.window.windowID in GuiApplication.mWindows)
							GuiApplication.mWindows[event.window.windowID].setSize(Vector2s32(event.window.data1, event.window.data2));
						break;
				}
				break;
		}
	}
	if (!mQuit)
		foreach (Window window; mWindows)
			window.onPaint();
}
return 0;

}

On Windows, DispatchMessage() enters into a loop for as long as you’re holding down the mouse button when you begin resizing your window.
Within the framework of the SDL API, there is no correction*. It would require rendering within the Window Procedure, which is impossible.

On Linux, it seems to be an issue of X11 destroying the OpenGL buffer contents during resize, which means it is probably not something that a client program can control or properly account for. I’ve never seen a program using OpenGL for graphics on Linux resize without some flickering.

    • Shy of some sort of mechanism to jump out of the Windows Procedure and then back in again as if no jump had occurred, such as maybe a Fiber or explicit context switching, but this would probably cause some issues too.------------------------
      Nate Fries

Nathaniel J Fries wrote:

On Windows, DispatchMessage() enters into a loop for as long as you’re holding down the mouse button when you begin resizing your window.
Within the framework of the SDL API, there is no correction*. It would require rendering within the Window Procedure, which is impossible.

On Linux, it seems to be an issue of X11 destroying the OpenGL buffer contents during resize, which means it is probably not something that a client program can control or properly account for. I’ve never seen a program using OpenGL for graphics on Linux resize without some flickering.

    • Shy of some sort of mechanism to jump out of the Windows Procedure and then back in again as if no jump had occurred, such as maybe a Fiber or explicit context switching, but this would probably cause some issues too.

I don’t have issue like that with DispatchMessage(). Currently I am using SDL under Windows, because I try to share the maximum code between platforms.

My application loop :

Code:

int execute()
{
MSG msg;

while (!mQuit)
{
	while (PeekMessageA(&msg, null, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessageA(&msg);
	}
		foreach (Window window; mWindows)
		window.onPaint();
}
return msg.wParam;

}

The Wndproc function :

Code:

extern(Windows) LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
{
Vector2s32 size;
Vector2s32 position;
bool state;

try
{
	switch (message)
	{
		case WM_CREATE:
			break;
		case WM_MOVE:		// position de cliet arena
			break;
		case WM_MOVING:		// position de la fenetre
			position.x = LOWORD(lParam);
			position.y = HIWORD(lParam);
			if (hWnd in GuiApplication.mWindows)
			{
				GuiApplication.mWindows[hWnd].setPosition(position);
				GuiApplication.mWindows[hWnd].onPaint();
			}
			return 0;
		case WM_SIZE:
			writeln("WM_SIZE");
			size.x = LOWORD(lParam);
			size.y = HIWORD(lParam);
			if (hWnd in GuiApplication.mWindows)
			{
				GuiApplication.mWindows[hWnd].setSize(size);
				GuiApplication.mWindows[hWnd].onPaint(); // WM_PAINT occurs before WM_SIZE
			}
			return 0;
		case WM_COMMAND:
			break;
		case WM_PAINT:
			// Certainly not necessary because paint is always call
			if (hWnd in GuiApplication.mWindows)
				GuiApplication.mWindows[hWnd].onPaint();
			break;
		case WM_DESTROY:
			if (hWnd in GuiApplication.mWindows)
				GuiApplication.mWindows[hWnd].destroy();
			PostQuitMessage(0);
			break;

			// TODO manage the WM_ACTIVATE event for fullscreen
		default:
			break;
	}
}
catch (Throwable e)
{
	collectException(MessageBoxA(null, e.toString().toStringz, "Error", MB_OK | MB_ICONEXCLAMATION));	// PS: string.toString() method is not nothrow
}
return DefWindowProcA(hWnd, message, wParam, lParam);

}

With this code “WM_SIZE” is printed during the window resize not only when I release the mouse button.

You may have a look to the answer 2 of this stackoverflow question :