SDL - окно ничего не показывает

Я делаю свои первые шаги в SDL (C++) и взял несколько руководств с сайта www.

Но есть одна проблема. Я установил SDL2 в свою систему Linux Mint, скомпилировал код руководства:

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (win == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Renderer *ren = SDL_CreateRenderer(win, -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == NULL){
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
    if (bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
    SDL_FreeSurface(bmp);
    if (tex == NULL){
        std::cout << "SDL_CreateTextureFromSurface Error: "
            << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Delay(4000);

    SDL_DestroyTexture(tex);
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}

с помощью этой команды компиляции:

g++ main.cpp -lSDL2 -o prog

И я получил это:

Оконная рама без внутренней части

Оконная рама без внутренней части. Где мне искать эту ошибку?



Окончательный код

Во-первых: спасибо starrify!

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *window = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (window == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }
/*
    SDL_Renderer *ren = SDL_CreateRenderer(window, -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == NULL){
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }
*/
    SDL_Surface *surface_bmp = SDL_LoadBMP("cb.bmp");
    if (surface_bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }
/*
    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, surface_bmp);
    SDL_FreeSurface(surface_bmp);
    if (tex == NULL){
        std::cout << "SDL_CreateTextureFromSurface Error: "
            << SDL_GetError() << std::endl;
        return 1;
    }
*/

    SDL_Surface *surface_window = SDL_GetWindowSurface(window);

    /*
     * Copies the bmp surface to the window surface
     */
    SDL_BlitSurface(surface_bmp,
                    NULL,
                    surface_window,
                    NULL);

    /*
     * Now updating the window
     */
    SDL_UpdateWindowSurface(window);

    /*
     * This function used to update a window with OpenGL rendering.
     * This is used with double-buffered OpenGL contexts, which are the default.
     */
/*    SDL_GL_SwapWindow(window); */

    SDL_Delay(5000);

/*    SDL_DestroyTexture(tex);*/
/*    SDL_DestroyRenderer(ren);*/
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Покажите мне этот результат :) введите здесь описание изображения

Я увидел, что это действительно легко. Таким образом, мне не нужен openGL для рисования. Это будет следующим шагом. Было бы неплохо, если бы вы помогли мне улучшить этот пример, чтобы получить его с помощью openGL для...


person Alex44    schedule 22.02.2014    source источник


Ответы (2)


SDL - окно ничего не показывает

Причина в том, что вы ничего не рисуете. Вы создали окно, визуализатор, поверхность и текстуру. Однако вы ничего не рисуете. И визуальный результат точно отражает то, что вы сделали.

Чтобы просто отобразить изображение BMP, загрузите изображение на поверхность и используйте SDL_BlitSurface, чтобы скопировать его на экран. Или для работы с текстурами вы должны рисовать примитивы, такие как треугольники или квадраты, как при работе с OpenGL.

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

ОТРЕДАКТИРОВАНО: я отредактировал ваш код, и вот что работает: (удален модуль рендеринга/текстуры, добавлены SDL_BlitSurface и SDL_UpdateWindowSurface)

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (win == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
    if (bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_BlitSurface(bmp, 0, SDL_GetWindowSurface(win), 0);
    SDL_UpdateWindowSurface(win);

    SDL_Delay(4000);

    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}
person starrify    schedule 22.02.2014

Поскольку вы используете SDL2, вам не следует использовать SDL_Surface для обновления экрана. Это старый способ, который должен был использовать SDL 1.2. Новая подсистема рендеринга — это то, что вам нужно для общего использования, потому что она аппаратно ускорена (использует GPU), а SDL_BlitSurface() и SDL_UpdateWindowSurface() — нет (все копирование пикселей выполняется на CPU).

Итак, что делать. Не используйте SDL_GetWindowSurface(). Используйте свой предыдущий код для создания средства визуализации и текстуры. Замените SDL_BlitSurface() вызовом SDL_RenderCopy(). Замените SDL_UpdateWindowSurface() вызовом SDL_RenderPresent().

В качестве альтернативы вы можете использовать SDL_gpu (примечание: я автор), который похож на старый API блитинга SDL 1.2, но имеет даже больше функций и оптимизаций, чем SDL_Renderer.

person Jonny D    schedule 09.02.2015