正确地将 SDL 矩形渲染到屏幕上

iri*_*iac 4 c++ sdl game-development sdl-2

这是我的代码,我正在关注SDL上的lazyfoos教程,这是我正在关注的确切教程 - http://lazyfoo.net/tutorials/SDL/08_geometry_rendering/index.php

请注意对 SDL_SetRenderDrawColor 的调用。我们使用 255 红色和 255 绿色,它们组合在一起形成黄色。还记得循环顶部对 SDL_SetRenderDrawColor 的调用吗?如果不存在,屏幕将被清除为最后使用 SDL_SetRenderDrawColor 设置的任何颜色,在这种情况下会导致黄色背景。

Lazyfoo 确实在上面解释了这一点,但对我来说仍然没有意义。

在屏幕上绘制一个填充的矩形是一项非常简单的任务,但有时会引起很多混乱,例如您需要调用 SDL_SetRenderDrawColor() 不是一次而是两次,一次在清除渲染器之前,也一次在清除渲染器之前您调用 SDL_RenderFillRect()。

为什么需要调用 SDL_SetRenderDrawColor() 两次以及为什么按这个顺序?我注意到,如果我在调用 SDL_RenderFillRect() 之前注释掉第一个 SDL_SetRenderDrawColor() ,整个窗口将是您设置矩形的颜色,但是当您按照我指定的顺序包含对 SDL_SetRenderDrawColor() 的两个调用时窗口在屏幕中央显示一个彩色矩形,屏幕的其余部分为白色(第一个 SDL_SetRenderDrawColor() 调用)。

这是我进行调用的游戏循环。

while( !quit )
{
    while( SDL_PollEvent( &event ) != 0 )
    {
        if( event.type == SDL_QUIT )
        {
            quit = true;

        }
    }

    SDL_SetRenderDrawColor( renderer, 255, 255, 255, 0 ); // line of code in question
    SDL_RenderClear( renderer );

    SDL_Rect fillRect = { 500 / 4, 500 / 4, 500 / 2, 500 / 2 };
    SDL_SetRenderDrawColor( renderer, 0x00, 0xFF, 0x00, 0xFF ); // 2nd line of code in question
    SDL_RenderFillRect( renderer, &fillRect );

    SDL_RenderPresent( renderer );
}
Run Code Online (Sandbox Code Playgroud)

Bla*_*aze 5

为什么需要调用 SDL_SetRenderDrawColor() 两次以及为什么按这个顺序?

的名字SDL_RenderClear有点误导。它不会将屏幕清除为“空”或任何其他内容 - 它只是用 所设置的任何颜色填充它SDL_SetRenderDrawColor。因此,如果您在“清除”和绘制矩形之间不更改颜色,那么您将看不到该矩形,因为您正在使用刚刚填充整个屏幕的相同颜色来绘制它。

所以在这里

SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
Run Code Online (Sandbox Code Playgroud)

你把整个屏幕变成白色。我们通过设置白色,然后用白色绘制整个屏幕来实现此目的。

然后这里

SDL_SetRenderDrawColor( gRenderer, 0xFF, 0x00, 0x00, 0xFF );  
Run Code Online (Sandbox Code Playgroud)

我们设置红色所以这里的矩形

SDL_RenderFillRect( gRenderer, &fillRect );
Run Code Online (Sandbox Code Playgroud)

将是红色(不是白色)。

如果我没记错教程,它还会画一条线和其他一些东西,每次都SDL_SetRenderDrawColor在之前调用以设置正确的颜色。

我注意到,如果我在调用 SDL_RenderFillRect() 之前注释掉第一个 SDL_SetRenderDrawColor() ,则整个窗口将是您设置矩形的颜色

非常好的观察力!你看,因为你正在循环 ( while(!quit){),所以你会这样做,SDL_RenderClear然后SDL_RenderFillRect......但然后SDL_RenderClear又来了,依此类推。因此,当SDL_RenderClear发生这种情况时,颜色实际上是SDL_RenderFillRect上次循环运行之前设置的。这就是为什么它也有这种颜色。

所以实际上,我第一次不知道颜色是什么,因为它还没有设置(可能是白色的默认值,或者其他),但我们可能看不到它,因为这只是第一次运行无论如何都要通过循环。那么大致发生的事情是:

...
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor( renderer, 0x00, 0xFF, 0x00, 0xFF );
SDL_RenderFillRect( renderer, &fillRect );
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor( renderer, 0x00, 0xFF, 0x00, 0xFF );
SDL_RenderFillRect( renderer, &fillRect ); 
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor( renderer, 0x00, 0xFF, 0x00, 0xFF );
SDL_RenderFillRect( renderer, &fillRect ); 
...
Run Code Online (Sandbox Code Playgroud)

所以你会看到,只有第二次SDL_SetRenderDrawColor调用时,除了第一帧中的第一次调用之外, 和 都将始终绘制为绿色SDL_RenderClearSDL_RenderFillRectSDL_RenderClear