简体   繁体   English

Linux中的SDL2空透明窗口

[英]SDL2 empty transparent window in Linux

Here is some sample SDL2 code I tried to run on my Linux computer running Ubuntu 18.04 with KDE Plasma Desktop Environment (I have multiple desktop environments installed in case it is relevant):这是我尝试在运行 Ubuntu 18.04 和 KDE Plasma 桌面环境的 Linux 计算机上运行的一些示例 SDL2 代码(我安装了多个桌面环境,以防万一):

#include<iostream>
#include<SDL2/SDL.h>

int main(int argc, char** argv)
{
    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        std::cerr << "SDL_Init() Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window* win = SDL_CreateWindow(
        "Hello world",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640,480,
        0
    );

    if(win == nullptr){
        std::cerr << "SDL_CreateWindow() Error: " << SDL_GetError() << std::endl;
        return 1;  
    }

    //Create and init the renderer
    SDL_Renderer* ren = SDL_CreateRenderer(win, -1, 0);
    if(ren == nullptr){
        std::cerr << "SDL_CreateRenderer() Error: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow(win);
        return 1;
    }

    //Render something
    SDL_RenderSetLogicalSize(ren,640,480);

    //Set colour of renderer
    SDL_SetRenderDrawColor(ren,255,0,0,255);

    //Clear the screen to the set colour
    SDL_RenderClear(ren);

    //Show all the has been done behind the scenes
    SDL_RenderPresent(ren);

    //Delay so that we can see what is on the screen
    SDL_Delay(5000);

    //Clean Up
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}

The red window that is supposed to appear appears only once when I run the program for the first time.当我第一次运行程序时,应该出现的红色窗口只出现一次。 All subsequent executions produce an empty transparent window with whatever is in the background.所有后续执行都会产生一个空的透明窗口,背景是任何东西。 The background image drags along with the window.背景图像随窗口一起拖动。

I have tried SDL_WINDOW_SHOWN flag in SDL_CreateWindow() as well as SDL_RENDER_ACCELERATED flag for SDL_CreateRenderer() .我已经尝试过SDL_WINDOW_SHOWN SDL_CreateWindow()中的SDL_RENDER_ACCELERATED标志以及SDL_CreateRenderer() SDL_RENDER_ACCELERATED标志。

The only way to produce the red screen again is to reboot the system.再次产生红屏的唯一方法是重新启动系统。

I even compiled and ran this with an IDE (CodeLite) and I still got the same results.我什至使用 IDE (CodeLite) 编译并运行它,但仍然得到相同的结果。

This particular question on SO shows similar problems.这个关于SO 的特定问题显示了类似的问题。 But the OP isn't using Linux and the problem isn't exactly the same.但是 OP 没有使用 Linux,问题也不完全相同。

Other posts on this website mention event processing but I haven't gotten that far.这个网站上的其他帖子提到了事件处理,但我还没有那么远。 If at all it is necessary, I would be grateful for some resources on it as the documentation doesn't explain much.如果有必要,我会很感激它的一些资源,因为文档没有解释太多。

Update :This program runs fine on another computer running Lubuntu 18.10.更新:该程序在另一台运行 Lubuntu 18.10 的计算机上运行良好。

Replace the SDL_Delay() (which blocks all event processing like notifying X11/Wayland & your window manager that your process is still alive) with a loop that calls SDL_PumpEvents() somehow, either directly (like below) or indirectly via SDL_PollEvent() / SDL_WaitEvent() :SDL_Delay() (它阻止所有事件处理,例如通知 X11/Wayland 和您的窗口管理器您的进程仍处于活动状态)替换为以某种方式直接(如下所示)或通过SDL_PollEvent()间接调用SDL_PumpEvents()的循环SDL_WaitEvent() :

const Uint32 startMs = SDL_GetTicks();
while( SDL_GetTicks() - startMs < 5000 )
{
    SDL_PumpEvents();

    //Render something
    SDL_RenderSetLogicalSize(ren,640,480);

    //Set colour of renderer
    SDL_SetRenderDrawColor(ren,255,0,0,255);

    //Clear the screen to the set colour
    SDL_RenderClear(ren);

    //Show all the has been done behind the scenes
    SDL_RenderPresent(ren);
}

All together:全部一起:

#include <iostream>
#include <SDL2/SDL.h>

int main( int argc, char** argv )
{
    if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
    {
        std::cerr << "SDL_Init() Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window* win = SDL_CreateWindow
        (
        "Hello world",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640, 480,
        0
        );

    if( win == nullptr )
    {
        std::cerr << "SDL_CreateWindow() Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    //Create and init the renderer
    SDL_Renderer* ren = SDL_CreateRenderer( win, -1, 0 );
    if( ren == nullptr )
    {
        std::cerr << "SDL_CreateRenderer() Error: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow( win );
        return 1;
    }

    const Uint32 startMs = SDL_GetTicks();
    while( SDL_GetTicks() - startMs < 5000 )
    {
        SDL_PumpEvents();

        //Render something
        SDL_RenderSetLogicalSize( ren, 640, 480 );

        //Set colour of renderer
        SDL_SetRenderDrawColor( ren, 255, 0, 0, 255 );

        //Clear the screen to the set colour
        SDL_RenderClear( ren );

        //Show all the has been done behind the scenes
        SDL_RenderPresent( ren );
    }

    //Clean Up
    SDL_DestroyRenderer( ren );
    SDL_DestroyWindow( win );
    SDL_Quit();

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM