SDL2全屏和渲染到纹理

SDL2 fullscreen and rendering to texture

本文关键字:纹理 SDL2      更新时间:2023-10-16

我使用的是一个名为UICanvas的类,这个类有一个纹理,子对象使用它来渲染。

我使用SDL_SetSendTarget来实现这一点,它运行得很好,但当我切换到全屏时,由于某种原因,整个屏幕都使用画布纹理作为屏幕纹理。这是一个错误,还是我做错了什么?

这是canvas类的draw函数,m_canvas是用于绘制子对象的纹理。

void UICanvas::draw( SDL_Renderer* onWhat, Uint32 deltaTime )
{
        /* Change rendering target to the canvas. */
        SDL_SetRenderTarget( onWhat, m_canvas );
        /* Fill with background color */
        Color old;
        SDL_GetRenderDrawColor( onWhat, &old.r, &old.g, &old.b, &old.a );
        SDL_SetRenderDrawColor( onWhat, m_color.r, m_color.g, m_color.b, m_color.a );
        SDL_RenderFillRect( onWhat, NULL );
        SDL_SetRenderDrawColor( onWhat, old.r, old.g, old.b, old.a );
        /* Draw child textures on the canvas. */
        drawChildren( onWhat, deltaTime );
        /* Reset to default rendering target */
        SDL_SetRenderTarget( onWhat, NULL );
        /* Position and render canvas */
        Point2Df abs( getAbsolutePosition() );
        Rectangle dest( static_cast<Sint32>( abs.x ), static_cast<Sint32>( abs.y ), m_width, m_height );
        SDL_RenderCopy( onWhat, m_canvas, NULL, &dest );
    }

每当我切换全屏时,整个屏幕都会变白。这是我用来切换全屏的功能:

void Application::toggleFullscreen()
{
        Uint32 flags( SDL_GetWindowFlags( GE_SYS.window ) );
        flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
        SDL_SetWindowFullscreen( GE_SYS.window, flags );
        SDL_DestroyRenderer( GE_SYS.renderer );
        GE_SYS.renderer = SDL_CreateRenderer( GE_SYS.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE );
        //SDL_SetRenderTarget( GE_SYS.renderer, NULL );
}

我对SDL还很陌生(不要介意SDL 1.2和SDL 2之间的任何细微差别),但如果我错了,我相信会有人(最终)纠正我。

从你发布的代码来看,每次使用"全屏桌面"模式切换全屏时,你似乎都在破坏和创建渲染器。这绝对不对。你也不应该强制使用特定的驱动程序(根据你的评论,强制使用OpenGL驱动程序似乎可以解决问题)。

相反,在我看来,你所需要做的就是更新窗口和/或逻辑渲染大小。

void Application::toggleFullscreen()
{
        Uint32 flags(SDL_GetWindowFlags(GE_SYS.window));
        flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
        SDL_SetWindowFullscreen(GE_SYS.window, flags);
        int w = 640, h = 480; // TODO: UPDATE ME! ;)
        if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)
        {
                SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
                SDL_RenderSetLogicalSize(GE_SYS.renderer, w, h);
        }
        else
        {
                SDL_SetWindowSize(GE_SYS.window, w, h);
        }
}

这种切换全屏的方法对我来说很有效,并且不需要一直创建和破坏渲染器(在切换时)。如果这不能完全解决问题,我提前道歉,但如果没有其他事情,这应该是朝着正确方向迈出的一步。