I have started to make a game in C++ with SDL. My Code is:
main.cpp
#include "SDL/SDL.h"
#include "gameSystem.h"
int main(int argc, char *args[])
{
gameSystem systemHandler;
SDL_Surface *buffer;
SDL_Event event;
while(event.type != SDL_QUIT)
{
SDL_PollEvent(&event);
SLD_Flip(buffer);
}
}
gameSystem.cpp
#include "SDL/SDL.h"
#include "gameSystem.h"
gameSystem::gameSystem()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_WM_SetCaption("GameName", NULL);
SDL_Surface *buffer;
bool fullscreen = false;
if (fullscreen == true)
{buffer = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_FULLSCREEN);}
else
{buffer = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);}
}
gameSystem::~gameSystem()
{
SDL_Quit();
}
gameSystem.h
class gameSystem
{
public:
gameSystem();
~gameSystem();
private:
SDL_Surface *buffer;
};
My linker options include: -lmingw32 -lSDLmain -lSDL -lwinmm -sdl_Mixer
I get the following error: "error: 'SLD_Flip' was not declared in this scope" on line 12 of main.cpp.
All the other SDL functions seem to be fine.
Does anyone know how to fix this problem?
You misspelled it. It should be SDL_Flip, not SLD_Flip.
Also, you haven't initialized your variable buffer in main. You are not setting its value inside of gameSystem::gameSystem(); the variable is out of scope.
Related
Basically im trying to create a game with SDL2 and Opengl, but I cant get passed this error. I've tried changing SDL_main(int argc, char *argv[]) to regular main but nothing changes. I know this error is due to the SDL_main library but I don't know how to fix it. I've been searching info for some hours now but can't figure it out, the only thing related to this problem I've found is this post, which didn't fix my problem.
Common.h
#ifndef _COMMON_H
#define _COMMON_H
/*=======STANDARD TEMPLATE LIBRARY=======*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <memory>
#include <ctime>
#include <vector>
using namespace std;
/*=======GLU/GLEW=======*/
#include <GL/glew.h>
#include <GL/glu.h>
#include <GL/gl.h>
/*=======SDL2=======*/
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_image.h>
/*=======CLASS DEFINITIONS=======*/
#endif
Main.cpp
#include "common.h"
bool isRunning = true;
int SDL_main(int argc, char *argv[])
{
//Error Checking/Initialisation
if (SDL_Init(SDL_INIT_NOPARACHUTE & SDL_INIT_EVERYTHING) != 0) {
SDL_Log("Unable to initialize SDL: %s\n", SDL_GetError());
return -1;
}
else
{
//Specify OpenGL Version (4.2)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Log("SDL Initialised");
}
//Create Window Instance
SDL_Window* window = SDL_CreateWindow(
"Game Engine",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640,
480,
SDL_WINDOW_OPENGL
);
//Check that the window was succesfully created
if(window == NULL)
{
//Print error, if null
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
else
SDL_Log("Window Successful Generated");
//Map OpenGL Context to Window
SDL_GLContext glContext = SDL_GL_CreateContext(window);
//Render
//Swap Render Buffers
SDL_GL_SwapWindow(window);
//Free up resources
SDL_GL_DeleteContext(glContext);
SDL_Quit();
return 0;
}
Error output
./src/lib/SDL2main.lib(x64/Release/SDL_windows_main.obj):(.text[main]+0x0): multiple definition of `main'
C:/Program Files/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x0): first defined here
Makefile
all:
g++ -I ./src/include -L ./src/lib -o ./Builds/Win_Build/engine main.cpp -lmingw32 -lSDL2main -lSDL2 -lmingw32 -lopengl32 -lglew32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_ttf --verbose
Lib folder
EDIT:
I fixed it by redownloading the libraries and using the .a extension ones. And also I changed the version of Glew to 64 bits. My new lib folder:
I'm trying to set up an SDL project with Visual Studio 2019 using this article:
https://www.wikihow.com/Set-Up-SDL-with-Visual-Studio
but the compiler is throwing me the errors 'one or more multiply defined symbols found' and
'_main already defined in main.obj'.
main.obj is a file in the debug folder of my project but when I try deleting it or the entire debug folder, VS recreates it when I run the project.
I've read that c++ can't have more than one main function but I can't open the main.obj file and I don't really want to delete the one in main.cpp
Here's the code I'm running and thanks for your help!
#include "SDL.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow
("An SDL2 window", // window's title
10, 25, // coordinates on the screen, in pixels, of the window's upper left corner
640, 480, // window's length and height in pixels
SDL_WINDOW_OPENGL);
SDL_Delay(3000); // window lasts 3 seconds
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Glad to know it works now. Maybe you had a messy file structure with your previous SDL installation. Anyways, I think it might be interesting to show how the SDL dependency can be removed from your main.cpp file, to avoid such problems in the future.
First, let's consider the example in your question. The example is not very useful in practice, but I'll show a better version after.
The main idea is hiding everything that has to do with SDL from your main.cpp and headers.
1. Simple Example
// MySDL.h - NO SDL STUFF
class MySDL
{
public:
MySDL() = default; // or whatever you need
void runtest() const; // here we'll run the 3sec window
};
Now, we can put all our SDL stuff in the cpp file:
// MySDL.cpp
#include "MySDL.h"
#include "SDL.h" // HERE WE INCLUDE SDL
void MySDL::runtest()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
}
No SDL included in main.cpp, we just include our SDL interface MySDL.h.
// Now you can use your SDL interface like this
int main(int, char* [])
{
MySDL sdl;
sdl.runtest();
return 0;
}
2. Better Version
However, you would typically want something more sofisticated than a window which disappears in 3 seconds. Therefore, you might want to store class members which depends on SDL. But then, you would have to #include "SDL.h" in your MySDL.h header file, which would give you the same problems as described in your question and comments. To remove this dependency, we can use the pimpl idiom.
The header file now includes a pointer to our SDL implementation. This SDL implementation will be defined in the cpp file in order to remove the SDL dependency.
// MySDL.h
class MySDL
{
public:
MySDL() = default; // or whatever you need
~MySDL();
void doSmthWithYourWindow(/*args*/);
private:
// pointer to our SDLImplementation (defined in cpp file)
class SDLImplementation;
std::unique_ptr<SDLImplementation> _sdl;
};
In our cpp file, we define the SDLImplementation, and MySDL has access to that implementation through the _sdl pointer.
// MySDL.cpp
#include "MySDL.h"
#include "SDL.h"
// here we can store class members which depend on SDL
struct MySDL::SDLImplementation
{
SDLImplementation()
{
SDL_Init(SDL_INIT_EVERYTHING);
_window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);
_renderer = SDL_CreateRenderer(_window, -1, 0);
SDL_SetRenderDrawColor(_renderer, 0, 255, 0, 255);
SDL_RenderClear(_renderer);
SDL_RenderPresent(_renderer);
}
// functionality of your SDL implementation
void turnWindowUpsideDown() { /* _window->turnUpsideDown(); */ }
// members depending on SDL
SDL_Window* _window;
SDL_Renderer* _renderer;
};
MySDL::~MySDL() = default;
void MySDL::doSmthWithYourWindow(/*args*/)
{
// here we have access to our SDL implementation
_sdl->turnWindowUpsideDown();
}
Just like before, we only include our MySDL.h interface in the main.cpp file.
int main(int, char* [])
{
MySDL sdl;
sdl.doSmthWithYourWindow();
return 0;
}
So I ended up deleting SDL and completely restarting with a different tutorial linked here:
https://www.youtube.com/watch?v=QQzAHcojEKg
Not really sure what the difference was but it worked. Anyways, thanks for your help and I'll put the new code here.
#include "SDL.h"
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
return 0;
}
I am trying to use the SDL_image library so I can display a .png file in a window made using SDL2 library.
My problem is when ever I compile the code I get a lot of errors of about deceleration and stuff in the SDL header files. I'm using Eclipse on Ubuntu LTS 16.04
I am not entirely sure of what the problem is and how I can solve this so a step by step of what, why and how so I can fully understand it would be
great
Answer to question is in comments of this post.
Here are my Errors
In file included from /usr/include/SDL2/SDL.h:52:0,
from /usr/include/SDL2/SDL_image.h:27,
from temp.cpp:12:
/usr/include/SDL2/SDL_render.h:116:3: error: conflicting declaration
‘typedef enum SDL_RendererFlip SDL_RendererFlip’
} SDL_RendererFlip;
^
In file included from /usr/local/include/SDL2/SDL.h:52:0,
from temp.cpp:11:
/usr/local/include/SDL2/SDL_render.h:116:3: note: previous declaration
as
‘typedef enum SDL_RendererFlip SDL_RendererFlip’
} SDL_RendererFlip;
^
In file included from /usr/include/SDL2/SDL.h:57:0,
from /usr/include/SDL2/SDL_image.h:27,
from temp.cpp:12:
/usr/include/SDL2/SDL_version.h:51:16: error: redefinition of ‘struct
SDL_version’
typedef struct SDL_version
`
Here is my code
#include <iostream>
#include <string>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Surface* surface;
SDL_Texture* texture;
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_JPG);
window = SDL_CreateWindow(
"SDL Window",
100,
600,
1200,
700,
SDL_WINDOW_OPENGL);
if (window == NULL)
{
cout << "Could not create window: \n" << SDL_GetError() <<
endl;
return 1;
}
renderer = SDL_CreateRenderer (window, -1, 0);
surface = IMG_Load("introtext.png");
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(5000);
SDL_DestroyTexture(texture);
SDL_FreeSurface(surface);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}
I am a SDL beginner.
I would like to draw a black background and a filled blue circle on it with SDL2. As there is no way to draw a circle with SDL2, I use SDL2_gfx. I have no problem to draw a black background, but I do not arrive to draw a circle with the function filledCircleRGBA.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL2_gfxPrimitives.h>
#define DEFAULT_WINDOW_WIDTH 800
#define DEFAULT_WINDOW_HEIGHT 600
void
print_SDL_error()
{
fputs("SDL_Error: ", stderr);
fputs(SDL_GetError(), stderr);
fputc('\n', stderr);
}
bool
initSDL()
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "SDL could not initialize!\n");
print_SDL_error();
return false;
}
return true;
}
SDL_Window*
initMainWindow()
{
SDL_Window* window;
window = SDL_CreateWindow("SDL2 test",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
SDL_WINDOW_SHOWN);
if(window == NULL)
{
fprintf(stderr, "SDL could not create a window!\n");
print_SDL_error();
}
return window;
}
SDL_Window*
initSDLAndMainWindow(SDL_Window* * window)
{
return initSDL() ? initMainWindow() : NULL;
}
void
quit(SDL_Window* main_window)
{
SDL_DestroyWindow(main_window);
SDL_Quit();
}
int
main(int argc, char* argv[])
{
SDL_Window* main_window;
main_window = initMainWindow();
if(main_window == NULL)
{
quit(NULL);
return EXIT_FAILURE;
}
SDL_Renderer* main_window_renderer;
main_window_renderer = SDL_CreateRenderer(main_window, -1, SDL_RENDERER_ACCELERATED);
if(main_window_renderer == NULL)
{
fprintf(stderr, "Renderer could not be created!\n");
print_SDL_error();
quit(main_window);
return EXIT_FAILURE;
}
SDL_SetRenderDrawColor(main_window_renderer, 0, 0, 0, 0);
SDL_RenderClear(main_window_renderer);
SDL_RenderPresent(main_window_renderer);
SDL_Delay(2000);
if(filledCircleRGBA(main_window_renderer,
150, 150, 75,
0, 0, 255, 0) != 0)
{
fprintf(stderr, "A circle was not rendered!\n");
print_SDL_error();
SDL_DestroyRenderer(main_window_renderer);
quit(main_window);
return EXIT_FAILURE;
}
SDL_RenderPresent(main_window_renderer);
SDL_Delay(2000);
SDL_DestroyRenderer(main_window_renderer);
quit(main_window);
return EXIT_SUCCESS;
}
I am running under Debian GNU/Linux 8 "Jessie", and I use libsdl2-dev and libsdl2-gfx-dev of my distribution.
To compile, I use gcc -O0 -g sdl2-test.c `sdl2-config --cflags --libs` -lSDL2_gfx.
Moreover, valgrind notifies me that there are 21 errors from 21 contexts. 3 errors come from SDL2 calls, and 19 from nouveau_dri.so that I suppose to be the shared library used by nouveau driver (a free/libre driver for nVidia GPU) so this ones may not be my fault.
Thanks.
You are calling filledCircleRGBA with an alpha value of 0. Your circle is completely transparent.
For the errors reported by Valgrind, I just noticed you are not actually calling SDL_Init. This is causing some leaks, but not all of them. The others aren't caused by your code.
I also see some Conditional jump or move depends on uninitialised value(s). Valgrind can reports where the uninitialised value was created with the --track-origins=yes option, that way you can see if you passed an uninitialised value to a library function or if the error is in the function.
You can create a suppression file for Valgrind to hide the leaks that aren't yours. It is best to have the debug symbols for the libraries if you want to create rules specific enought to avoid hiding cases where you create something with an SDL function and don't destroy it.
I am currently attempting to write a very simple 2d game engine using SDL in order to help myself get more comfortable with coding. Unfortunately, I made the mistake of starting with a single source file, and now that my code is getting bigger, I am trying to split the existing code (which works fine before the split) into multiple header and source files. The first major issue I've encountered is that when I try to define SCREEN_HEIGHT, SCREEN_WIDTH, Window, and Renderer in init.cpp after declaring them in init.h, I get error: 'blank' does not name a type (blank being Window, Renderer, etc.). I am also trying to make them global, which may be part of the issue. Included below is the relevant code (I took out all the stuff I think is irrelevant in this case). I suspect I'm just missing something really simple here, but I've been unable to find an existing answer online like I have with my previous problems.
main.cpp
#include "globals.h"
#include "texture.h"
....
globals.h
#ifndef GLOBALS
#define GLOBALS
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#endif //GLOBALS
texture.h
#ifndef TEXTURE
#define TEXTURE
#include "globals.h"
#include "init.h"
....
#endif // TEXTURE
texture.cpp
#include "texture.h"
....
init.h
#ifndef INIT
#define INIT
#include "globals.h"
//screen dimensions
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
//initiates SDL and creates a window and renderer
bool init();
//the created window
SDL_Window* Window;
//the renderer that will be used
SDL_Renderer* Renderer;
#endif // INIT
init.cpp
#include "init.h"
SCREEN_WIDTH = 640;
SCREEN_HEIGHT = 480;
Window = NULL;
Renderer = NULL;
bool init()
{
bool success = true;
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
{
printf( "SDL was unable to initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf( "Linear texture filtering not enabled!");
}
else
{
Window = SDL_CreateWindow( "Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( Window == NULL)
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
Renderer = SDL_CreateRenderer( Window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if( Renderer == NULL)
{
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
SDL_SetRenderDrawColor( Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int PNGImage = IMG_INIT_PNG;
if( !(IMG_Init( PNGImage) & PNGImage))
{
printf( "Image loading not enabled! SDL_Image Error: %s\n", IMG_GetError());
success = false;
}
if( TTF_Init() == -1)
{
printf( "True type fonts not enabled! SDL_TTF Error: %s\n", TTF_GetError());
success = false;
}
}
}
}
}
return success;
}
I get the error in init.cpp at the top of the code before bool init()
Renderer = NULL; is an assignment statement, which you cannot have in global scope. You can only have declarations in global scope. Since you have already declared Renderer in your header file, you don't need to redeclare it either. Just set it to null within one of your initialization functions (e.g. your current init() function).