I’ve been using SFML now for more than a year but I never really understood how sf::View really works, until now. So I feel like sharing this enlightenment and I’ll also create a tutorial in the wiki section on GitHub.
This basically states that we plan to derive the functions we set up in step 1 in game.cpp. Also realize we have a constructor and a deconstructor. The deconstructor is represented as Game; In general, c will create a deconstructor for you and you usually want to avoid defining one yourself if you can. Thanks for contributing an answer to Game Development Stack Exchange! Please be sure to answer the question. Provide details and share your research! But avoid Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience. Use MathJax to format equations. To begin, you must have the SFML graphics library setup properly on your development environment. This post will not show you how to do that, but for all using Microsoft Visual Studio, you can watch this tutorial by Richard Phelix that is still working in 2017 and you can download SFML here.
What can a sf::View do?
- Your question should not be 'how do I set up SFML on Dev-C', but rather 'how do I set up a library with Dev-C', and more generally 'how do I use Dev-C'. This way you won't have to post on the forums of each other library that you may use in the future. Especially since you chose a dead IDE that nobody knows about anymore.
- This tutorial covers the process of setting up an SFML project using Visual C 2013. The process will be very similar for all versions of Visual Studio. Text Link Video Link. Part Two – Windows, Game Loop and Timers. This tutorial explores the beating heart of an SFML application. It covers how to create a window and process events.
- Setting up SFML. This short tutorial will guide you through downloading the SFML files that allow us to include the functionality contained in the library in our projects. In addition, we will see how we can use the SFML DLL files that will enable our compiled object code to run alongside SFML. To set up SFML, follow these steps.
- The purpose of this assignment was to set up our Linux environment and experiment with the SFML demo code. Once we got the SFML demo code to run successfully, we were asked to draw our own sprite and make it respond by moving via keystrokes.
This question is not that complicated to answer and I would’ve already been able to do so a few weeks back but I never really understood how sf::View works. The answer would be a description, so here you go:
A sf::View is basically a 2D camera i.e. you can move freely in two dimensions, you can rotate the whole scene clockwise or counterclockwise and you can zoom in and out but there’s no tilting or panning. Furthermore zooming really means enlarging the existing picture rather than closing in on something. In short terms there’s no 3D interaction.
Examples
So if you now want to move a sprite around without altering its coordinates but instead moving the 2D camera, you could do this easily by calling:
Next you maybe want to get a closer look at something, so you can use:
Or you want to rotate everything:
Now you get the idea what the camera can do and you’d probably be even able to program something with it, but do you understand how it works? Do you know what the center of the sf::View is?
So let’s get a bit more technical.
How does sf::View work?
So lets see what the documentation of SFML says about this:
A view is composed of a source rectangle, which defines what part of the 2D scene is shown, and a target viewport, which defines where the contents of the source rectangle will be displayed on the render target (window or texture).
The viewport allows to map the scene to a custom part of the render target, and can be used for split-screen or for displaying a minimap, for example. If the source rectangle has not the same size as the viewport, its contents will be stretched to fit in.
If you’ve understood everything then congrats! I didn’t (at first) and although it’s a good, short and precise description it’s not very intuitive.
From the text above we can extract that there are two different rectangle defining the sf::View: a source and a viewport. What we also have, although not ‘physically’, is the render coordinate system, i.e. the coordinates you use to draw sprites etc.
At first I’ll explain how the source rectangle and the render coordinate system work together, then talk about the size and the constructor, furthermore show you how to use the viewport to create different layouts like a split-screen or a mini-map, as suggest in the description and at the end get a bit away from the direct manipulation of the sf::View and look at the convertCoords(…) function of a sf::RenderTarget.
At the bottom of the post you’ll find a ZIP file which holds a fully working example, demonstrating everything you’ll learn in this post.
The source rectangle
Since I don’t want to talk about the viewport yet but I’ll let it have its defaults value, which means that it will cover the whole window i.e. the whole scene will be rendered 1:1 onto the window.
In the example above I’ve already moved the view to the point, where I’m rendering the separate sprite of Link. Link’s position in pixel is (1056, 640) but to get him centered, respectively the top left corner of him, I can’t just use what might seem intuitively:
(Of course you can set the view center to (0, 0) and then move to to (1056, 640) but we’re trying to understand what the center of the view is.)
Since I’m assuming that you’ve already some knowledge with SFML, I’ll also assume that you know SFML is using a Cartesian coordinate system with a flipped Y axis. So the point (0, 0) can normally be found in the top left corner and then maximum x and y value can be found in the bottom right corner. If you’re working with images you’ll soon get comfortable with this system.
But now comes the center of view, which is in fact defined from the middle point of the display area. The view uses a Cartesian coordinate system too but this time the X axis gets flipped. In the end we have the point (0, 0) (also known as origin) in middle of the view, the maximum x and y values are in the top left corner and the minimal and negative x and y values are in the bottom right corner. What you’re now actually can set with setCenter is the where origin of the rendering coordinate system is put in the coordinate system of the view. I hope the following images will clarify the situation a bit.
The black square should represent the window and since we set the viewport to a fixed value the origin of the sf::View coordinate system will always be in the middle of the window. Here are the two separated coordinate systems:
If we combine them we get for example something like:
Then we have our two operations rotate() and zoom(). The last picture combines the two transformation:
I think it’s nearly impossible to explain this even better.
Note that in the images above, I’ve moved the rendering coordinate system around to get a few different variations. I guess most of the time it’s better to use the move() function since you won’t need to deal with where to place the origin point. On the other hand you really need to understand how sf::View works to use rotate() and zoom() because it’s not obvious that those transformation will happen around the sf::View origin i.e. the middle of the view.
You should keep in mind the introduced concept doesn’t just hold for a window it’ll work with any render target including sf::RenderTexture.
The size and the constructor
How To Set Up Sfml In Dev C 2b 2b Answer
Before we take a closer look at the viewport we need to understand what the size of the view is and which parameters the constructor takes.
For now we’ve used the same size for the view as for the render target, this gives us a 1:1 projection. But what if we’d divide the size of both sides by two? From the observer perspective such a change would equal to using view.zoom(0.5f) but from the programmer perspective it’s something completely different. As we’ll learn in the next paragraph we can use the viewport to map the rendering stuff to a certain area on the window. Now if’ we’d apply the scene with the same size as before everything would get shrinked and eventually stretched if the ratio of the side isn’t the same anymore. This can create some wanted effects but mostly it would defeat the purpose. With setting a specific size, we’re telling the sf::View how big the view should get drawn while not making any visible transformations on the rendering part.
With that in mind it’s now easy to understand how to use the constructor.
Where origin relates to a 2D vector of the origin in the rendering coordinate system and size relates to the sf::View size as discussed above.
The viewport rectangle
After we’ve seen most of the things sf::View can do, we want to generalize this even further. For now we’ve assumed we were using a window and rendered 1:1 onto it’s surface, but what if we wanted to display my stuff only on the lower right corner or use only the half left side? That’s where the viewport comes in.
The default values are sf::FloatRect(0, 0, 1, 1) which means the view covers 100% of the render target. So we got another rectangle which holds percentage values of the size of the render target. The first two values describe the position of the upper left corner and the last two values the lower right corner.
If you want to split the screen you’d need two different views for the left and the right side. Before you then draw to one side you’ll have to change the view on the render target first. To draw something to the other side, just set the second view and you’re good to go. This could look like this:
With all the knowledge provided above you should now have a good understanding of why we divide the window width by two or why viewRight is defined with 0.5 as first argument.
Another example I promised to show is how to create a mini-map i.e. a scaled down overview of the whole map. In practice it’s often better to construct it’s own mini-map rather than just scaling down the original one, since the quality can get fairly poor. But let us first test how it will really look like.
If you’re working with more dynamic data you’d probably need to render everything to a sf::RenderTexture and then extract the texture and render it twice. In this example we ignore those facts and just assume we’ve got a sprite with the Zelda map texture thus we can reduce the code to a few lines.
The convertCoords(…) function
As we’ve seen in the paragraph with the source rectangle it’s not very intuitive to work with those two coordinate system. It’s also pretty hard to determine by hand at which position for instance your mouse cursor is located relative to the view underneath. But why would you want to do this by hand, since SFML has already a build in function that will do the heavy lifting for you, namely convertCoords(…)?
There are two ways to use this function:
- Determine the relative position on the render target of the point P to the current view of the render target.
- Determine the relative position on the render target of the point P to a specified view.
This function can be very useful, e.g. you’ve moved around your view and now the user click on a point on the window. Just call convertCoords(…) and you’ll instantly know where on the moved view he clicked.
Complete demonstration
I’ve created a small application which packs up every introduced concept. The code isn’t the prettiest but contains a lot of more or less useful comments. I also provide a package that contains just the images presented in this blog post and since maybe some people want both, I’ve created one that contains everything.
- Code Package (392 KB)
- Image Package (801 KB)
- Full Package (1.16 MB)
If you have any questions/suggestions or found any mistakes/bugs/errors just let me know in the comment section!
Related article: Using ImGui with modern C++ and STL
This is the first part of tutorial about Dear ImGui (AKA ImGui) and it’ll show you how to set it up with SFML. The second part will be library agnostic and will talk about common ways of doing stuff in ImGui, some awesome widgets and some useful STL overloads.
Different ImGui widgets (taken from ImGui’s github page)
Table of contents
- Using ImGui-SFML
Introduction
Having good content creation (level editor, resource editor, etc.) and debuggingtools for your game is very important and can lead to productivity andcreativity boost. Here are some examples of tools I managed to make with ImGuifor my games.
Level Editor in Tomb Painter
Level Editor
Lua console
Animation editor
As you can see there’s a wide range of widgets that ImGui provides and there are lots of other great examples of how other people use it here.
Dear ImGui and immediate mode GUI concept
Dear ImGui is an immediate mode GUI library which makes making GUI for all kinds of tools very easy.
Immediate mode GUI is a bit different to what people think when they hear “GUI” (“retained mode” is a classic way of doing GUI).Immediate mode GUI is a way of doing GUI which involves creating and drawing widgets in each frame. Instead of creating some Button
object and adding a callback to it, you write something like
Simple as that!
For a great in-depth talk on this concept, I recommend to check out Casey Muratori’s talk on IMGUI.
Back to Dear ImGui. It’s:
- MIT Licensed
- Very fast and light
- Constantly updated and expanded
- Doesn’t do dynamic allocation/deallocation
- Very portable – has lots of bindings for different libraries and frameworks
- Easily expandable
Using ImGui-SFML
ImGui-SFML is a binding I wrote tosimplify usage of ImGui with SFML. Here’s how you can use it.
Option A. Using ImGui-SFML with CMake
Important: since ImGui-SFML v2.0 minimal version for SFML is 2.5.0 and. For ImGui it’s 1.68
Also you can see how you can get and ImGui, SFML and ImGui-SFML with amazing FetchContent CMake module here
First, you need to download ImGui, ImGui-SFML and build SFML somewhere.
Then, run this where you want to build ImGui-SFML:
If you have SFML installed on your system, you don’t need to set SFML_DIR duringconfiguration.
You can also specify BUILD_SHARED_LIBS=ON
to build ImGui-SFML as a shared library. To build ImGui-SFML examples, set IMGUI_SFML_BUILD_EXAMPLES=ON
.
After the building, you can install the library on your system by running:
If you set CMAKE_INSTALL_PREFIX
during configuration, you can install ImGui-SFML locally.
Integrating into your project is simple:
If CMake can’t find ImGui-SFML on your system (or you didn’t install it), just define ImGui-SFML_DIR
before calling find_package
.
Option B. Manual integration
This is slightly more complex…
- Use SFML to get a simple window to show up. Follow the “Getting started” tutorial here if you have never done it before.
- Download ImGui.
Download ImGui-SFML.
Important: you have to add the contents of imconfig-SFML.h to ImGui’s imconfig.h to get implicit
ImVec2
sf::Vector2f
conversion working!- Add ImGui and ImGui-SFML directories to your include directories.
- Add these files to your build / project:
- imgui.cpp
- imgui_draw.cpp
- imgui_widgets.cpp
- imgui-SFML.cpp
- imgui_demo.cpp
- (Optional) If you get linking errors, link OpenGL to your project.
Here’s a complete example of using ImGui and SMFL together.
You’ll see something like this:
Try to change some stuff. Double click on r/g/b field to set values precisely, or just drag some widgets to change window’s background color. Press the button to change window title.Here, it works!
Awesome! Now let’s see how it works.
ImGui is initialized by calling ImGui::SFML::Init
function to which you pass your sf::RenderWindow
. This creates internal default font atlas. See how you can use other fonts in Fonts how-to section of imgui-sfml’s README.
Shutting down is done with ImGui::SFML::Shutdown
call which cleans some things up. (Deleting internal font atlas, if it’s used, for example).
There are two phases of using ImGui in your game loop: update and render.
Updating consists of event processing, state update and widget update. Event processing is done by calling ImGui::SFML::ProcessEvent
and it’s almost the same as processing SFML events. It’s used to process keyboard and mouse input and handle window resize and focus events. State update (which is being done by calling ImGui::SFML::Update
) updates delta time which ImGui uses internally, so you have to pass it using your delta time clock, as well as mouse coordinates (or your window relative to which mouse coordinates will be taken). ImGui::NewFrame
is also being called here and you can call ImGui widget creation functions after that. Calling stuff like ImGui::Button
or ImGui::Color3Edit
updates widgets and it also generates one draw list which is used for rendering later.
Drawing is done with ImGui::SFML::Render
call.
Don’t call ImGui::Render
, it may lead to some bugs which ImGui::SFML::Render
doesn’t have.
You must create all widgets between ImGui::SFML::Update()
and ImGui::Render()
.
If you’re updating more than you draw, then you can either update ImGui once per frame or call ImGui::EndFrame
at the end of your update function.
Widgets are easily created by calling corresponding functions (more about them in the next part). For example, you can call ImGui::InputInt
and pass a pointer to int there.When you change widget’s value, the integer is changed too.Buttons work pretty easy too – they don’t need callbacks, you just wrap code which you want to call after the button is pressed in if(ImGui::Button(…)) { … }
and that’s all you have to do.
Call ImGui::ShowTestWindow
somewhere when you create widgets and you’ll get a nice window with lots of examples of ImGui stuff. This is very useful as example of how to do stuff with ImGui. Just look for the thing you want to make in this test window and you’ll easily find how to do it in corresponding part of imgui_demo.cpp.
Useful overloads for SFML
There are also some useful overloads implemented in SFML ImGui binding. For example, you can use ImGui::Image
and ImGui::ImageButton
with sf::Textures
and sf::Sprites
! I’ve also defined implicit conversions between ImVec2
and sf::Vector2f
, so you can pass sf::Vector2f
to ImGui’s functions without needing to cast explicitly. You can also draw lines and rects with DrawLine
, DrawRect
, DrawRectFilled
.
How To Set Up Sfml In Dev C 2b 2b 1b
Conclusion
As you can see, using ImGui is easy and it’s easy to start doing really impressive and useful stuff with it right away. Thank you for reading this tutorial, I hope it was useful and that ImGui will help you make better tools and greater games as the result of having awesome tools.
Follow me on twitter @EliasDaler to not miss the new stuff!