I can't make SDL + OpenGL work in Visual Studio 2012 - c++

I just started a tutorial to learn C++ OpenGL using SDL. The steps shown in the videotutorial were done by using the IDE called Code Blocks, but I thought it was going to work also for Visual Studio 2012.
I downloaded the SDL2 developer which is for Windows x64 (my Windows 7 is 64 bits, but the Visual Studio 2012 I have is an x86 version)
To install the SDL2 in Visual Studio 2012, I put:
the .h files in the include folder (D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\SDL).
the .lib files in the lib folder (D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\SDL).
the .dll file in C:/Windows/system folder.
After that, I opened the IDE, made a new project and while I was writting the code, autocompletion popped up for specific SDL features, meaning success... until I tried to run it.
This is the code I wrote according to the videotutorial:
#include "SDL.h"
int main(int argc, char* args[]){
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
When I click on "Start Debugging" or "Start without debugging", after pressing yes to build it, the output comes with errors.
Here's a screenshot of the code I wrote, plus the output:
After that, I tried an older version of the SDL the tutorial was already using, which was the 1.2 (I overwrote few files of the newer version) but still no good results.
How do I fix it so I can practice with OpenGL + SDL features?

TLDR:
When you use a library in your project,
Compiling needs header filenames (#include <*.h>) and include directories containing them
Linking needs lib filenames (*.lib, what you're missing) and library directories containing them
Running needs dynamic libraries (*.dll), commonly using the same name as the .lib in the current or system directory (VS has binary directories too but I've never needed to know what they're for exactly)
When you compile code and add #include <SDL.h>, the compiler runs through a list of possible directories its been given to find that file. There are some default directories already set up, but so you don't have a mess of all your libraries in one place it's possible to add more. For example, Setting Global C++ Include Paths in Visual Studio 2012 (and 2011, and 2010). If your SDL.h is in a subdirectory in an include directory it won't be found - eg. just check this shouldn't be <SDL/SDL.h> or something similar.
With the include path set and the correct #include your code can compile. Now it's the linking stage. You've got some code that says I need the these functions and the linker has to either find the actual code for those functions and link them statically (all the code can be found in the .lib) or set up the program to link at runtime, dynamically (in which case the program needs to be able to find the .dll, and I think on windows you need a .lib file that goes with it).
So in addition to the include directory you need a library directory. Also, just like you said to the compiler #include <SDL.h> you need to tell the linker to look for the code for those functions defined in SDL.h in SDL.lib (which may end up actually providing the code at runtime when loading SDL.dll). I think specifying libraries could even be done through #pragma calls, but it's more common to see the library files specified as arguments to the linker program. As #ScottMcP-MVP said, append SDL.lib to the Project Properties->Configuration Properties->Linker->Input->Additional Dependencies list. If it still says unresolved external that generally means the linker still can't find the file, so check for typos and double check the directories. Worst case is a mismatch between SDL.h and SDL.lib or SDL.lib was compiled with different options or a different compiler.
The error you're receiving is the linker saying the compiler says I need an "external" function, SDL_Init, to make your code work but I haven't found/resolved-the-reference-to one in the list of libraries I've been given.
Just as an example/recap all these GUI options end up going to the compiler/linker. So for example a full compile line might look like this:
./compiler -I/path/to/my/includes -L/path/to/my/lib -lmylibrary.lib mycode.cpp -o myexecutable.exe
Where mycode.cpp contains #include <mylibrary.h>. Note that here the ./compiler is operating as both compiler and linker. The process could be split into:
./compiler -I/path/to/my/includes mycode.cpp -o mycompiledcode.o
./linker -L/path/to/my/lib -lmylibrary.lib mycompiledcode.o -o myexecutable.exe
Once you have your executable it needs to be able to find SDL.dll when you run it. Exactly as you've done, the executable should search the windows system directory. It should also search its current directory. On linux you can set an rpath (not sure on windows). If you keep getting application configuration incorrect and the dll is definitely there it's time to grab dependency walker and see what dll name the program is actually trying to load. Worst case is the application finds a different version of the dll or something else with the same name before the desired one.
Good luck. OpenGL is great fun!!
[EDIT]
You can use either x32 or x64 lib files, but all your code must be the same. It'll probably be easier to start with x32, and if you need fast double computation and more ram then change. OpenGL doesn't have great support for x64 yet so it probably won't make much difference to you.
Additional Dependencies is where you put just "SDL.lib". This file then needs to exist in one of visual studio's library directories. If you don't get unresolved externals from SDL anymore then that part is fixed.
Your _main error is probably to do with a disgusting hack *spit* SDL uses. Straight after #include <SDL.h> put #undef main (may want to surround in #ifdefs in case it changes):
#include <SDL.h> //my include is <SDL2/SDL.h>, as I have both an SDL and SDL2 dir in my include path
#ifdef main
#undef main //remove SDL's main() hook if it exists
#endif
An important thing to note: generally use </> to include external libraries and "/" to include headers within your project - What is the difference between #include <filename> and #include "filename"?

You have to link the lib file into your exe. See Project, Properties, Link, Additional Dependencies. Put the name of the lib file there.

Related

C++ Code::Blocks making libraries on Windows

So I'm using Code::Blocks right now as my IDE on Windows 10 and I made a small library with one little function.
Code::Blocks made me a .a file.
I then made a little test project that uses the library. Added it to my project build options in Linker Settings, and added its directory to my search directories. Great.
I can see the header file I made for the library so that's working.
I then try to use the function and I'm getting an 'undefined reference' for that function call.
So..I'm going to assume Windows doesn't understand how to load libraries with the '.a' extension? I believe Windows uses .lib files instead but I'm not sure how else I'm supposed to compile a .lib file in Code::Blocks as there's no template for it.
I am extremely new to Code::Blocks and making libraries in general.
Solved. Problem was when renaming the file from "main.c" to "main.cpp", Code::Blocks does not automatically change the compiler variable.
This was done by going into the file properties in the IDE and changing the variable from "CC" to "CPP".

Visual Studio (C++) is automatically linking against an unwanted version of lib file

I am trying to create a C++ project in Visual Studio 2013 that has CGAL and Boost (and a couple of other libraries) as dependencies. I preferably like to link to these libraries dynamically. Also, I'd like to link to the "Release" versions of these libraries for performance reasons (not the "Debug" versions).
Starting from an empty C++ project, I added the path to header files of the aforementioned libraries as shown in the image below:
Inside the linker options, I then added the directories that contain the DLL and lib files of the external libraries. (CGAL directory contains CGAL's compiled DLL files along with lib files).
At this point, I have not added a single "lib" file "Additional Dependencies" dialog:
Now something weird is going on and I cannot explain why. If I try to build the project as-is (under the "Debug" configuration), I get a LNK1104 error about the linker not being able to find CGAL-vc120-mt-gd-4.7.lib. I know that the error means I should add the lib file in "Additional Dependencies" dialog...
But wait... WHAT...?!!
How does Visual Studio know how to automatically link against this lib file?! Worse yet, how does it know it needs the "debug" version of the library? (With the gd suffix). Also, how does it know I compiled CGAL with VS2013!!??
At first, I though the project was inheriting properties from some preset property sheets somewhere in my system. But I am certain that's not the case as this behavior shows even with a project created from scratch.
My main question is, how would you force Visual Studio to link against the "Release" version of this library? (eg. CGAL-vc120-mt-4.7.lib)
Side question but related: Am I even linking against the DLL files? How can I be certain that I am in deed doing dynamic linking and not static linking?
This is probably happening due to the #pragma comment(lib) mechanism - eg see What does "#pragma comment" mean?
This is a way of the compiler emitting instructions for the linker so that it can decide between multiple versions of a library depending on the compiler version. In this case it means that it can automatically pick up the correct version of the library (debug vs release, vs2013 vs vs2015, MT vs MD, etc). When you added the explicit reference to the library in Additional Dependencies then it is now trying to look for two files.
So, to fix the problem, remove it from Additional Dependencies and let VS pick the right library. If you are getting the LNK1104 error then it suggests that either the link library path isn't set up correctly, or you don't have the CGAL library file it's looking for. You can increase the verbosity settings for the linker in the Project Options to get more detail about what's happening.

Using OpenGL with Visual Studio 2013 Express

To give you an idea of what I am really trying to do. My goal is to create a c++ program in Visual Studio and using OpenGl display a blackscreen and a white dot in the middle of the screen.
Before I can even get to the coding part though, I have to include the OpenGL library somehow.
Looking at OpenGL documentation they say that it's already installed, I just need to initialize it.
I'd rather not have to do all the initialization work as it's already been done several times, such as FreeGLUT, but I have 2 real problems that I currently just do not understand.
1) How do I compile FreeGlut?
I've downloaded the source code for FreeGLUT here http://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz?download
I configured it with CMAKE into a visual studio 2013 compatible project.
but once I open it with Visual Studio and try to compile it, I get a bunch of errors saying:
Error C1083: Cannot open include file: 'EGL/egl.h': No such file or directory c:\freeglut-3.0.0\include\gl\freeglut_std.h 136 1 One_static
2) Once I get it compiled, how do I link it to my c++ project so that I can do
#include<FreeGLUT.h>
or
#include <GL/glut.h>
?
Most likely CMake did configure it wrong; EGL is used in embedded systems (think Android, set-top boxes, and such) not Windows. Double check that CMake does something sensible there.
After you've built FreeGLUT copy it somewhere convenient (do not copy it into the Visual Studio installation directory) and add the directories where you placed FreeGLUT to your own OpenGL project's compiler and linker search paths (reachable in the Visual Studio Build configuration).
Personally I place customly built libraries at
C:\local\include\ (the header files)
and
C:\local\lib (the .lib, .a and .dll files)
I also tend to give libraries an architecture infix like x86_32 or x86_64. e.g. freeglut-x86_64.dll. It's unlikely Windows will ever get some kind of "fat binary" in which the code for several architectures can be merged.
For convenience put the DLL path into the system search path for DLLs. When deploying your program copy the required DLLs into the same directory as the EXE files.

How can I run a .exe file on any Windows computer?

My friend wanted me to make him this program and he is not very tech savvy. How can I make the .exe run without making him download anything extra? It was coded in C++ on Visual Studio.
If your program uses anything from the standard library, it will need the Visual C++ runtime library, which is typically loaded from the library DLLs (something like msvcr110.dll).
However you can instruct the compiler (the linker, rather) to include (I do not mean #include-ing the header file) the library as part of your executable (exe file). (I guess you thought of ISO because an archive file would include all the necessary DLLs) According to https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx, use the /MT compiler option will cause the "multithreaded, static version" of the Visual C++ runtime library (which is the library in pre-compiled code) to be included in your program during linking (in contrast to the default /MD option, which only causes code that helps your program link to the main library DLL to be included).
Correction: The program will be larger, but since the linker does not actually add everything to the output program, the size of the output file depends on what the program uses. Microsoft Visual Studio ~ C/C++ Runtime Library ~ Static/dynamic linking This might be helpful. (If you are interested, look into Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib (don't forget to replace the version number).)
Go to project settings -> configuration properties -> C/C++ -> code generation and set runtime library to Multi-threaded (MT).
Correction: it seems directly setting the compiler flag will work even with the default /MD or /MDd flag left in the command line.
EDIT: be sure to clean the solution (build -> clean solution) after applying these settings. Otherwise the linker may still try to use the old files.

Why do I have to call my library explicitly?

I'm following an OpenGL tutorial and I'm at the last step, using GLEW to setup the FPS counter. I had a problem where I had to use #pragma comment(lib, "glew32sd.lib") to successfully link my library. Whereas with freeglut, I didn't have to explicitly reference it.
My structure is simple,
library\
dll\
freeglut.dll
glew32d.dll
include\
GL\
freeglut.h
freeglut_ext.h
freeglut_std.h
glew.h
glut.h
glxew.h
wglew.h
lib\
freeglut.lib
glew32d.lib
glew32sd.lib
I have set Visual Studio to include the include\ dir and to look for additional libraries in lib. The dll folder is set to copy to the output via a post-build job. I'm pretty sure it works because up to this point everything was fine with freeglut. Only glew isn't working.
How is Visual Studio not able to link glew but it is working with freeglut ? They are in the same directory. I see that freeglut is being linked because I see it in the linker's output 1> Processed /DEFAULTLIB:freeglut.lib. Both libraries are compiled from my computer.
I tried to compile GLEW as a static library so I'm assuming the compiler does not load the .dll so I might as well remove it. But in both cases it wouldn't work. I tried using #define GLEW_STATIC and #define GLEW_BUILD, would not link either.
Then I stumbled on an answer on SO and found that if I did #pragma comment(lib, "glew32sd.lib") it would correctly load my library. Now I'm assuming that by explicitly telling the linker to use this .lib it makes it work. But why then does freeglut gets loaded automatically ? I'm not referencing directly it anywhere.
Right now my code is working but I'm just curious. I'm a new C++ developer and the concept of static libraries and dynamic libraries is still too fresh in my mind.
You need to tell the linker which libraries you use either via the pragma or in the Project->Linker->Input->Additional Dependencies area of the project properties.
In the case of freeglut the pragmas are supplied for you in freeglut_std.h unless you explicitly define FREEGLUT_LIB_PRAGMAS to 0. If you did that you would need to add the dependency manually either via your own pragmas or in the Additional Dependencies area.
In general it is up to you to add the dependencies you need. In my experience it is rare for a library to attempt to do it automatically.