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

properly rendering an SDL rectangle to the screen

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

Notice the call to SDL_SetRenderDrawColor. We're using 255 red and 255 green which combine together to make yellow. Remember that call to SDL_SetRenderDrawColor at the top of the loop? If that wasn't there, the screen would be cleared with whatever color was last set with SDL_SetRenderDrawColor, resulting in a yellow background in this case.

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

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

为什么需要调用 SDL_SetRenderDrawColor() 两次,为什么要按这个顺序调用?我注意到如果我在调用 SDL_RenderFillRect() 之前注释掉第一个 SDL_SetRenderDrawColor(),完整的 window 将是您设置矩形的颜色,但是当您包括按照我指定的顺序对 SDL_SetRenderDrawColor() 的两次调用 window 在屏幕中央显示一个彩色矩形,屏幕的其余部分为白色(第一个 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 );
}

Why do you need to call SDL_SetRenderDrawColor() twice and why in that order?

SDL_RenderClear 的名称有点误导。它不会将屏幕清除为 "empty" 或任何东西 - 它只是用 SDL_SetRenderDrawColor 设置的任何颜色填充它。因此,如果您在 "clearing" 和绘制矩形之间不更改颜色,那么您将看不到矩形,因为您绘制的颜色与刚刚填充整个屏幕的颜色相同。

所以这里

SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );

你把整个屏幕弄白了。我们通过设置白色,然后在整个屏幕上绘制白色来做到这一点。

那么这里

SDL_SetRenderDrawColor( gRenderer, 0xFF, 0x00, 0x00, 0xFF );  

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

SDL_RenderFillRect( gRenderer, &fillRect );

将是红色(不是白色)。

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

I noticed if I comment out the first SDL_SetRenderDrawColor() just before the call to SDL_RenderFillRect(),the full window will be the colour you set the rectangle to be

很好的观察!你看,因为你在循环 (while(!quit){),所以你执行 SDL_RenderClear 然后 SDL_RenderFillRect... 但随后 SDL_RenderClear 再次出现,依此类推。所以当 SDL_RenderClear 发生时,颜色实际上是在 last 运行 中 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 ); 
...

所以你看,只有第二次 SDL_SetRenderDrawColor 调用,SDL_RenderClearSDL_RenderFillRect 将始终以绿色绘制,除了第一个 SDL_RenderClear 调用第一帧。