SDL issues (c++) - c++

I'm new to C++ and i have been following a tutorial on how to make pong using C++ and SDL. I've been following the tutorial word by word but now I've hit a road block. When i try to run i get an error saying that my SDL functions are not being recognized.
The error i get is: fatal error C1083: Cannot open include file: 'SDLmain': No such file or directory
Here is my code:
#include "SDL.h"
#include"SDL_ttf.h"
SDL_Surface screen;
SDL_Event occur;
void loadGame()
{
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
SDL_Surface* hello = NULL;
SDL_Surface* screen = NULL;
screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
}
int main (int argc, char* args[])
{
loadGame();
bool running = true;
while(running == true)
{
}
return 0;
}

You should check your SDL lib and include paths. Make sure you've set the correct directories for your IDE to find the sdlmain files it needs.

Under VC++ Directories, Include directories, you should have C:\sdl2.0\include (or wherever you put SDL and its include subfolder), along with whatever else your projects need.
If this is already set... which version of SDL are you using (1.x or 2.x)? Is your version of SDL_TTF, and any other SDL add-ons, the same version?

Make sure that "SDL_main.h" is in the same folder as "SDL.h".
From "SDL.h":
//[...]
/**
* \file SDL.h
*
* Main include header for the SDL library
*/
#ifndef _SDL_H
#define _SDL_H
#include "SDL_main.h"
#include "SDL_stdinc.h"
#include "SDL_assert.h"
//[...]

Related

main already defined in main.obj

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

Undefined reference when using glew and mingw?

I am using Eclipse, I had originally downloaded the binary from the website until someone pointed out that I needed to build it from source to make it work with mingw, so I did and I got these files: glew32.dll, libglew32.a, and libglew32.dll.a
I dropped the glew32.dll into the debug folder, and linked the libraries but it did not work.
The weird part: GLenum status = glewInit(); works but glClearColorand glClear do not work and I get a undefined reference to error when I try to call them.
Please see these screenshots: http://imgur.com/a/L8iNb and http://imgur.com/a/nYoWD
C++.cpp
#include <iostream>
#include "classHeaders\display.h"
#include "GL\glew.h"
int main(int argv, char** args){
display x(800,600,"something");
while(!x.isClosed()){
glClearColor(0.0f,0.15f,0.3f,1.0f); //undefined reference to ERROR here
glClear(GL_COLOR_BUFFER_BIT); //undefined reference to ERROR here
x.Update();
}
return 0;
}
display.cpp
#include "classHeaders\display.h"
#include "GL\glew.h"
#include <iostream>
display::display(int width, int height, const std::string& title){
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
m_window = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height, SDL_WINDOW_OPENGL);
m_glContext = SDL_GL_CreateContext(m_window);
GLenum status = glewInit(); //NO ERRORS OCCUR
if(status != GLEW_OK){
std::cerr << "glew failed to initialize" << std::endl;
}
m_isClosed = false;
}
display::~display(){
SDL_GL_DeleteContext(m_glContext);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
bool display::isClosed(){
return m_isClosed;
}
void display::Update(){
SDL_GL_SwapWindow(m_window);
SDL_Event e;
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
m_isClosed = true;
}
}
}
display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include <string>
#include "SDL2\SDL.h"
#undef main /*need to put this in or else it gives me "undefined reference to WinMain" ERROR*/
class display{
public:
display(int width, int height, const std::string& title);
void Update();
bool isClosed();
virtual ~display();
private:
display(const display& other){}
display& operator=(const display& other){}
SDL_Window* m_window;
SDL_GLContext m_glContext;
bool m_isClosed;
};
#endif /* DISPLAY_H_ */
To set up GLEW, a current OpenGL Context is needed (see Creating an OpenGL Context (WGL) for more information).
Create OpenGL context and window
A OpenGL Context and a window can easily created by SDL, GLFW or GLUT (see Initializing GLEW for more information).
Initilize SDL
If you are using SDL you have to create the window and you have to create the OpenGL context.
SDL_Window *window = SDL_CreateWindow(""OGL window", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL );
SDL_GLContext glContext = SDL_GL_CreateContext( window );
Note, you should check for errors with SDL_GetError.
The OpenGL context has to become the current context before you use it. Use SDL_GL_MakeCurrent therefor.
SDL_GL_MakeCurrent( window, glContext );
Initilize GLUT
To set up GLUT you have to use glutInit and can follow the instructions of initializing glew.
glutInit(&argc, argv);
glutCreateWindow("OGL window");
Initilize GLFW
Note, glfwInit returns GLFW_TRUE if succeded:
if ( glfwInit() != GLFW_TRUE )
return;
GLFWwindow *wnd = glfwCreateWindow( width, height, "OGL window", nullptr, nullptr );
if ( wnd == nullptr )
{
glfwTerminate();
return;
}
glfwMakeContextCurrent( wnd );
After you have created an OpenGL Context and you have made it become the current context, you have to initialize glew.
Set up GLEW
Note that glewInit returns GLEW_OK if succeded:
if ( glewInit() != GLEW_OK )
return;
To link the GLEW library correctly you have to set up proper preprocessor definitions:
On Windows, you also need to define the GLEW_STATIC preprocessor token when building a static library or executable, and the GLEW_BUILD preprocessor token when building a dll
See also the answer to GLEW Linker Errors (undefined reference to `__glewBindVertexArray')
So basically to solve this problem you want to download the source from the glew website and compiler it yourself. You use the command prompt to get in the directory of the folder you downloaded and execute these commands line by line in order:
gcc -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc -nostdlib -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.dll.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
and finnally:
gcc-ar cr lib/libglew32.a src/glew.o (though the "gcc-" may not be needed, it was for me)
Once you're done with that left click on your project and go to Properties, then under C/C++ Build go to settings, then under MinGW C++ Linker click in Libraries. Once you're there make sure your Library search path is correct (the place where Eclipse looks for your libraries) then in Libraries enter these one by one: glew32 opengl32 glu32 glew32.dll SDL2 SDL2main SDL2_test
Also when you compiled from source there should be a glew32 with a .dll not a .a extension in your lib folder inside the glew folder you downloaded from the website, drop that in into your debug (where your .exe is created). Do the same for the .dllnot the .dll.a for SDL and also make sure you have your include folders for both glew and SDL set up under the GCC C++ Compiler (also under your settings for the C/C++ Builder). It should work now.

Including SDL.h causes program to terminate immediately after building, and not run, but not give an error

This test program should create a blank window that stays open until you x-it-out. I copied it from SDL's documentation to make sure it is correct. It can be found here.
// Example program:
// Using SDL2 to create an application window
#include "SDL.h"
#include <stdio.h>
int main(int argc, char* argv[]) {
SDL_Window *window; // Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
//game loop, quitGame to quit
bool quitGame = false;
//var for checking events
SDL_Event event;
while(!quitGame) {
//Update particles
//Draw particles
//Check for events
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT)
quitGame = true;
}
}
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}
It doesn't create a window and terminates immediately, but gives no errors.
I'm using Eclipse, mingw32, and the latest stable release of SDL2. SDL2's libraries and headers are within a file in my C drive. I am using a 64 bit system. I include the entire folder of SDL2's header files. The only library folder I have linked is the one within the 64 bit part of the SDL2 folder. The libraries I have linked are the ones suggested by HolyBlackCat, (in this order) mingw32, SDL2main, and SDL2. Any help is greatly appreciated. Thanks!

dyld: Library not loaded...reason image not found?

I'm new to c++ and XCode, I'm using sdl2 to create a window but when i compile it, it crashes giving me a thread.I have included opengl.h , stdio.h and SDL2.h. There are questions about
dlyd:library not loaded but their different.
Error Message:
dyld: Library not loaded: #rpath/SDL2.framework/Versions/A/SDL2 Referenced from:
/Users/shayanrazavi/Library/Developer/Xcode/DerivedData/c++_code-bbdyozxqxxdxosbxuyhcrqobxrkd/Build/Products/Debug/c++
code
Reason: image not found
This is the code I used i couldn't get int main to be inside the code block for some reason but anyway and I got this code from https://wiki.libsdl.org/SDL_CreateWindow.
int main(int argc, char* argv[]) {
SDL_Window *window; // Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully made
if (window == NULL) {
// In the event that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// The window is open: enter program loop (see SDL_PollEvent)
SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}
I figured out why this was happening I was meant to put the framework in /Library/Frameworks folder before using it in XCode because when you download SDL it gives you a read me file and the read me file says to put it in that folder.
I should try reading all the text in read me files next time I guess. But if I try running this in XCode it will crash for some reason. (Makes sense because it says dyld: Library not loaded and we just put it in /Library/Frameworks)

SDL2 test works only when i start without debugging

i am trying to learn SDL2 from lazyfoo.net and i have quite a few problems (i've also been learning c++ since January so i do know some of what is going on, but not all of it), the first and most obvious one is that the "Hello world" appears only when i start without debugging, if i do debug it gives me "the program can't start because SDL2.dll is missing from your computer". which is not true at all. i put the .dll file into my current project's folder (which i have called TEST), the site just told me to put it in the same area as the .vxcproj file is, which is what i did...
also the tutorial tells me to type #include <SDL.h>, and when i do it says a lot of the stuff is undefined (i just copied and pasted this directly from the zip file at the bottom of the tutorial page), so i have to use #include <SDL2/SDL.h>
and the third one (that i managed to fix, sorta) is when putting the image onto the screen, it showed that it could not find the .bmp file, so i had to get the file into the source files section of visual studio. it works for this test but if i start incorporating multiple .bmp files it might become confusing. was i supposed to do that?
here is my code, which is almost identical to the one in the zip file
#include <SDL2/SDL.h> //first modification i did
#include <stdio.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
bool init();
bool loadMedia();
void close();
SDL_Window* gWindow = NULL;
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* gHelloWorld = NULL;
bool init()
{
bool success = true;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}
bool loadMedia()
{
bool success = true;
gHelloWorld = SDL_LoadBMP("hello_world.bmp"); //second modification
if (gHelloWorld == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", "hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void close()
{
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
SDL_DestroyWindow(gWindow);
gWindow = NULL;
SDL_Quit();
}
int main(int argc, char* args[])
{
if (!init())
{
printf("Failed to initialize!\n");
}
else
{
if (!loadMedia())
{
printf("Failed to load media!\n");
}
else
{
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);
SDL_Delay(2000);
}
}
close();
return 0;
}
HMMM
Your questions:
1
I'm also bothered, it would be better to use #including , and it would be better if you put those stuffs into the header file like stdafx or the header of your class to make it less confusing, there's a big chance you messed up on integrating your directories + your .dlls are not in a good place.
2
You're supposed to put all the dlls into the main project's folder's debug, the area where you see an exe, .pdb, and .ilk.
3
You used "hello_world.bmp", there's nothing wrong with that, it's your file's location, if you're going to run debug then place the files (the .bmp) inside... let's say you made a project named ABC, and placed it in a folder called ABC, there would be 3 folders called DEBUG (if you ran debug at least once), ipch, and ABC.
you're supposed to place the files inside the ABC folder which contains the .vcxproj, and other stuffs, then if you wanted to run your game using the .exe file in the mainfolder's debug folder then you're supposed to copy all the files you used (in this case, you used the .bmp) and paste them in that folder, the folder that contains the .exe, that way if you run debug, it would read in the ABC folder while if you personally go to the .exe file, it would read the files that are with it in it's folder.
#Skalli he clearly stated Visual Studio which means he is running Windows,
please when incorporating images, place them at the same directory as the exe you built when using Release mode. Look at the SDL library files, go to bin and copy the SDL2.dll and place it where your EXE is. Also to be able to run the program from the IDE, go to your Program Files x86 folder and go to your IDE folder, should be called "Microsoft Visual Studio XX" and go to the bin and paste the SDL2.dll
comment on my answer if the problem persists