I want to resize form

Hi. I’m ko.

I started development using SDL.
I want to use the window size change event, but it doesn’t work normally.
The image is displayed using ffmpeg, but when the size is changed, the image does not move.

When ‘render’ and ‘texture’ are re-generated, it works normally.

However, I think ‘renderer’, ‘texture’ and regenerating is like the wrong way.
I have in some way images again.

I’ll put the sauce on top.
I would appreciate it if you could let me know what’s wrong.

            while (SDL.SDL_PollEvent(out SDL.SDL_Event e) == 1)
            {
                if (e.type == SDL.SDL_EventType.SDL_WINDOWEVENT)
                {
                    switch (e.window.windowEvent)
                    {
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
                            SDLEvent = true;
                            break;
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED:
                            SDL.SDL_DestroyTexture(texture);
                            SDL.SDL_DestroyRenderer(renderer);
                            texture = IntPtr.Zero;
                            renderer = IntPtr.Zero;
                            renderer = SDL.SDL_CreateRenderer(window, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL.SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC);
                            texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_IYUV, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, this.Width, this.Height);
                            break;
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_EXPOSED:
                            SDLEvent = false;
                            break;
                    }
                }
            }

Ok, first of all, your while loop’s condition should be > 0 not == 1, since you can have more than one event in the queue. As it currently stands, if you have two or more events in the queue your while loop doesn’t execute.

Second, yeah, you don’t need to destroy and recreate the renderer. You’ll probably need to recreate the texture if its pixels need to be 1:1 with the on-screen pixels.

As to why it stays in the top-left corner, we’d have to see your drawing code.

1 Like

Thanks for your reply.

I apply your advice.
But… Same Issue.

This is my source.

I’ll be waiting for your advice.
I’m so thankful.

private void SetDrawImage(byte[] ImageBytes, int Width, int Height)
{
try
{
if (ImageBytes == null || ImageBytes.Length == 0)
return;

            if (window == IntPtr.Zero)
                return;

            if (renderer == IntPtr.Zero)
                return;

            if (texture == IntPtr.Zero)
                return;

            while (SDL.SDL_PollEvent(out SDL.SDL_Event e) > 0)
            {
                if (e.type == SDL.SDL_EventType.SDL_WINDOWEVENT)
                {
                    switch (e.window.windowEvent)
                    {
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
                            SDLEvent = true;
                            break;
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED:
                            SDL.SDL_DestroyTexture(texture);
                            SDL.SDL_DestroyRenderer(renderer);
                            texture = IntPtr.Zero;
                            renderer = IntPtr.Zero;
                            renderer = SDL.SDL_CreateRenderer(window, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL.SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC);
                            texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_IYUV, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, this.Width, this.Height);
                            break;
                        case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_EXPOSED:
                            SDLEvent = false;
                            break;
                    }
                }
            }

            if (SDLEvent)
                return;


            SDL.SDL_Rect sdl_rect = new SDL.SDL_Rect() { x = 0, y = 0, w = Width, h = Height };
            unsafe
            {
                fixed (byte* p = ImageBytes)
                {
                    IntPtr bytesPtr = IntPtr.Zero;

                    bytesPtr = new IntPtr(p);

                    if (bytesPtr == IntPtr.Zero)
                        return;
                    
                    if (SDL.SDL_UpdateTexture(texture, ref sdl_rect, bytesPtr, Width) != 0)
                    {
                        SDLErrMsg = SDL.SDL_GetError();
                        return;
                    }
                }
            }

            if (SDL.SDL_RenderClear(renderer) != 0)
            {
                SDLErrMsg = SDL.SDL_GetError();
                return;
            }

            if (SDL.SDL_RenderCopy(renderer, texture, IntPtr.Zero, IntPtr.Zero) != 0)
            {
                SDLErrMsg = SDL.SDL_GetError();
                return;
            }

            SDL.SDL_RenderPresent(renderer);
        }
        catch (Exception)
        {

        }
    }

So that’s kind of a weird way of structuring things. Does the source image’s size change when the window is resized? Or are you trying to just stretch the source image to be the size of the window?

I don’t really see where you’re actually updating the size when the window resize event is seen. All I see is you destroying the old renderer and image, and then making a new renderer and image that’s the old size.

Also, why are you exiting when a non-resize event occurs? What happens when there’s a non-resize event in the queue before a resize event?

1 Like

I’d change it to something like:

// put this in your main loop, not in SetDrawImage()
// in C++, because I don't know Java or whatever language you used in your example

// This assumes you're just trying to get an image that's always the same size (like from a video)
// to fill the window

while(running) {
	bool windowResized = false;

	SDL_Event event;
	while(SDL_PollEvent(&event) > 0) {
		switch(event.type) {
			case SDL_WINDOWEVENT:
				switch(event.window.event) {
					case SDL_WINDOWEVENT_RESIZED:
						this->windowWidth = event.window.data1;
						this->windowHeight = event.window.data2;
						// deal with the actual resizing later
						windowResized = true;
						break;
				}
				break;
			case SDL_QUIT:
				running = false;
				break;
			// test for more event types if you want to
		}
	}

	// Put anything that cares about the window being resized here
	// You *DON'T* need to recreate the renderer or the texture

	if(textureContentsNeedToBeUpdated) {
		// Update the texture contents here, like if it's time to show a new video frame
		textureContentsNeedToBeUpdated = false;
	}

	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer);

	SDL_RenderCopy(renderer, texture, nullptr, nullptr);

	SDL_RenderPresent(renderer);
}
1 Like

Your help is being helpful to me. I used C#.
I’m way has been a buffer and height, width outside the function is how.
The information functions and thread out of action, ffmpeg the parameters of the information function after receiving a way that conjures images through the application for use.

The images that render the work. and add the images on texture.

I check my source. I find SDL ErrMsg.
’ Reset(): INVALIDCALL ’

This error message is sent after SDL_WINDOWEVENT_RESIZED event. After SDL_WINDOWEVENT_EXPOSED,

It occurs in SDL_RenderPresent.

Error messages are not returned from SDL_UpdateTexture, SDL_RenderClean, and SDL_RenderCopy.

I’m sorry but I have no idea what you’re trying to say here. If all you’re trying to do is make a video frame take up the whole window, you shouldn’t need to do anything regarding messing with resize events or recreating the renderer or texture, just draw your texture with SDL_RenderCopy(renderer, texture, NULL, NULL) (or whatever the C# equivalent is).

I wouldn’t be surprised if this has something to do with the fact that you’re destroying and recreating the renderer and texture every resize event (at least, the ones you’re handling).

1 Like