| Jonny D's Projects | |||||||||||
| News GigaSun Jet Tutorials C++ Projects -Beginners SDL Projects -SPriG -NFont Other Projects Contact
|
Tutorials
and Articles:
Graphics from Scratch,
Using SDL
Prerequisites: Some knowledge of C or C++ (Variables, loops, functions). Not prerequired: A compiler/IDE, money. Hello there! In this article, I want to get you set up with a C or C++ build environment and help you to install the Simple DirectMedia Layer (SDL - www.libsdl.org). I personally use Windows XP and Debian GNU/Linux, going between the two with the excellent operating system portability of SDL. All of my SDL programs compile without changes on either system. Oh yeah, it's the life ;) To help you out a little, I've colored specific paragraphs: Red will be for Windows, and Green will be for Linux. Here's what we'll be talking about: Setting up a build environment (Code::Blocks IDE) A test program: Console output Installing SDL (and libraries in general) A test program: Drawing rectangles and blitting a bitmap Some notes on SDL Setting
up a build environment (Code::Blocks IDE)
First up, let's talk IDEs. IDE stands for Integrated Development Environment. These are programs that help you to write programs faster and easier than if you're just writing in a text editor. They usually include a built-in editor, debugger, and allow you to compile and test your program right there. Technically, the IDE doesn't compile your programs. It asks a compiler to do this for you. That means that you must have a compiler suite installed as well. On Windows, your best bet is to use MinGW. This is the Windows port of the free GNU Compiler Collection. If you're already set with Microsoft Visual Studio, you can just skip ahead (but I can't help you as much). Fortunately, my favorite IDE, Code::Blocks, comes equipped with MinGW. I suggest you take a look at CodeBlocks (www.codeblocks.org), since that's where I'm going with this. Once you download the release candidate from the official website (codeblocks-8.02mingw-setup.exe, 19Mb), you just run it and install it. When you run it for the first time, you'll choose your compiler and you should be all set to make a simple C/C++ program. On Linux, everyone uses the GNU Compiler Collection. Your system almost definitely has it installed already. Your kernel is probably built with it! Here let me differentiate the compilers. The C compiler is gcc. The C++ compiler is g++. Just open a terminal and type:
or
Now, depending on your Linux distribution, your installation of CodeBlocks can vary. You can use a package manager like APT on Debian and Ubuntu (As root: apt-get install codeblocks) or Yum on others. You could also download what you need from the CodeBlocks site. If you're on Debian or Ubuntu, you'll need to extract the tar.gz file and then use dpkg to install the packages:
or
Running codeblocks in the terminal or finding it in your applications menu will open the program and verify your compiler. Now you're ready! A
test program: Console output
Let's write a quick program to flex our new programming muscles... Create a new project, choose "Console application" (it has a shell in front of a 'shell'), and put this in your main source file:
Hopefully this works right the first time. This is a C program, as my other code here will be, so I don't have to worry about compatibility. The only weird thing you might see is how I defined main(). According to the standards, your main function should return an integer. Zero means that everything went fine. Any other number means that there was an error. The parameters of main, argc and argv, are used for working with command-line arguments. argc tells you the count of how many arguments there are. argv holds the values of the arguments. The first argument is, by default, your program's name as it was called. Here's an example - If I run test.exe like so:
we have: argc == 3 argv[0] is the string "test.exe" argv[1] is "-c" argv[2] is "moreFPS" To apply command-line arguments in Windows, you have to use the command console (run: cmd). This command line stuff is all very useful, but more importantly for now, SDL 1.2 requires main() to be defined this way. Installing
SDL (and libraries in general)
When you install a library you really start to understand the whole process. When you compile a program, you also have to link it. A compiler will spit out object files (.o). These are then put together by a "linker" to make your executable. A library is a precompiled chunk of code that you can use in your programs instead of adding all of the original source files into each of your projects. Static link libraries are built into your program when you link it after compiling. Dynamic link libraries (or Shared libraries) are linked to your program at runtime. When your program is being linked at compile-time, it still needs to know which dynamic libraries you're using. A common naming convention for libraries that you'll see a lot is: "libmything.a". On Windows, dynamic libraries appear as .lib, .a, and .dll files. MS Visual Studio uses .lib files. We'll be using .a files. You link to the .a (or .lib) file when you compile, and then the program knows to look for the .dll when it runs. Static link libraries also appear as .lib or .a files. Sometimes, the library will have a 'd' appended to the file name to signify dynamic linking. On Linux, shared (dynamic) libraries have .so extensions. Static libraries appear as .a files. To install a library, you need to drop some files into your compiler's include/ folder and lib/ folder. If you got CodeBlocks with MinGW, those folders are in the codeblocks\mingw\ directory. If you're on Linux, your folders are /usr/include/ and /usr/lib/. A library typically comes as header files (.h usually) and the library files (.lib, .a, .dll, .so). Put the header files into your include folder and the library files into your lib folder. That's the basic idea. There are some other ways about it (devpaks), but that is the way it is often done. On Windows, you are usually presented with the binaries (precompiled library files) and you just toss the files where they should go. When you give someone else your program, include the .dll files that it uses with it. The .dll files should be in the same folder as your executable. On Linux, you're often presented with just plain source code. If there is a Makefile with the code, you can usually just move into that directory and type:
If there's not a Makefile, but there's a config or configure file, try:
Alternatively, many libraries occur as packages. Use APT to get these. Most Linux users can get the required libraries for themselves, but you can include your .so files when you distribute your programs. Now, finally, let's install SDL 1.2. On the SDL website (www.libsdl.org), you'll find "Runtime Libraries" and "Development Libraries". You'll probably want both. The Development Libraries are vital, however. Installation is just like above, except that people usually treat SDL as special. I put my headers into include/SDL/ so that I can easily find them and add to them. You have to tell the compiler to look there as well, but it keeps SDL nice and separate. On Debian, you can use APT (as root) to get the required packages:
This does all the work for you. Okay. We've just installed SDL! It's time for a program so we can see how SDL looks in the wild... A
test program: Drawing rectangles and blitting a bitmap
SDL is pretty neat. Right here you have a library that gives you cross-platform access to video and audio hardware, mouse and keyboard, even joysticks and CD-ROMs. There are many good tutorials out there. I suggest SDLTutorials.com, Sol, Lazy Foo', Cone3D, and NeHe. I'd like to keep my presentation fairly concise, so I'll forgo the details of how everything works in SDL. I'll just give you enough to get going. You should definitely check out those tutorial sites to get a feel for how to do various things with SDL. To make my quick example, let's load an image and draw some rectangles. First, make a quick bitmap image. You can use MS Paint, but I suggest the Gimp (GNU Image Manipulation Program - www.gimp.org) for both Windows and Linux. It's roughly on the level with Adobe Photoshop, and costs exactly 100% less. However you do it, make a quick drawing and save it as a .bmp file. Put that into a new folder and open CodeBlocks. Make a new console project and put it in that folder, too. To set up the project to allow you to use a library, you need to do three things. First, you have to make sure that the compiler can find your library header files (it automatically checks the include/ folder, but not subdirectories). Second, tell the linker which libraries you're using in your specific project. Third, write an include statement in your source code. To tell the compiler where to find the headers, go into CodeBlocks' "Settings" menu and choose "Compiler and Debugger". The Global Compiler Settings should be showing. Choose the "Search directories" tab, then add a new location on the "Compiler" tab. Tell it the name of the folder where SDL is (include/SDL/). If you're on Windows, you should add a linker option, too. Go to the "Linker Settings" tab and under "Other linker options", type -mwindows. Alright, so your global compiler stuff is set. You only have to do that once. Now you have to set your project's specific libraries. Go to the "Project" menu and choose "Build options". The screen should look familiar. Make sure you have your main project selected (not just debug or release), then click on the "Linker settings" tab. Here, click on the "Add" button to add libraries. On Windows with MinGW, you have to add mingw32 first. Now, add SDLmain and SDL. This is also where you'd add other libraries. For instance, if the library file is libSDL_image.a, you would add SDL_image. On the command line, this translates to -lSDL_image. Be aware that Linux is case-sensitive! And the last part is in the code, so let's check it out:
This code is very, very simple SDL stuff. I didn't even put in framerate controls or mouse input, and I didn't give the user any feedback when an error occurs. You can find a little more code in my SDL example, but this will suit us fine for now. What I've done here is just to initialize SDL, load that picture, then enter the main loop and draw everything. There are many more substantial examples in the tutorials that I mentioned earlier. If there is no picture drawn, double-check the file name (case-sensitive in Linux, remember). Some
notes on SDL
As you can see, SDL uses event-based input. This has several advantages, especially conceptually (easier to think about and encapsulate). You can also check the state of certain input devices for a different approach, but events are the usual thing to work with. SDL has fairly good documentation, thankfully. I keep a copy on my computer for quick reference. If you can't find an answer there, try checking out those tutorial sites. Failing that, the SDL mailing list is quite active. Also, I will occasionally post SDL resources, like my alpha-blending table (which does a better job than the official docs, if I may say so). Colors in SDL are usually stored in Uint32 variables. This type (and others) is defined by SDL so that you can be sure that you get exactly 32 bits on every different platform/OS, rather than the ambiguous 'unsigned int'. On a 32-bit surface, each color component gets 8 bits. If I write a hexidecimal constant like so: 0x50a600ff, and the pixel format is ARGB, then my components would be alpha = 0x50 (80), red = 0xa6 (166), green = 0x00 (0), and blue = 0xff (255). There you can see that color components range from 0 to 255 (256 values). These components can each be stored in Uint8 variables. SDL uses the standard coordinate axes for computer graphics. The point (0, 0) is in the upper left-hand corner of the screen. The x coordinate increases to the right, and the y coordinate increases downward. This does have a small side-effect that the coordinate system is left-handed (angles are measured clockwise). It pays to wrap certain things in your own functions. For example, you can write a function that draws an image to the screen, taking just the surface pointer and coordinates. I personally found it very easy to wrap both keyboard and joystick handling into one function, so my game accepts either input method for a particular player and the code to use it is nice and clean. Well, that's just about all I have to say right now. I hope to hear from you if this all works out. See ya next time for an emphasis on Sprig! Jonny D |
||||||||||