Функция SDL2, которая стирает линии? - PullRequest
0 голосов
/ 12 мая 2019

Я делаю программу, которая создает линии, как я могу стереть строку?Есть ли для него функция?

Я уже пробовал использовать SDL_RenderClear(), но она не сработала.(обратите внимание, что я новичок и что я НЕ коренной американец, также мне всего 10 лет, поэтому объясните простым способом.)

Вот моя строка для создания кода:

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

using namespace std;

int main( int argc, char * argv[] )
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_Window *janela = NULL;
    SDL_Renderer *renderer = NULL;
    bool roda = true;
    SDL_Event evento;
    int x;
    int y;
    int x2;
    int y2;
    janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
    renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);


    while (roda) {
    SDL_Event evento;
    while (SDL_PollEvent(&evento)) {
       switch(evento.type){

         case SDL_QUIT:
         roda = false;
         break;

         case SDL_MOUSEBUTTONDOWN:{
         x = evento.motion.x;
         y = evento.motion.y;
         break;}

         case SDL_MOUSEBUTTONUP:
         while(roda){
         x2 = evento.motion.x;
         y2 = evento.motion.y;
         SDL_SetRenderDrawColor(renderer , 255 , 0 , 0 , 255);
         SDL_SetRenderDrawColor(renderer , 125 , 234 , 253 , 255);
         SDL_RenderDrawLine(renderer , x , y , x2 , y2);
         SDL_RenderPresent(renderer);
         break;}

         case SDL_KEYDOWN:{
         switch(evento.key.keysym.sym){
         case SDLK_b:{


          SDL_RenderClear(renderer);


             }
            }
           }
          }
         }
        }


    SDL_DestroyWindow(janela);
    janela = NULL;
    SDL_DestroyRenderer(renderer);
    renderer = NULL;
    SDL_Quit();

    return 1;
}

Я ожидаю, что строки будут стерты, но этого не произошло.

1 Ответ

1 голос
/ 13 мая 2019

Типичный основной цикл в основном такой:

while(!quit) {
    while(pool_event()) {
        // change state to react to event
    }

    clear_previous_frame();
    for each line {
        draw_line();
    }
    present();
}

Таким образом, вы всегда должны очищать и перерисовывать ваши строки, добавляя новое состояние строки, если события говорят об этом (но пока не рисуют его - обработка событий не должна этого делать, или она становится очень компилированной). Проблематично сохранить содержимое предыдущего кадра и просто добавить больше строк; краткое объяснение объясняется тем, что SDL_RenderPresent документация говорит The backbuffer should be considered invalidated after each present (а длинное объяснение - это, в основном, список причин, почему это так).

Чтобы отслеживать линии, которые вы хотите нарисовать, вам нужно их где-то сохранить. std::vector может быть простым вариантом, если ваши требования не противоречат ему.

Подводя итог, модифицированный код вашего вопроса с небольшим количеством комментариев:

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

struct line {
    int x0, y0, x1, y1;
};

int main( int argc, char * argv[] )
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_Window *janela = NULL;
    SDL_Renderer *renderer = NULL;
    bool roda = true;
    int x;
    int y;
    janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
    renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);

    std::vector<line> lines;

    while (roda) {
        SDL_Event evento;
        while (SDL_PollEvent(&evento)) {
            switch(evento.type){
            case SDL_QUIT:
                roda = false;
                break;

            case SDL_MOUSEBUTTONDOWN:
                // save starting coordinates
                x = evento.motion.x;
                y = evento.motion.y;
                break;

            case SDL_MOUSEBUTTONUP: {
                // add new line to draw
                line l = { x, y, evento.motion.x, evento.motion.y };
                lines.push_back(l);
            } break;

            case SDL_KEYDOWN:
                if(evento.key.keysym.sym == SDLK_b) {
                    // drop lines
                    lines.resize(0);
                }
                break;
            }
        }

        // clear previous contents - in most cases, screen content is
        // invalidated after RenderPresent and you need to draw again
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);    // your 'clear' colour
        SDL_RenderClear(renderer);

        // draw all accumulated lines
        SDL_SetRenderDrawColor(renderer, 125, 234, 253, 255);    // your lines colour
        for(const line &l : lines) {
            SDL_RenderDrawLine(renderer, l.x0, l.y0, l.x1, l.y1);
        }

        // all drawn - present
        SDL_RenderPresent(renderer);
    }


    SDL_DestroyWindow(janela);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();

    return 0;   // 0 is 'success' return code, non-0 is failure
}
...