SDL_CreateRGBSurfaceFrom / SDL_BlitSurface - я вижу старые кадры на моем эмуляторе

Я работаю над эмулятором Space Invaders и для вывода на дисплей использую SDL2.

Проблема в том, что в окне вывода я вижу все кадры, так как эмуляция начинается!

В основном, важная часть кода такова:

Intel8080 mainObject; // My Intel 8080 CPU emulator
mainObject.loadROM();

//Main loop flag
bool quit = false;

//Event handler
SDL_Event e;

//While application is running
while (!quit)
{
    //Handle events on queue
    while (SDL_PollEvent(&e) != 0)
    {
        //User requests quit
        if (e.type == SDL_QUIT)
        {
            quit = true;
        }
    }

    if (mainObject.frameReady)
    {
        mainObject.frameReady = false;

        gHelloWorld = SDL_CreateRGBSurfaceFrom(&mainObject.frameBuffer32, 256, 224, 32, 4 * 256, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);

        //Apply the image
        SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);

        //Update the surface
        SDL_UpdateWindowSurface(gWindow);
    }

    mainObject.executeROM();
}

где Intel8080 - это код моего эмулятора ЦП, а mainObject.frameBuffer32 - видеопамять Space Invaders, которую я преобразовал из 1bpp в 32bpp, чтобы использовать функцию SDL_CreateRGBSurfaceFrom.

Эмуляция работает нормально, но я вижу все кадры, созданные с момента запуска эмулятора!

Я пытался изменить значение альфы в 4 байтах каждого пикселя RGBA, но ничего не изменилось

1 ответ

Решение

Это происходит потому, что похоже, что вы рендерите игру без предварительной очистки окна. По сути, вы должны заполнить все окно цветом, а затем постоянно рендерить поверх него. Идея состоит в том, что заполнение окна определенным цветом перед его рендерингом эквивалентно стиранию предыдущего кадра (большинство современных компьютеров достаточно мощны, чтобы справиться с этим).

Возможно, вы захотите ознакомиться с функцией SDL_FillRect SDL, она позволит вам заполнить весь экран определенным цветом.

Рендеринг псевдокода:

while(someCondition)
{
    [...]

    // Note, I'm not sure if "gScreenSurface" is the proper variable to use here.
    // I got it from reading your code.
    SDL_FillRect(gScreenSurface, NULL, SDL_MapRGB(gScreenSurface->format, 0, 0, 0));

    SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);

    SDL_UpdateWindowSurface(gWindow);

    [...]
}
Другие вопросы по тегам