Home > Graphics, SFML, Tutorial > Video Modes and Windowing

Video Modes and Windowing

Hello, and welcome. Today we’re going to discuss windowing and video modes in more detail. That is, we shall see how we can manipulate windows, and control their attributes. Also, of course, we discuss video modes, and how we can best use them.

The Video

Windows and Render Windows

So we previously used the following code for our window:

sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing");

To create our SFML window. Now, I’m going to tell you that in fact the class sf::RenderWindow doesn’t actually handle windowing itself. It is inherited from sf::Window, which actually handles windowing. They have all the same constructors, so we could do this:

sf::Window Window(sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing");

So what does a render window do that a window doesn’t? Well basically, sf::Window creates a window and OpenGL rendering context. That’s pretty much it. Then you have to draw everything inside the window client area yourself, directly, with OpenGL. The sf::RenderWindow allows us to draw using SFML graphics functionality.

Note that you can also draw with OpenGL to an sf::RenderWindow, but because SFML uses OpenGL for rendering, the OpenGL states might not be preserved. (There is an option to preserve them automatically, but it is inefficient, as it must restore all OpenGL states, not just the ones you care about.)

Creating Windows

Now we understand windows and render windows, let’s talk a little more about creating them. We can do this either by passing arguments to the constructor, or by using the default constructor and then passing the arguments to the sf::Window::Create function. All non default constructors have an equivalent create function.

Using Constructors

As I said, you can create a window directly by passing the appropriate arguments to its constructor. We should all know this, as it’s how we have created a window in every lesson so far. We’ll discuss the arguments passed in general terms in just a minute. But first, here is an example.

sf::Window Window(sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing");

Using Create Functions

We can, however, use the window’s create function as well. To do this, we use the window’s default constructor (which in fact does nothing), and then pass the same arguments to the create function as we did to the constructor in the previous example.

sf::Window Window;
Window.Create(sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing");

Window Creation Parameters

Now we shall discuss in more detail the arguments passed to the window, but first, just note that subsequently I shall use the constructor method to create all my windows, but everything is equally application to the approach using the Create method.

Here is the constructor argument list (yet again!).

sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing")

We pass two arguments: one of type sf::VideoMode and one of type const std::string&. The string is easy: it is just the caption of the window. But let’s now talk about sf::VideoMode in some detail.

Video Modes

A video mode describes the video resolution of our display area. sf::VideoMode is a structure with three members: Width, Height and BitsPerPixel, which represent respectively the video X resolution, the video Y resolution and the pixel depth/colour depth (e.g. 16bit colour or 32bit colour).

sf::VideoMode has a constructor which accepts three arguments – to set the Width, Height and BitsPerPixel respectively. So the line

sf::VideoMode Mode(800, 600, 320);

creates a video mode representing a display area of 800 x 600 pixels, and with 32bit colour. Note that the three member variables of sf::VideoMode are public, so you can access them for reading or writing directly.

Validity of Video Modes

Aside from the constructor and the member variables, sf::VideoMode has one other non static member: the member function sf::VideoMode::IsValid. This function accepts no arguments and returns a boolean value.

What does it do? Well as you’ve probably noticed when configuring your video games’ settings, only certain resolutions are available in fullscreen mode. What the sf::VideoMode::IsValid function does is return true if the mode is a valid fullscreen video mode, and false otherwise.

For example, the following little program

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
	sf::VideoMode Good(1024, 768, 32), Bad(1333, 711, 11);
	if (Good.IsValid())
		std::cout << "'Good' is a valid fullscreen video mode.\n";
	if (!Bad.IsValid())
		std::cout << "'Bad' is an invalid fullscreen video mode.\n";

	return 0;
}

yielded this output:

'Good' is a valid fullscreen video mode.
'Bad' is an invalid fullscreen video mode.

Getting the Current Display Mode

Presumably you have at some point configured your display resolution a particular value, for example I use the full 1920 x 1080 resolution provided by my monitor. You may also be aware that there is a changeable colour setting for your system display mode, though it is unlikely you would want to change it from the default of 32 bit.

Anyway, the point is that we can access the current display mode of the system via the static member function sf::VideoMode::GetDesktopMode. It accepts no arguments and returns an sf::VideoMode describing the current display mode. Write out and build the following program to test it out!

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
	sf::VideoMode Mode = sf::VideoMode::GetDesktopMode();
	std::cout << "The current desktop mode is " << Mode.Width << 'x' << Mode.Height << ' ';
	std::cout << "with " << Mode.BitsPerPixel << " bit colour.\n";

	return 0;
}

For me, it yields the following output:

The current desktop mode is 1920x1080 with 32 bit colour.

Yours, of course, may be different – the point is that it will be your current desktop resolution and colour depth.

Getting all Supported Video Modes

We might also want to get all supported video modes, for example, to populate a list of video modes in a graphics options page in our game. You may already have seen this in my Enumerating Video Modes post. If not, here is some code again. We use the static member function sf::VideoMode::GetFullscreenModes, which takes no arguments and returns a list of video modes, in the form std::vector<sf::VideoMode>.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

int main()
{
	std::vector<sf::VideoMode> Modes = sf::VideoMode::GetFullscreenModes();
	for (unsigned i=0; i<Modes.size(); i++)
		std::cout << Modes[i].Width << 'x' << Modes[i].Height << ' ' << Modes[i].BitsPerPixel << std::endl;

	return 0;
}

This was the output.

1920x1080 32
1680x1050 32
1600x1200 32
1600x1024 32
...
1280x1024 16
1280x960 16
1280x800 16
1280x768 16
1280x720 16
...
800x600 8
720x576 8
720x480 8
640x480 8

Note that in the code posted in a previous post (as mentioned above), the output loop was slightly different. This was merely to format the output in a more pleasant manner. See the other post for details.

Video Modes and Windows

We have had a good, hard look at sf::VideoMode now, but we aren’t quite done with it. I just want to talk now about its relevance to the window and to SFML graphics in general.

Client Area vs. Display Mode

When we create our window, we provide a video mode, and the client area of the window is automatically set to the same size as the X & Y resolutions of the video mode. (The client area of the window is the ‘bit where the application goes’ – basically everything except the border and title bar.) However, unless we explicitly forbid it (see later), the client area may be resized, either when the user resizes the window, or the programmer does using code.

Now, it is important to understand that while the client area may be changed, the actual display mode itself stays the same. So even if the user maximises the window, so that the X resolution goes from 800 to 1920 and the Y resolution from 600 to 1080 (for example), then the 800 x 600 video mode will remain 800 x 600. This means that even if the window is resized, everything you draw will always be scaled to fit the whole window – without any extra code on your part.

Taking Control of Windows

Having thoroughly and comprehensively discussed video modes, it is time to return to the original subject of discussion – windowing.

Construction and Creation

Previously we passed two arguments to the sf::Window constructor:

sf::Window Window(sf::VideoMode(800, 600, 32), "SFML Tutorial 04 - Video Modes and Windowing");

Window Styles

Hopefully by now you well understand the role of video modes in windowing, so these first two arguments should be understandable for you. However, there are in fact two more arguments that may be passed to this constructor (and the corresponding sf::Window::Create function).

The first is an unsigned long integer describing the window style. All the possible values are contained within the sf::Style namespace. Here is a list of relevant values:

  • sf::Style::Titlebar - specifies that the window should have a title bar
  • sf::Style::Resize - specifies that the window may be resized by the user; also makes the window have a title bar, regardless of sf::Style::Titlebar
  • sf::Style::Close - makes the window closable by the user by providing the close button (red cross on Windows) and the application menu (click the icon near the caption on Windows); also makes the window have a title bar, regardless of sf::Style::Titlebar‘s presence
  • sf::Style::None - gives the window none of the above (useful for splash screens, etc)
  • sf::Style::Default - combines Resize, Titlebar and Close to provide a standard window
  • sf::Style::Fullscreen - everyone’s favourite: makes the window fullscreen (remember to use a valid fullscreen video mode)

Note that this constructor parameter has a default value of sf::Style::Default, which is how we got away with excluding it before. Anyway, experiment with a few of these values and see how you go!

Also, of course, note that theoretically multiple styles may be combined with the bitwise OR operator |, though there is no real application for this: it doesn’t make sense to combine with sf::Style::None or sf::Style::Fullscreen and all other window configurations are covered by sf::Style::Close, sf::Style::Resize, sf::Style::Titlebar and sf::Style::Default.

OpenGL Context Settings

Now the final argument (the fourth one) is of type const sf::ContextSettings&. Now sf::ContextSettings describes an OpenGL context, which specifies certain OpenGL settings (such as depth buffer size and antialiasing level). However, as that moves into the realm of OpenGL, it is beyond the scope of this tutorial.

This argument, too, has a default value, so you can safely leave it out of the constructor. If you want to use it, to change AA level or something, I might write a post about it later. Failing that, check out the relevant documentation.

Recreating Windows

Having created your window, either using a constructor or the sf::Window::Create method, you can call sf::Window::Create again to recreate your window, for example to change your window’s settings or that of your display mode.

Additional Window Constructor

As you know, sf::Window and sf::RenderWindow have a default constructor which does nothing and a constructor of the form

sf::Window::Window(const sf::VideoMode& videomode, const std::string& caption, unsigned long Style = sf::Style::Default, const sf::ContextSettings& settings = ContextSettings())

But there’s a third one two. I shan’t discuss it in detail here, but it basically allows you to create a rendering area on top of an existing window/control which you got from elsewhere (e.g. Qt or WinAPI).

If you want to read about it, see the documentation, but I’ll just say that it accepts two arguments: the handle of the control, and the OpenGL context settings of type sf::ContextSettings. Maybe I’ll write a post on it later…

Standard Windowing Control

We can also manipulate our window in some fairly standard ways. To do this, we use some member functions of the sf::Window class. Here are a few, with brief explanations.

  • sf::Window::ShowMouseCursor(bool show)
    If show is false, the mouse cursor is hidden; otherwise it is revealed
  • sf::Window::SetPosition(int x, int y)
    Sets the window position to (x, y);
  • sf::Window::SetSize(unsigned int width, unsigned int height)
    Set the size of the window client area to width by height;
  • sf::Window::SetTitle(const std::string& title)
    Sets the window caption to title;
  • sf::Window::Show(bool show)
    If show is false, the window is hidden; otherwise it is revealed;
  • sf::Window::Close()
    Closes the window
  • sf::Window::Display()
    Displays the window to the screen (and updates the client area)

There are a few others – if you want to read more about them, check out the sf::Window doxygen documentation. There are also some get function to retrieve various window attributes:

  • sf::Window::GetWidth()
    Get the width of the window’s client area;
  • sf::Window::GetHeight()
    Get the height of the window’s client area;
  • sf::Window::GetSettings()
  • Get the OpenGL context settings;
  • sf::Window::IsOpened()
    Returns true if the window is opened; false otherwise.
About these ads
  1. xander333
    12.06.2011 at 21:48 | #1

    Awesome post xander, clear and effective ;D

    • 12.06.2011 at 22:00 | #2

      Thanks. Windowing was originally going to be discussed alongside event handling, but as I wrote the tutorial I gradually realised there was a lot to say on the subject.

  2. Anonyme
    16.10.2011 at 16:26 | #3

    Thanks, this helped me.

  3. Raptor
    09.09.2012 at 03:22 | #4

    Xander,

    Great post as are all of your posts and videos. Keep up the excellent work.

  1. 01.08.2011 at 23:09 | #1
  2. 06.08.2011 at 16:15 | #2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 77 other followers

%d bloggers like this: