Sharp DirectMedia Layer (XNA-like Framework for SDL)
SharpDL aims to provide a managed, cross-platform, XNA-like framework with graphics, input, audio, and event systems based on the SDL2 library. Games created with this library should strive to be lightweight and portable (in both .NET and Mono). Currently, SharpDL only supports utilizing the built-in SDL 2D rendering system and does not support any OpenGL bindings.
Because SharpDL is written in C# intended for compilation in .NET or Mono, utilizing the native SDL2 libraries requires marshalling of data types through P/Invoke. This also means that any memory allocated in "native land" (ie: in the SDL libraries) will require strict adherence to good disposal mechanisms in the managed code. Failing to free any allocated resources will result in memory leaks.
For more information about the wrapper around SDL2 in order to make our P/Invoke possible, see the [SDL2-CS] 1 GitHub page.
SharpDL consists of four main projects: SharpDL, SharpDL.Events, SharpDL.Graphics, and SharpDL.Input. A project for audio is not yet available.
- SharpDL
- Responsible for the base `Game` class, `GameTime`, and some experimental classes such as `Logger` and `Timer`.
- SharpDL.Events
- responsible for various `EventArgs` implementations that are based on the `SDL_Event` union. For example, the SDL_Event union is processed in the SharpDL's `Run` loop, `EventArgs` of the proper type are created, and an `event` of that handles that type is fired. This allows for a more .NET-like event system.
- SharpDL.Graphics
- Contains any class that is responsible for graphical operations such as creating a SDL_Window, rendering with a SDL_Renderer, creating a SDL_Surface, or loading a SDL_Texture. Examples of some of these classes are `Color`, `Font`, `Renderer`, `Window`, `Texture`, `TrueTypeText`, and more. Some classes do not have direct relations to SDL structures such as `Vector`, which represents an X,Y coordinate in a 2D space.
- SharpDL.Input
- Contains classes to handle Keyboard and Mouse input by capturing mapped SDL structures into .NET-style enumerators. Joystick and controller input is not yet available.
The base Game
class offers options to initialize SDL, create windows, create renderers, and process events. Two important steps to the initialization of the library is to create a SDL window and create a SDL renderer as shown below.
SDL_CreateWindow
is wrapped by the Window
class. Creating a window:
string title = "My Window"
int x = 0;
int y = 0;
int width = 640;
int height = 480;
WindowFlags flags = WindowFlags.Shown | WindowFlags.GrabbedInputFocus;
Window window = new Window(title, x, y, width, height, flags);
SDL_CreateRenderer
is wrapped by the Renderer
class. Creating a renderer:
int index = -1;
RendererFlags flags = RendererFlags.RendererAccelerated;
Renderer renderer = new Renderer(window, index, flags);
renderer.SetRenderLogicalSize(640, 480); // or however large we want to render to
To simply make a game without worrying about the way the library works, follow these steps (or look at the examples folder in the project).
-
Inherit from the SharpDL.Game class.
-
Override the
Initialize
method. Callbase.Initialize()
to initialize SDL.
You are now free to create surfaces and textures to render to the screen with your renderer object. However, you will want to override the LoadContent
, Update
, and Draw
methods of the Game
class in order to get the timing of your texture creation, updating, and rendering to work with SharpDL's game loop.
Texture myTexture;
int myTexturePositionX = 100;
int myTexturePositionY = 100;
// load all game assets here such as images and audio
protected override void LoadContent()
{
// creates an in memory SDL Surface from the PNG at the passed path
Surface surface = new Surface("Content/Images/MyImage.png", SurfaceType.PNG);
// creates a GPU-driven SDL texture using the initialized renderer and created surface
myTexture = new Texture(renderer, surface);
}
// update the game state here such as entity positions
protected override void Update(GameTime gameTime)
{
}
// draw loaded assets here
protected override void Draw(GameTime gameTime)
{
renderer.RenderTexture(myTexture, positionX, positionY);
renderer.RenderPresent();
}
You can see that this is very similar to XNA's game looping features. While the SharpDL library is extremely simple at this time, you can still create some pretty fun games from it.