I have the following code in main.cpp:
#include <SDL2/SDL.h>
#include <iostream>
int main(){
SDL_Init(SDL_INIT_VIDEO);
bool quit = false;
SDL_Event event;
SDL_Window * window = SDL_CreateWindow("Chess",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 640, 0);
SDL_Delay(100);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Surface * board = SDL_LoadBMP("board.bmp");
if (board == NULL) {
std::cout << "The image 'board.bmp' could not be loaded due to the following SDL error: " << SDL_GetError() << std::endl;
return 1;
}
else {
std::cout << "The image 'board.bmp' was loaded successfully" << std::endl;
}
SDL_Texture * board_texture = SDL_CreateTextureFromSurface(renderer, board);
if (board_texture == nullptr){
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_RenderCopy(renderer, board_texture, NULL, NULL);
while (!quit)
{
SDL_WaitEvent(&event);
SDL_RenderPresent(renderer);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
}
SDL_Delay(15);
}
SDL_DestroyTexture(board_texture);
SDL_FreeSurface(board);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Both error checks return nothing, and I can't figure out why.
Also, I build using:
g++ chess.cpp -o chess -I include -L lib -l SDL2-2.0.0
This seems to work for my Windows PC, but not on my Intel Macbook Pro. Are there any solutions/workarounds available?
As documentation says
The backbuffer should be considered invalidated after each present; do
not assume that previous contents will exist between frames. You are
strongly encouraged to call SDL_RenderClear() to initialize the
backbuffer before starting each new frame's drawing, even if you plan
to overwrite every pixel.
So it should be:
SDL_WaitEvent(&event);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, board_texture, NULL, NULL);
SDL_RenderPresent(renderer);
Related
Here is some sample SDL2 code I tried to run on my Linux computer running Ubuntu 18.04 with KDE Plasma Desktop Environment (I have multiple desktop environments installed in case it is relevant):
#include<iostream>
#include<SDL2/SDL.h>
int main(int argc, char** argv)
{
if(SDL_Init(SDL_INIT_VIDEO) != 0){
std::cerr << "SDL_Init() Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window* win = SDL_CreateWindow(
"Hello world",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640,480,
0
);
if(win == nullptr){
std::cerr << "SDL_CreateWindow() Error: " << SDL_GetError() << std::endl;
return 1;
}
//Create and init the renderer
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, 0);
if(ren == nullptr){
std::cerr << "SDL_CreateRenderer() Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(win);
return 1;
}
//Render something
SDL_RenderSetLogicalSize(ren,640,480);
//Set colour of renderer
SDL_SetRenderDrawColor(ren,255,0,0,255);
//Clear the screen to the set colour
SDL_RenderClear(ren);
//Show all the has been done behind the scenes
SDL_RenderPresent(ren);
//Delay so that we can see what is on the screen
SDL_Delay(5000);
//Clean Up
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
The red window that is supposed to appear appears only once when I run the program for the first time. All subsequent executions produce an empty transparent window with whatever is in the background. The background image drags along with the window.
I have tried SDL_WINDOW_SHOWN flag in SDL_CreateWindow() as well as SDL_RENDER_ACCELERATED flag for SDL_CreateRenderer().
The only way to produce the red screen again is to reboot the system.
I even compiled and ran this with an IDE (CodeLite) and I still got the same results.
This particular question on SO shows similar problems. But the OP isn't using Linux and the problem isn't exactly the same.
Other posts on this website mention event processing but I haven't gotten that far. If at all it is necessary, I would be grateful for some resources on it as the documentation doesn't explain much.
Update:This program runs fine on another computer running Lubuntu 18.10.
Replace the SDL_Delay() (which blocks all event processing like notifying X11/Wayland & your window manager that your process is still alive) with a loop that calls SDL_PumpEvents() somehow, either directly (like below) or indirectly via SDL_PollEvent()/SDL_WaitEvent():
const Uint32 startMs = SDL_GetTicks();
while( SDL_GetTicks() - startMs < 5000 )
{
SDL_PumpEvents();
//Render something
SDL_RenderSetLogicalSize(ren,640,480);
//Set colour of renderer
SDL_SetRenderDrawColor(ren,255,0,0,255);
//Clear the screen to the set colour
SDL_RenderClear(ren);
//Show all the has been done behind the scenes
SDL_RenderPresent(ren);
}
All together:
#include <iostream>
#include <SDL2/SDL.h>
int main( int argc, char** argv )
{
if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
{
std::cerr << "SDL_Init() Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window* win = SDL_CreateWindow
(
"Hello world",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640, 480,
0
);
if( win == nullptr )
{
std::cerr << "SDL_CreateWindow() Error: " << SDL_GetError() << std::endl;
return 1;
}
//Create and init the renderer
SDL_Renderer* ren = SDL_CreateRenderer( win, -1, 0 );
if( ren == nullptr )
{
std::cerr << "SDL_CreateRenderer() Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow( win );
return 1;
}
const Uint32 startMs = SDL_GetTicks();
while( SDL_GetTicks() - startMs < 5000 )
{
SDL_PumpEvents();
//Render something
SDL_RenderSetLogicalSize( ren, 640, 480 );
//Set colour of renderer
SDL_SetRenderDrawColor( ren, 255, 0, 0, 255 );
//Clear the screen to the set colour
SDL_RenderClear( ren );
//Show all the has been done behind the scenes
SDL_RenderPresent( ren );
}
//Clean Up
SDL_DestroyRenderer( ren );
SDL_DestroyWindow( win );
SDL_Quit();
return 0;
}
I'm creating a window and drawing a box but for some reason instead of drawing a box, the screen is just changed to that color. I have attached a photo of how the window looks and I will attach the source code.
#include <iostream>
#include <SDL.h>
#undef main
using namespace std;
int SCREEN_WIDTH = 650;
int SCREEN_HEIGHT = 650;
int main() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *window = SDL_CreateWindow("Cells", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == nullptr) {
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
SDL_Event event;
bool quit = false;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
SDL_RenderClear(renderer);
// renderTextures
SDL_Rect fillRect = { 122, 122, 122, 122};
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
}
return 0;
}
Doesn't Draw Correctly
SDL_RenderClear uses current draw colour, which you modified, so your clear and rectangle colour is the same. Set different clear colour (the one you want at background where nothing else is drawn) with e.g.
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// now draw your rectangles with different col
The program doesnt show the image in the window i have created , also i dont get any of the fail messages that i have set , which means the values are not null.
What is the problem?
Here is the code:
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
int main(int argc,char* argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Event event;
bool quit = false;
SDL_Surface *tmpsur = NULL;
SDL_Texture *tex = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("First window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
tmpsur = IMG_Load("assets/player.png");
if (tmpsur == NULL)
{
std::cout << "fail" << std::endl;
}
tex = SDL_CreateTextureFromSurface(renderer,tmpsur);
if (tex == NULL)
{
std::cout << "fail 2" << std::endl;
}
SDL_FreeSurface(tmpsur);
SDL_RenderPresent(renderer);
while (!quit)
{
while (SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
You need to copy your texture onto the render target. Before presenting your renderer you need to call SDL_RenderCopy like this:
SDL_RenderCopy(renderer, text, nullptr, nullptr);
SDL_RenderPresent(renderer);
The nullptrs in the argument will make it copy the texture over all your target (the window).
i've installed SDL to develop a program, and while on the test phase for this lib, the compiled code does not execute, and i mean it won't even open the cmd box. The weird thing is, it occasionally executes.
I'm using Eclipse Hellios with minGW32 and i686-w64-mingw32 on windows10.
My test code is:
#include <iostream>
#include <Windows.h>
#include <SDL2/SDL.h>
int main(int, char**)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 1;
SDL_Window *window = SDL_CreateWindow("", 300, 100, 1024, 800, SDL_WINDOW_OPENGL);
if (window == NULL)
{
std::cout << "SDL init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface *background = SDL_LoadBMP("Resources/Lilothyn.bmp");
if (background == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background init error", SDL_GetError(), window);
return 1;
}
if (renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, background);
if (texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Texture init error", SDL_GetError(), window);
}
SDL_RenderPresent(renderer);
SDL_Event event;
bool running = true;
while(running)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
running = false;
SDL_DestroyTexture(texture);
SDL_FreeSurface(background);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
break;
default: break;
}
}
return 0;
}
the odd thing is, i previously had "SDL_LoadBMP("Resources/TommyBMP.bmp");" and it executed properly. Changing a string shouldn't make the program stop working, both files are at the Debug/Resources folder so it can't be a case of not finding them...
note: further testing shows that a simple "hello world" has the same issue, so the problem will likely not be from SDL.
"help me obi wan, you're my only hope".
I am having troubles with SDL_Texture
RPGTutorial.cpp
#include "stdafx.h"
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = NULL;
window = SDL_CreateWindow("RPG Tutorial!", 100, 100, 600, 400, SDL_WINDOW_SHOWN);
if (window == NULL)
{
std::cout << "Window couldn't be created" << std::endl;
return 0;
}
SDL_Renderer* renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
std::cout << "Renderer is not being created!" << std::endl;
SDL_DestroyWindow(window);
system("PAUSE");
return 0;
}
SDL_Event* mainEvent = new SDL_Event();
SDL_Texture* grass = NULL;
grass = IMG_LoadTexture(renderer, "Grass.bmp");
if (grass == NULL)
{
std::cout << "Grass Image was not found!" << std::endl;
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
system("PAUSE");
return 0;
}
SDL_Rect grass_rect;
grass_rect.x = 0;
grass_rect.y = 0;
grass_rect.w = 64 * 2;
grass_rect.h = 64 * 2;
while (!quit && mainEvent->type != SDL_QUIT)
{
SDL_PollEvent(mainEvent);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, grass, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
stdafx.h
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <iostream>
I have the Grass.bmp in the RPGTutorial->RPGTutorial->Grass.bmp
When I compile it, it is successful. It runs through the code til I get to the part where it checks if(grass == NULL) and it goes through that and exits. Can someone help me know why my grass is not being set to the image when I have the image in the same folder that the .cpp files are in? I even tried adding an Image folder to hold it in, and it did not work either.
If you have the time, I recommend you take some time to go through the Lazyfoo tutorials they are fantastic. He mentions this issue in the second tutorial, "Getting an Image on the Screen."
Visual Studio changes your current working directory to the place where your .vcxproj file is. That will be the directory you want to place your resources in. If you're not sure where that is, you can use the _getcwd() function in the direct.h header MSDN Source For getcwd