7z. 7z. - 5 months ago 46
Linux Question

SDL2 on Arch Linux: window renders what's on the screen behind it

I've just started with SDL2, read a couple of articles on it and was able to compile the test program I've written on Arch Linux with success. The only problem that seems to be occurring, is that the window that's being created doesn't render the image. I've tried running the same code on Mac, which does result in the expected. I'm using CLion, which isn't the malefactor, because compiling with g++ through CLI results in the same.

My Arch Linux install:

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


Here's the code I'm compiling:

#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;
}


My CMakeLists.txt file (used by 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})


And the Unix command I've used to compile it with g++:

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


What it looks like when running the code on Arch:

Code run on Arch Linux

I should note that it only copies what's on the screen once, and doesn't update the window content. So when I move the window around, what's rendered in the window stays the same.

On Mac:

enter image description here

Have found a couple of articles also hinting at this issue, but the solutions to those articles do not work for me. Specifically, I'm talking about these articles.

SDL - window doesn't show anything

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

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

Hope that I've provided enough information, and that there's someone out there that has experienced the same issue and has been able to resolve it. Thanks in advance!




Edit after keltar's comment (still not doing what it's supposed to):

#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;
//}

Answer

I have run your code on Ubuntu 14.04 without any problem. In order to check if its a 'rendering driver' issue on Linux, could you run my little GPL game from the command line and copy-paste the info displayed in the console ?

You should see something like this:

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

I encountered the same kind of problem on CentOS 5 when the 'SDL_RENDERER_PRESENTVSYNC' flag is ON in the renderer or as long as you don't copy any texture to a renderer.

Another idea, what happens when you do this ?

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