правильно отображать прямоугольник SDL на экране - PullRequest
0 голосов
/ 11 декабря 2018

Вот мой код, я следую учебникам lazyfoos по SDL, вот точный учебник, которому я следую - 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_SetRenderDrawColor () непосредственно перед вызовом SDL_RenderFillRect (), полное окно будет цветом, который вы установили для прямоугольника, но когда вы включите два вызова 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 );
}

1 Ответ

0 голосов
/ 11 декабря 2018

Почему вам нужно дважды вызывать SDL_SetRenderDrawColor () и почему в этом порядке?

Имя SDL_RenderClear немного вводит в заблуждение.Он не очищает экран от «пустого» или чего-либо еще - он просто заполняет его тем цветом, который был установлен SDL_SetRenderDrawColor.Поэтому, если вы не измените цвет между «очисткой» и рисованием прямоугольника, то вы не увидите прямоугольник, потому что рисуете его тем же цветом, которым вы только что заполнили весь экран.

Так вот

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

Вы делаете весь экран белым.Мы делаем это, устанавливая белый цвет, а затем закрашивая весь экран белым цветом.

Затем здесь

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

Мы устанавливаем красный цвет, поэтому прямоугольник здесь

SDL_RenderFillRect( gRenderer, &fillRect );

Будет красным (не белым).

И если я правильно помню урок, он также рисует линию и некоторые другие вещи, каждый раз вызывая SDL_SetRenderDrawColor прямо перед тем, чтобы установить правильный цвет.

Я заметил, что если я закомментирую первый SDL_SetRenderDrawColor () непосредственно перед вызовом SDL_RenderFillRect (), полное окно будет цветом, для которого вы установите прямоугольник

Очень хорошее наблюдение!Видите ли, поскольку вы зацикливаетесь (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 ); 
...

Итак, вы видите, что только с этим вторым вызовом SDL_SetRenderDrawColor оба SDL_RenderClear и SDL_RenderFillRect всегда будут отображаться зеленым, кроме самого первого вызова SDL_RenderClearв первом кадре.

...