簡體   English   中英

沒有 X 的 Raspberry Pi 上的 SDL2?

[英]SDL2 on Raspberry Pi without X?

我希望開發一些使用 SDL2 在 7" RPi 觸摸屏上顯示圖形的代碼,但我寧願不安裝完整的桌面操作系統。我已經安裝了 Raspbian Buster Lite。一些簡單的測試代碼在我嘗試運行它:

user@rpi4:~/01_hello_SDL $ ./hw
Window could not be created! SDL_Error: Could not initialize EGL
user@rpi4:~/01_hello_SDL $ sudo ./hw
error: XDG_RUNTIME_DIR not set in the environment.
Window could not be created! SDL_Error: Could not initialize EGL

我正在嘗試創建窗口

SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL )

我找到了一篇文章,其中引用了有關如何在沒有 X 的情況下構建 SDL2 的說明,但我希望有人能教我更多關於 SDL 如何在各種環境中找到顯示的信息,以及是否有可能做我想做的事情。

幾年前,我使用 SDL 1.2 在運行 Debian 版本的 Beaglebone Black 上制作全屏圖形,但我似乎丟失了該安裝,並且不記得它是如何設置的。 我依稀記得一些關於 fbdev 的問題,它是非加速圖形,但這在當時並不重要(雖然我現在想獲得加速圖形,但這並不重要)。

示例代碼:

/*This source code copyrighted by Lazy Foo' Productions (2004-2019)
and may not be redistributed without written permission.*/

//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 480;

int main( int argc, char* args[] )
{
    //The window we'll be rendering to
    SDL_Window* window = NULL;

    //The surface contained by the window
    SDL_Surface* screenSurface = NULL;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    }
    else
    {
        //Create window
        window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL );
        if( window == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
        }
        else
        {
            //Get window surface
            screenSurface = SDL_GetWindowSurface( window );

            //Fill the surface white
            SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) );

            //Update the surface
            SDL_UpdateWindowSurface( window );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Destroy window
    SDL_DestroyWindow( window );

    //Quit SDL subsystems
    SDL_Quit();

    return 0;
}

好的,使用2019-07-10-raspbian-buster-lite.img讓它在我的 Raspberry Pi 3 上2019-07-10-raspbian-buster-lite.img ,兩者都使用默認的 Broadcom blob和 KMS/DRM 后端:

  1. 安裝 SDL2 構建依賴項:

     # install everything Debian uses to build SDL sudo apt build-dep libsdl2 # needed for the KMSDRM backend: sudo apt install libdrm-dev libgbm-dev
  2. Mercurial / Git獲取最新的穩定SDL 源代碼壓縮包或標簽 ( release-2.0.10 ) 並將其解壓縮到~/sdl-src

  3. 運行 SDL 的configure腳本:

     cd ~/sdl-src ./configure --enable-video-kmsdrm

    這是我的configure摘要,請注意Video drivers列表中的rpikmsdrm(dynamic)條目:

     SDL2 Configure Summary: Building Shared Libraries Building Static Libraries Enabled modules : atomic audio video render events joystick haptic sensor power filesystem threads timers file loadso cpuinfo assembly Assembly Math : Audio drivers : disk dummy oss alsa(dynamic) pulse(dynamic) sndio(dynamic) Video drivers : dummy rpi x11(dynamic) kmsdrm(dynamic) opengl opengl_es1 opengl_es2 vulkan wayland(dynamic) X11 libraries : xcursor xdbe xinerama xinput2 xinput2_multitouch xrandr xscrnsaver xshape xvidmode Input drivers : linuxev linuxkd Using libsamplerate : YES Using libudev : YES Using dbus : YES Using ime : YES Using ibus : YES Using fcitx : YES
  4. 構建和安裝 SDL; 在我的 Rpi3 上花了大約 4.5 分鍾:

     make -j4 && sudo make install
  5. 構建測試程序:

     g++ main.cpp `pkg-config --cflags --libs sdl2`
  6. (可選)如果要使用 KMSDRM 后端而不是默認的 OpenGL ES blob,請啟用“完整 KMS”驅動程序:

     $ sudo raspi-config select '7 Advanced Options' select 'A7 GL Driver' select 'G3 GL (Full KMS)' reboot
  7. 運行測試程序:

     $ ./a.out Testing video drivers... The path /dev/dri/ cannot be opened or is not available The path /dev/dri/ cannot be opened or is not available SDL_VIDEODRIVER available: x11 wayland KMSDRM RPI dummy SDL_VIDEODRIVER usable : RPI The path /dev/dri/ cannot be opened or is not available The path /dev/dri/ cannot be opened or is not available SDL_VIDEODRIVER selected : RPI SDL_RENDER_DRIVER available: opengl opengles2 opengles software SDL_RENDER_DRIVER selected : opengles2

    您可以使用環境變量來覆蓋默認的視頻/渲染驅動程序選擇:

     SDL_VIDEODRIVER=KMSDRM SDL_RENDER_DRIVER=software ./a.out

    我不得不用 envvars 握住 SDL 的手,才能加載 KMSDRM 后端:

     # no envvars, fails: $ ./a.out Testing video drivers... SDL_VIDEODRIVER available: x11 wayland KMSDRM RPI dummy SDL_VIDEODRIVER usable : KMSDRM SDL_VIDEODRIVER selected : KMSDRM SDL_CreateWindow(): Could not initialize OpenGL / GLES library # with envvars, succeeds: $ SDL_VIDEO_EGL_DRIVER=libEGL.so SDL_VIDEO_GL_DRIVER=libGLESv2.so ./a.out Testing video drivers... SDL_VIDEODRIVER available: x11 wayland KMSDRM RPI dummy SDL_VIDEODRIVER usable : KMSDRM SDL_VIDEODRIVER selected : KMSDRM SDL_RENDER_DRIVER available: opengl opengles2 opengles software SDL_RENDER_DRIVER selected : opengl

這是我一直在使用的測試程序:

#include <SDL.h>
#include <iostream>
#include <vector>

int main( int argc, char** argv )
{
    SDL_Init( 0 );

    std::cout << "Testing video drivers..." << '\n';
    std::vector< bool > drivers( SDL_GetNumVideoDrivers() );
    for( int i = 0; i < drivers.size(); ++i )
    {
        drivers[ i ] = ( 0 == SDL_VideoInit( SDL_GetVideoDriver( i ) ) );
        SDL_VideoQuit();
    }

    std::cout << "SDL_VIDEODRIVER available:";
    for( int i = 0; i < drivers.size(); ++i )
    {
        std::cout << " " << SDL_GetVideoDriver( i );
    }
    std::cout << '\n';

    std::cout << "SDL_VIDEODRIVER usable   :";
    for( int i = 0; i < drivers.size(); ++i )
    {
        if( !drivers[ i ] ) continue;
        std::cout << " " << SDL_GetVideoDriver( i );
    }
    std::cout << '\n';

    if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        std::cerr << "SDL_Init(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }
    std::cout << "SDL_VIDEODRIVER selected : " << SDL_GetCurrentVideoDriver() << '\n';

    SDL_Window* window = SDL_CreateWindow
        (
        "SDL2",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        640, 480,
        SDL_WINDOW_SHOWN
        );
    if( nullptr == window )
    {
        std::cerr << "SDL_CreateWindow(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }

    std::cout << "SDL_RENDER_DRIVER available:";
    for( int i = 0; i < SDL_GetNumRenderDrivers(); ++i )
    {
        SDL_RendererInfo info;
        SDL_GetRenderDriverInfo( i, &info );
        std::cout << " " << info.name;
    }
    std::cout << '\n';

    SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );
    if( nullptr == renderer )
    {
        std::cerr << "SDL_CreateRenderer(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }
    SDL_RendererInfo info;
    SDL_GetRendererInfo( renderer, &info );
    std::cout << "SDL_RENDER_DRIVER selected : " << info.name << '\n';

    bool running = true;
    unsigned char i = 0;
    while( running )
    {
        SDL_Event ev;
        while( SDL_PollEvent( &ev ) )
        {
            if( ( ev.type == SDL_QUIT ) ||
                ( ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE ) )
            {
                running = false;
            }
        }

        SDL_SetRenderDrawColor( renderer, i, i, i, SDL_ALPHA_OPAQUE );
        SDL_RenderClear( renderer );
        SDL_RenderPresent( renderer );
        i++;
    }

    SDL_DestroyRenderer( renderer );
    SDL_DestroyWindow( window );
    SDL_Quit();
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM