SDL - Поверхности не должны быть заблокированы во время блита

Я пытаюсь написать простую игру на C. Я использую SDL2 для рисования. Вот основной цикл:

...
while( !quit_f )
{
    //Handle events on queue
    while( SDL_PollEvent( &e ) != 0 )
    {
        //User requests quit
        if( e.type == SDL_QUIT )
        {
            quit_f = 1;
        }
    }
    currTime = clock();
    dt = (float)((currTime - t)/1000.0f);
    update_player(dt, player);

    printf("locks before drawing: %i\n", player->surface->locked );
    draw_player(player);

    printf("\n");
    printf("%p\n", player->surface);
    printf("locks before window update: %i\n", player->surface->locked );

    //Update window surface
    SDL_UpdateWindowSurface( window );

    printf("%s\n", SDL_GetError());
    printf("locks after window update: %i\n", player->surface->locked );
    printf("\n");
    t = currTime;
}
...

Вот функция draw_player:

void draw_player(struct GameObject * self){
    printf("%p\n", self->surface);
    printf("locks iside draw_player - before blit: %p\n", self->surface->locked);
    SDL_BlitSurface(window, NULL, self->surface, NULL);
    printf("locks iside draw_player - after blit: %p\n", self->surface->locked);
}

Он хорошо компилируется, но не отображает плеер после запуска. Выход:

locks before drawing: 0
0x89795b0
locks iside draw_player - before blit: (nil)
locks iside draw_player - after blit: (nil)

0x89795b0
locks before window update: 0
Surfaces must not be locked during blit
locks after window update: 0

Я не понимаю, почему self->surface->locked NULL внутри функции draw_player. Указатели на поверхность одинаковы, так что... я не совсем понимаю. Я нигде не вызываю SDL_LockSurface в моем коде, но SDL жалуется, что поверхность заблокирована во время блита - Surfaces must not be locked during blit, Я пытался вызвать SDL_UnlockSurface до SDL_BlitSurface, но ничего не изменилось. Есть идеи? Я должен отметить, что я начинающий в C и SDL. Я запускаю Fedora 24. Поскольку SDL - это кроссплатформенная библиотека, это не должно быть проблемой. Я использую gcc 6.1.1.

Спрайт плеера в формате png, поэтому я использую IMG_Load. Вот как создается игрок:

void init_player(struct GameObject * player, char * path, float x, float y){
    SDL_Surface * image = IMG_Load(path);
    if(image == NULL){
        printf("Error while loading png: %s\n", IMG_GetError()); 
        return;
    }

    // direction vector
    player_dir = malloc(sizeof(Vector2d));
    player_dir->x = 0.0f; 
    player_dir->y = 0.0f;

    // destination rectangle
    SDL_Rect * dRect = malloc(sizeof(SDL_Rect));
    dRect->x = round(x);
    dRect->y = round(y);
    dRect->w = image->w;
    dRect->h = image->h;

    player->surface = image;
    player->destRect = dRect;
    player->x = x;
    player->y = y;
    player->width = image->w;
    player->height = image->h;    
    player->update = update_player; // function pointer
    player->draw = draw_player; // function pointer
}

И последнее, что я должен вам сказать. Я храню указатели для рисования и обновления функций в структуре GameObject. Поэтому я называю update_player как player->update(...), То же самое с функциями рисования. Это немного хакерский стиль, но мне это нравится. Я попытался вызвать draw_player сразу. Поскольку результат был таким же, я думаю, что мой стиль кодирования не проблема. Но я могу ошибаться. Не стесняйтесь поправлять меня.

РЕДАКТИРОВАТЬ: Я мог бы найти эту ошибку. SDL_BlitSurface(window, NULL, self->surface, NULL); должно быть SDL_BlitSurface(screenSurface, NULL, self->surface, NULL);, Window - указатель на SDL_Window, а screenSurface - указатель на SDL_Surface. Почему он не выдавал ошибку во время компиляции? Хорошо, ошибка исчезла. Но ничего не отображается.

РЕДАКТИРОВАТЬ № 2 Я нашел это. Это была такая глупая ошибка. Это правильное решение: SDL_BlitSurface(self->surface, NULL, screenSurface, NULL); Вот как выглядит SDL_BlitSurface:

int SDL_BlitSurface(SDL_Surface*    src,
                const SDL_Rect* srcrect,
                SDL_Surface*    dst,
                SDL_Rect*       dstrect)

Сначала должна быть поверхность источника, а третья поверхность назначения. Это было написано наоборот. Это вызвало ошибку.

0 ответов

Другие вопросы по тегам