2016-06-29 6 views
4

Я только что начал с SDL2, прочитал пару статей по нему и смог с успехом скомпилировать тестовую программу, написанную на Arch Linux. Единственная проблема, которая, кажется, происходит, заключается в том, что созданное окно не отображает изображение. Я пробовал использовать тот же код на Mac, что приводит к ожидаемому. Я использую CLion, который не является злоумышленником, потому что компиляция с g ++ через CLI приводит к тому же.SDL2 на Arch Linux: окно отображает, что находится на экране позади него

My Arch Linux установки:

OS: Arch Linux x86_64 
Kernel Release: 4.6.2-1-ARCH 

Вот код, я компиляции:

#include <iomanip> 
#include <SDL2/SDL.h> 
using namespace std; 

const int WIDTH = 640; 
const int HEIGHT = 480; 

bool init(); 
bool loadMedia(); 
int close(); 

SDL_Window* window = NULL; 
SDL_Surface* surface = NULL; 
SDL_Surface* image = NULL; 

int main(int argc, char** argv) { 
    if(init()) 
     if(loadMedia()) 
      printf("Media loaded"); 
    SDL_BlitSurface(image, NULL, surface, NULL); 
    SDL_UpdateWindowSurface(window); 
    SDL_Delay(5000); 
    return close(); 
} 

bool init() { 
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { 
     printf("Error initializing SDL: %s", SDL_GetError()); 
     return false; 
    } else { 
     window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN); 
     if(window == NULL) { 
      printf("Error creating window: %s", SDL_GetError()); 
      return false; 
     } 
     else 
      surface = SDL_GetWindowSurface(window); 
    } 
    return true; 
} 

bool loadMedia() { 
    image = SDL_LoadBMP("/home/me/ClionProjects/SDLTest/test.bmp"); 
    if(image == NULL) { 
     printf("Error loading in image: %s", SDL_GetError()); 
     return false; 
    } 
    return true; 
} 

int close() { 
    SDL_FreeSurface(surface); 
    SDL_FreeSurface(image); 
    SDL_DestroyWindow(window); 
    SDL_Quit(); 
    return 0; 
} 

Мой файл CMakeLists.txt (используется CLion):

cmake_minimum_required(VERSION 3.5) 
project(SDLTest) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -w -lSDL2") 

set(SOURCE_FILES main.cpp) 
add_executable(SDLTest ${SOURCE_FILES}) 

И команда Unix, которую я использовал для ее компиляции с g ++:

g++ main.cpp -w -lSDL2 -o prog 

Что это выглядит, когда работает код на арке:

Code run on Arch Linux

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

На Mac:

enter image description here

нашел пару статей, также намекая на эту проблему, но решения этих статей не работает для меня. В частности, я говорю об этих статьях.

SDL - window doesn't show anything

https://bbs.archlinux.org/viewtopic.php?id=188412

https://gamedev.stackexchange.com/questions/117792/why-does-sdl-render-the-background-from-the-operating-system-to-the-window

Надеется, что я предоставил достаточно информацию, и что есть кто-то там, что испытал тот же вопрос, и было в состоянии решить. Заранее спасибо!


Edit после keltar's comment (до сих пор не делать то, что он должен):

#include <iomanip> 
#include <SDL2/SDL.h> 
using namespace std; 

const int WIDTH = 640; 
const int HEIGHT = 480; 

bool init(); 
bool loadMedia(); 
//int close(); 

SDL_Window* window = NULL; 
SDL_Surface* surface = NULL; 
SDL_Surface* image = NULL; 

int main(int argc, char** argv) { 
    if(init()) 
     if(loadMedia()) 
      printf("Media loaded"); 
    SDL_BlitSurface(image, NULL, surface, NULL); 
    SDL_UpdateWindowSurface(window); 
    SDL_Delay(5000); 
    SDL_Quit(); 
    return 0; 
} 

bool init() { 
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { 
     printf("Error initializing SDL: %s", SDL_GetError()); 
     return false; 
    } else { 
     window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN); 
     if(window == NULL) { 
      printf("Error creating window: %s", SDL_GetError()); 
      return false; 
     } 
     else 
      surface = SDL_GetWindowSurface(window); 
    } 
    return true; 
} 

bool loadMedia() { 
    image = SDL_LoadBMP("/home/me/ClionProjects/SDLTest/test.bmp"); 
    if(image == NULL) { 
     printf("Error loading in image: %s", SDL_GetError()); 
     return false; 
    } 
    return true; 
} 

//int close() { 
// SDL_FreeSurface(surface); 
// SDL_FreeSurface(image); 
// SDL_DestroyWindow(window); 
// SDL_Quit(); 
// return 0; 
//} 
+0

1. не занимайтесь свободной поверхностью окна и 2. - в большинстве случаев (как правило, с задействованным диспетчером компоновки) вы не можете ожидать, что изображение будет отображаться простым ожиданием. Добавьте цикл, который сбрасывает очередь событий, затем рисует ваше изображение, а затем повторяет. – keltar

+0

... и я снова забыл о функции 'close'. Пожалуйста, не делай этого. http://stackoverflow.com/questions/31482117/sdl-event-handling-not-working – keltar

+0

Спасибо за советы, я рассмотрю их, когда буду более свободно работать с фреймворком. На данный момент я просто следую этому руководству, поскольку вы, возможно, уже вычитали: http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php Изменение того, что вы предложили, не изменило того факта, что на самом деле ничего нет от того, что я прошу об этом. Главное, что я пытаюсь сделать сейчас, - это исправление несоответствия, которое, кажется, существует между запуском этого кода в Arch Linux и его запуском на OS X. –

ответ

1

Я запустить свой код на Ubuntu 14.04 без каких-либо проблем. Чтобы проверить, не является ли его проблемой «драйвер рендеринга» в Linux, можете ли вы запустить мою маленькую GPL game из командной строки и скопировать информацию, отображаемую в консоли?

Вы должны увидеть что-то вроде этого:

Video drivers (2): 'x11' 'dummy', active = 'x11' 
Screen: 1920 x 1080, game: 1024 x 576 
Rendering drivers (2): 'opengl' 'software', active = 'opengl' 
Render flags = 0x000a | ACCELERATED | TARGETTEXTURE 
Window flags = 0x001a | OPENGL | BORDERLESS 
0 joystick(s) detected 

я столкнулся с такой же проблемой на CentOS 5, когда флаг «SDL_RENDERER_PRESENTVSYNC» включен в визуализатора или до тех пор, пока вы не копировать любые текстуры к рендереру.

Другая идея, что происходит, когда вы это делаете?

for(int i = 0; i < 10; i++) { 
    SDL_BlitSurface(image, NULL, surface, NULL); 
    SDL_UpdateWindowSurface(window); 
    SDL_Delay(500); 
} 
+0

Спасибо за ответ! Когда я помещаю функцию рендеринга изображения в цикл, вторая итерация вокруг него фактически отображает изображение. Поскольку я планирую сделать игру, которая должна отображаться постоянно, я не вижу проблемы с использованием Arch в качестве платформы разработки (которая является моей предпочтительной ОС). Еще странно, что первый вызов для отображения результатов на экране за окном, который нужно скопировать. И это не просто делает это при рендеринге изображения. Попытка окраски фона красным прямоугольником делает то же самое. –

+0

Если вы планируете сделать игру, конечно, вы не должны использовать SDL_UpdateWindowSurface(), который является «программным обеспечением», но [2D ускоренными функциями рендеринга] (https://wiki.libsdl.org/CategoryRender) или OpenGL. –