使用SDL2绘制矩形

19
我刚开始使用SDL2,但遇到了问题。 我想创建一个窗口并将其涂成红色。 但它仍然是白色的,我不明白为什么。
这是代码:
int main (int argc, char** argv) {
    SDL_Window* pWindow = NULL;
    pWindow = SDL_CreateWindow("Jeu de la vie", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        640,
        480,
        SDL_WINDOW_SHOWN);

    SDL_Surface* pSurface = NULL;
    pSurface = SDL_GetWindowSurface(pWindow);
    SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, 255, 0, 0));

    while(1);

    SDL_FreeSurface(pSurface);
    SDL_DestroyWindow(pWindow);
    SDL_Quit();
    return EXIT_SUCCESS;
}
1个回答

84

你的代码存在一些问题,我会尽量解决大部分问题。

初始化SDL

SDLSDL2需要在使用前进行初始化。初始化SDL的方式是使用以下函数:

int SDL_Init(Uint32 flags)

在不同的子系统中,flags 可以是不同的值。使用 SDL_INIT_EVERYTHING 来初始化所有内容。

int SDL_Init(SDL_INIT_EVERYTHING)

了解更多,请点击这里。


初始化SDL_WindowSDL_Renderer

在使用SDL_RendererSDL_Window之前,需要对它们进行设置。如果您已经正确创建了窗口,则无需涉及此步骤。下面是如何设置SDL_Renderer

SDL_Renderer* SDL_CreateRenderer(SDL_Window* window,
                                 int         index,
                                 Uint32      flags)

index 定义要使用哪个驱动程序。将其设置为 -1 以使用支持其他参数的第一个驱动程序。
flags 用于使呈现优化,软件呈现,防止垂直同步等。将其设置为 SDL_RENDERER_ACCELERATED

此处了解有关 SDL_CreateRenderer 的更多信息。

混合使用 SDLSDL2

SDL_Surface 主要是在 SDL 中使用的,而不是在 SDL2 中使用的。 SDL2_imageSDL2_ttf 等仍然使用 SDL_Surface,但是它们在使用之前被转换为 SDL_Texture

SDL_FillRect(...); 也主要是 SDL 的东西。但是如上所述,SDL_Surface 可以使用,但需要先将其转换为 SDL_Texture

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                          SDL_Surface*  surface)

点击这里阅读更多信息。

并使用

int SDL_RenderCopy(SDL_Renderer*   renderer,
                   SDL_Texture*    texture,
                   const SDL_Rect* srcrect,
                   const SDL_Rect* dstrect)

为了渲染它,请在此处阅读更多内容

无限循环(while(1);

你真的不应该这样做,它会一直循环下去。使用SDL_Delay(5000)暂停5000毫秒或5秒。

一个更简单的方法

你可以使用

int SDL_RenderDrawRect(SDL_Renderer*   renderer,
                       const SDL_Rect* rect)

绘制矩形。

应该使用

int SDL_SetRenderDrawColor(SDL_Renderer* renderer,
                           Uint8         r,
                           Uint8         g,
                           Uint8         b,
                           Uint8         a)

要设置你所绘制的内容的颜色,使用

int SDL_RenderClear(SDL_Renderer* renderer)

在这之后,您需要调用SDL_RenderDrawRect()函数。

到此为止,所有内容都已经被“幕后”绘制。要将其渲染到屏幕上,请使用:

void SDL_RenderPresent(SDL_Renderer* renderer)

示例

#include <SDL2/SDL.h>

int main (int argc, char** argv)
{
    SDL_Window* window = NULL;
    window = SDL_CreateWindow
    (
        "Jeu de la vie", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        640,
        480,
        SDL_WINDOW_SHOWN
    );

    // Setup renderer
    SDL_Renderer* renderer = NULL;
    renderer =  SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);

    // Set render color to red ( background will be rendered in this color )
    SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );

    // Clear winow
    SDL_RenderClear( renderer );

    // Creat a rect at pos ( 50, 50 ) that's 50 pixels wide and 50 pixels high.
    SDL_Rect r;
    r.x = 50;
    r.y = 50;
    r.w = 50;
    r.h = 50;

    // Set render color to blue ( rect will be rendered in this color )
    SDL_SetRenderDrawColor( renderer, 0, 0, 255, 255 );

    // Render rect
    SDL_RenderFillRect( renderer, &r );

    // Render the rect to the screen
    SDL_RenderPresent(renderer);

    // Wait for 5 sec
    SDL_Delay( 5000 );

    SDL_DestroyWindow(window);
    SDL_Quit();

    return EXIT_SUCCESS;
}

结果

渲染结果


您可以在我的博客上了解更多关于SDL2的信息。


一些修正... SDL_Renderer 需要一个参数,而 SDL_RenderDrawRect 需要传入 R 的地址。SDL_RenderClear(pRenderer); .. SDL_RenderDrawRect(pRenderer, &r); - Begui
1
@Begui 谢谢!我写示例代码时可能太快了,因为第一部分的参数是正确的。 - olevegard
非常好的解释!但我遇到了一个问题,也许你可以帮忙解决。当我尝试通过调用SDL_CreateRender来设置渲染器时,返回NULL,并且当我调用SDL_GetError()时,它告诉我“OpenGL上下文已经创建”。这是什么意思?似乎没有任何东西被渲染,我猜测是因为这个原因。我尝试使我的文件与你的完全相同,但仍然发生这种情况。提前致谢! - Julian
@JulianCleary 我已经更新了代码,其中有一些错误。如果你仍然无法让它工作,你应该用你的代码创建一个新问题。我很乐意继续帮助你。 - olevegard
SDL_CreateRenderer()函数中的index参数是渲染驱动程序,而不是SDL_Window。在本例中最好将其保留为-1。(以初始化支持请求标志的第一个渲染器。) - Runium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接