Monday, October 13, 2014

SFML Tutorial: Hello World

In this tutorial, we'll create a SFML window and draw a shape and some text, and demonstrate a basic animation.

This tutorial assumes that you already have the SFML.Net libraries and their dependencies, but we will create a new project file for this tutorial. This and all future tutorials will assume that you are using Visual Studio (however, it's definitely possible to use SFML.Net with Mono!).

A portion of the code used in this tutorial (and likely future tutorials) is taken from the official examples for SFML.Net.

Start by creating a new project (Ctrl + Shift + N). Use the Empty Project template (I named my project "HelloSFML").

The first thing we'll want to do is set up the configuration so we're building for the correct architecture. Open the Configuration Manager (either under the Build menu or in the contextual menu if you right click on the solution in the Solution Explorer). In the Configuration Manager, click on the "Any CPU" platform in the line for your project, and choose "<New...>". Set the new platform to your system architecture (x64 for 64-bit, x86 for 32-bit), and click OK. Close the Configuration Manager.


Now we can add the libraries for SFML.Net. The libraries for SFML.Net itself should be added as references (right click on the project or the References folder and choose "Add Reference..."). For this example, we need sfmlnet-graphics-2.dll, sfmlnet-system-2.dll, and sfmlnet-window-2.dll. The dependency libraries should be added as existing items (Shift + Alt + A). Add csfml-graphics-2.dll, csfml-system-2.dll, and csfml-window-2.dll.

To make sure our dependencies are included when we build the program, select them in the Solution Explorer and set "Copy to Output Directory" to "Copy always". This will move them to the directory where the program would look for them.


Now we can add some code! Add a new class (Shift + Alt + C), and name it HelloSFML.To this class, add the following code:

        public static void Main()
        {

        }

Next, we'll tell Visual Studio we want to run this function when the application starts. Go to the project properties (in the Project menu, or right click on the project in the Solution Explorer). Change the Output Type to "Windows Application", and change the Startup Object to the class you just created.

 

Now we just need to add some content to that function. The first thing we want to do is to create a window to draw to (you'll need to add using directives for SFML.Graphics and SFML.Window as well):

            // Create window
            RenderWindow window = new RenderWindow(new VideoMode(800, 600), "Hello SFML.Net!", Styles.Close, new ContextSettings(24, 8, 2));
            window.SetVerticalSyncEnabled(true);
            window.SetActive();
            
            // Setup event handlers
            window.Closed += new EventHandler(OnClosed);
            window.KeyPressed += new EventHandler(OnKeyPressed);


This code creates a new window 800 pixels wide by 600 pixels tall, gives it a title, sets it to not be resizable or have a maximize button, and gives it 24-bit depth buffer depth, 8-bit stencil buffer depth, and two levels of multisampling for anti-aliasing. After the window is created, we add event handlers for when the close button is hit and when a key is pressed (so we can close the window if the escape key is hit). We'll make these event handlers when we're done with the main function.

Next we'll add something to show in this window:

            // Create objects to draw
            RectangleShape rect = new RectangleShape(new Vector2f(300, 200));
            rect.Origin = 0.5f * rect.Size;
            rect.Position = new Vector2f(400, 300);

            Text text = new Text("Hello SFML.Net!", new Font(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts) + "/arial.ttf"), 24);
            text.Position = new Vector2f(400, 300);
            text.Origin = rect.Origin;
            text.Color = Color.Black;            
            
            // Set up timing
            Clock clock = new Clock();
            float delta = 0.0f;

This code creates two drawable objects, a rectangle and some text. For animating them later, I've set the origins and positions to some specific places. I'm having it load Arial from the system font directory. This is not the ideal way to load fonts (they should be included with your project instead of expected to be installed on the system), but for the sake of simplifying the tutorial we'll just load a default system font. In this code we also create a timer to use for animation purposes.

One more block of code and our Main function is complete:

            while (window.IsOpen)
            {
                // Update objects
                delta = clock.Restart().AsSeconds();
                rect.Rotation = rect.Rotation + 15 * delta;
                text.Rotation = rect.Rotation;
                window.DispatchEvents();

                // Display objects
                window.Clear(new Color((byte) 50, (byte) 50, (byte) 180));
                window.Draw(rect);
                window.Draw(text);
                window.Display();
            }

This is our main loop. We get a delta time (the amount of time that passed from the start of the previous iteration of the loop, AKA the frame time) and use that to determine new rotations for our objects. We then clear the window and draw the objects. We also have the window dispatch events in this loop, passing on the news to our event handlers if it's time to close the window.

The last thing to add is our event handlers, outside of Main(), but still in the HelloSFML class:

        /// <summary>
        /// Function called when the close button is clicked
        /// </summary>
        static void OnClosed(object sender, EventArgs e)
        {
            RenderWindow window = (RenderWindow) sender;
            window.Close();
        }

        /// <summary>
        /// Function called when a key is pressed
        /// </summary>
        static void OnKeyPressed(object sender, KeyEventArgs e)
        {
            RenderWindow window = (RenderWindow) sender;
            if (e.Code == Keyboard.Key.Escape)
                window.Close();
        }

These simply handle the times where we would want to end the program by closing the window. If the close button on the window is pressed, or the escape key is pressed, the window will close, ending the program (our main loop will continue as long as window.IsOpen is true).

Now, if you run the program you should see a spinning white rectangle with text, on a blue background!


1 comment:

  1. My skype is Logehcol.

    I've been doing a lot of work on C#, and I just recently started using OpenTK as a wrapper for graphical/gaming development. You seem like a pretty advanced individual with OpenTK. I'd love if you'd add me on Skype as a resource for when I hit issues? If not, that's fine.

    ReplyDelete