gpt4 book ai didi

macos - SDL2 窗口在调整大小时变黑

转载 作者:行者123 更新时间:2023-12-02 01:16:47 28 4
gpt4 key购买 nike

我已经开始使用 SDL2,但缺乏经验。我正在Mac系统上工作。几乎一切都很好,但我有一个问题,当调整可调整大小的窗口的大小时,拖动 handle 时,窗口会变黑,我只能在释放后重新绘制它。我已经检查过,在调整窗口大小时,没有生成任何事件,并且我无法干扰或检测到这一点,因为事件循环只是暂停了。有什么可行的解决办法吗?

这是代码(几乎是处理调整大小事件教程的副本):

SDL_Event event;

SDL_Rect nativeSize;
SDL_Rect newWindowSize;

float scaleRatioW;//This is to change anything that might rely on something like mouse coords
float scaleRatioH; //(such as a button on screen) over to the new coordinate system scaling would create

SDL_Window * window; //Our beautiful window
SDL_Renderer * renderer; //The renderer for our window
SDL_Texture * backBuffer; //The back buffer that we will be rendering everything to before scaling up

SDL_Texture * ballImage; //A nice picture to demonstrate the scaling;

bool resize;

void InitValues(); //Initialize all the variables needed
void InitSDL(); //Initialize the window, renderer, backBuffer, and image;
bool HandleEvents(); //Handle the window changed size event
void Render(); //Switches the render target back to the window and renders the back buffer, then switches back.
void Resize(); //The important part for stretching. Changes the viewPort, changes the scale ratios

void InitValues()
{
nativeSize.x = 0;
nativeSize.y = 0;
nativeSize.w = 256;
nativeSize.h = 224; //A GameBoy size window width and height

scaleRatioW = 1.0f;
scaleRatioH = 1.0f;

newWindowSize.x = 0;
newWindowSize.y = 0;
newWindowSize.w = nativeSize.w;
newWindowSize.h = nativeSize.h;

window = NULL;
renderer = NULL;
backBuffer = NULL;
ballImage = NULL;

resize = false;
}

void InitSDL()
{
if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
//cout << "Failed to initialize SDL" << endl;
printf("%d\r\n", __LINE__);
}

//Set the scaling quality to nearest-pixel
if(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0") < 0)
{
//cout << "Failed to set Render Scale Quality" << endl;
printf("%d\r\n", __LINE__);
}

//Window needs to be resizable
window = SDL_CreateWindow("Rescaling Windows!",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
256,
224,
SDL_WINDOW_RESIZABLE);

//You must use the SDL_RENDERER_TARGETTEXTURE flag in order to target the backbuffer
renderer = SDL_CreateRenderer(window,
-1,
SDL_RENDERER_ACCELERATED |
SDL_RENDERER_TARGETTEXTURE);

//Set to blue so it's noticeable if it doesn't do right.
SDL_SetRenderDrawColor(renderer, 0, 0, 200, 255);

//Similarly, you must use SDL_TEXTUREACCESS_TARGET when you create the texture
backBuffer = SDL_CreateTexture(renderer,
SDL_GetWindowPixelFormat(window),
SDL_TEXTUREACCESS_TARGET,
nativeSize.w,
nativeSize.h);

//IMPORTANT Set the back buffer as the target
SDL_SetRenderTarget(renderer, backBuffer);

//Load an image yay
SDL_Surface * image = SDL_LoadBMP("Ball.bmp");

ballImage = SDL_CreateTextureFromSurface(renderer, image);

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

SDL_FreeSurface(image);
}

bool HandleEvents()
{
while(SDL_PollEvent(&event) )
{
printf("%d\r\n", __LINE__);
if(event.type == SDL_QUIT)
{
printf("%d\r\n", __LINE__);
return true;
}
else if(event.type == SDL_WINDOWEVENT)
{
if(event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{
resize = true;
printf("%d\r\n", __LINE__);
}
}

return false;
}
return false;
}

void Render()
{
SDL_RenderCopy(renderer, ballImage, NULL, NULL); //Render the entire ballImage to the backBuffer at (0, 0)
printf("%d\r\n", __LINE__);

SDL_SetRenderTarget(renderer, NULL); //Set the target back to the window

if(resize)
{
Resize();
resize = false;
}
printf("%d\r\n", __LINE__);

SDL_RenderCopy(renderer, backBuffer, &nativeSize, &newWindowSize); //Render the backBuffer onto the screen at (0,0)
SDL_RenderPresent(renderer);
SDL_RenderClear(renderer); //Clear the window buffer

SDL_SetRenderTarget(renderer, backBuffer); //Set the target back to the back buffer
SDL_RenderClear(renderer); //Clear the back buffer
printf("%d\r\n", __LINE__);

}

void Resize()
{
int w, h;
printf("%d\r\n", __LINE__);

SDL_GetWindowSize(window, &w, &h);

scaleRatioW = w / nativeSize.w;
scaleRatioH = h / nativeSize.h; //The ratio from the native size to the new size

newWindowSize.w = w;
newWindowSize.h = h;

//In order to do a resize, you must destroy the back buffer. Try without it, it doesn't work
SDL_DestroyTexture(backBuffer);
backBuffer = SDL_CreateTexture(renderer,
SDL_GetWindowPixelFormat(window),
SDL_TEXTUREACCESS_TARGET, //Again, must be created using this
nativeSize.w,
nativeSize.h);

SDL_Rect viewPort;
SDL_RenderGetViewport(renderer, &viewPort);

if(viewPort.w != newWindowSize.w || viewPort.h != newWindowSize.h)
{
//VERY IMPORTANT - Change the viewport over to the new size. It doesn't do this for you.
SDL_RenderSetViewport(renderer, &newWindowSize);
}
}

int main(int argc, char * argv[])
{
InitValues();
InitSDL();

bool quit = false;
printf("%d\r\n", __LINE__);

while(!quit)
{
printf("%d\r\n", __LINE__);
quit = HandleEvents();
Render();
}

return 0;
}

最佳答案

好吧,在与 SDL2 进行了一些斗争之后,我让它在 macOS 10.12 上运行。

问题是这样的:

  1. 例如,当您使用 SDL_PollEvent(&event) 轮询事件时,SDL2 会捕获调整大小事件并仅重新发送最后 3 个事件。
  2. 在此期间(您在调整区域大小上按下鼠标左键并按住鼠标),SDL_PollEvent 处于阻塞状态。

解决方法如下:

幸运的是,您可以使用 SDL_SetEventFilter 连接到事件处理程序。每次收到事件时都会触发此事件。因此,对于所有发生的调整大小事件。

因此,您可以做的是注册自己的事件过滤器回调,该回调基本上允许每个事件(通过返回 1),监听调整大小事件,并将它们发送到您的绘制循环。

示例:

//register this somewhere
int filterEvent(void *userdata, SDL_Event * event) {
if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_RESIZED) {
//convert userdata pointer to yours and trigger your own draw function
//this is called very often now
//IMPORTANT: Might be called from a different thread, see SDL_SetEventFilter docs
((MyApplicationClass *)userdata)->myDrawFunction();

//return 0 if you don't want to handle this event twice
return 0;
}

//important to allow all events, or your SDL_PollEvent doesn't get any event
return 1;
}


///after SDL_Init
SDL_SetEventFilter(filterEvent, this) //this is instance of MyApplicationClass for example

重要提示:请勿在 filterEvent 回调中调用 SDL_PollEvent,因为这会导致卡住事件出现奇怪的行为。 (例如调整大小有时不会停止)

关于macos - SDL2 窗口在调整大小时变黑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34967628/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com