Simple DirectMedia Layer (SDL) is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.
The library is very powerful, however it contains only low-level functions. In order to extend SDL features, several libraries were created. The main extensions are:
- SDL_gfx: graphics primitive toolkit and rotozoom
- SDL_image: an image file loading library
- SDL_ttf: a TrueType fonts toolkit
- SDL_mixer: a multichannel sample and music mixer
There are several other libraries providing abstractions and extensions for SDL, but I believe the libraries above are the basis for any development using SDL.
Since SDL is written in C, we need a JNI interface for Java usage. Ivan Ganza created sdljava, which is a binding to the SDL API. It provides the ability to write games and other applications from the Java programming language. It is designed to be fast, efficient and easy to use.
But why Java?
SDL is a library, not an engine. There are no abstractions or special features like event handling, thread support, or collision detection… SDL only offers low-level access to multimedia resources. In fact, SDL is not thread safe at all!
Java3D applications development is complex and not very intuitive. We can design our games using Java objects, develop our game business logic using Java, leverage the Java API features.
Cross-platform games development is possible combining Java and SDL together.
SDL download
You can download manually all required files or download my package here: sdl_part1.
SDL initialization
Create a Java project using your favorite IDE (I always recommend Eclipse). You have to set up the classpath and library classpath for your project. My package includes a Eclipse project already configured. Please refer to file ‘.classpath’ for guidance.
After the initial set up, we can create our first class and initialize the SDL library.
1 2 | SDLMain.init(SDLMain.SDL_INIT_VIDEO); SDLSurface screen = SDLVideo.setVideoMode(800, 600, 16, SDLVideo.SDL_DOUBLEBUF | SDLVideo.SDL_FULLSCREEN); |
The first line initializes the SDL library (it should be ran only one time and before using any SDL function). The second line creates a surface that represents the screen (width: 800; height: 600; 16bit; double buffered and full-screen mode). In SDL, everything is mapped to a surface, including images, geometries, texts, etc. If you try to run only this piece of code, you probably won’t even see the screen surface. We need something for keeping the main thread alive. You can use your imagination for now: infinite loop or sleeping.
Surface manipulation
As said before, everything in SDL is mapped to a surface. Now, let us create a new surface, using the same properties as the main screen.
1 2 3 4 | SDLPixelFormat format = screen.getFormat(); SDLSurface redSurface = SDLVideo.createRGBSurface( screen.getFlags(), 100, 100, format.getBitsPerPixel(), format.getRMask(), format.getGMask(), format.getBMask(), format.getAMask() ); long redColor = SDLVideo.mapRGB( redSurface.getFormat(), 255, 0, 0 ); redSurface.fillRect(redColor); |
SDL library provides only primitive drawing functions. The last two lines are used for surface filling, using red color. So far we have the screen surface and another red-filled surface. The next step now is combining these two surfaces.
1 2 | SDLRect redRect = new SDLRect(0, 0); redSurface.blitSurface(screen, redRect); |
The first line specifies a location. In our case, it specifies the location (x, y) of our new surface within the screen surface. The second line performs the blit operation. A blit operation is the combination of two bitmaps (surfaces). Ok, now let’s run the application…
You were supposed to see the red surface within the screen surface, right? Wrong! The question now is: where is my red surface? The answer is on the next code snippet.
1 | screen.flip(); |
We forgot to flip the screen! The flip SDL function has two behaviours: (1) redraw the entire surface, or (2) flip the screen when using double buffer. The final result is the same: the flipped screen is updated. Let’s try running our application again… Now you can see the red surface on left-top of the screen (0, 0).
Advanced surface manipulation
The SDL_gfx library (represented by SDLGfx class) provides advanced surface manipulation. The following code snippet performs the drawing of a green filled circle and a blue border-only rectangle on the screen surface. The colors are being represented as RGBA (red, green, blue, alpha).
1 2 3 | SDLGfx.filledCircleRGBA(screen, 200, 150, 50, 0, 255, 0, 255); SDLGfx.rectangleRGBA(screen, 0, 200, 100, 300, 0, 0, 255, 255); screen.flip(); |
Another advanced feature provided by SDL_gfx is image zoom and rotation. The next code snippet will use our first red surface as basis for modification. We are going to rotate it 45º and scale it two times bigger. These modifications can be done to any SDL surface and will generate a new surface.
1 2 3 4 | SDLSurface changedRedSurface = SDLGfx.rotozoomSurface(redSurface, 45, 2.0, true); SDLRect changedRedRect = new SDLRect(300, 200); changedRedSurface.blitSurface(screen, changedRedRect); screen.flip(); |
Image manipulation
SDL library provides basic bitmap image loading functions. The following code snippet shows how to load bitmap images. The loading process generates a surface.
1 2 3 4 | SDLSurface spriteSurface = SDLVideo.loadBMP("centro_atletismo.bmp"); SDLRect spriteRect = new SDLRect(300, 0); spriteSurface.blitSurface(screen, spriteRect); screen.flip(); |
After running the application, you’ll probably want to ask me: what is the purple color history? And why is the image dotted? I know the answers, but now ain’t time to explain it. We will discuss transparency in my next post.
Instead of using the basic bitmap image loading function, you can use the SDL_image library. This library provides support for several image formats, including PNG and GIF. The only difference between standard SDL and SDL_image is the first line of the previous code snippet. I’m using the same bitmap file, but you can test using your own files. The following code snippet presents the image loading process using SDL_image library.
1 | SDLSurface spriteSurface = SDLImage.load("centro_atletismo.bmp"); |
Extra information
You can found a lot more information in SDL documentation.
Next post
In the next post I will present the TrueType fonts manipulation and I will explain the transparency/opacity mechanism used by SDL. Besides, I am going to present the audio and events management.
Some screenshots will be nice