Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Advice on window seperation needed  (Read 5194 times)

0 Members and 1 Guest are viewing this topic.

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Advice on window seperation needed
« on: June 02, 2014, 01:43:02 am »
hi,

i want to split my window in three (well known) parts basically:

1) game region where the game itself is drawn e.g. the map, units and everything else
2) minimap in the typical left bottom corner
3) unitmenu in the bottom right part of the screen for the player to give commands to the units

like this:

i want to use SfGUI for the menu.

How do i best implement this with sfml? if this was QT i would just use 3 widgets and 2 layouts to get the proper ordering and positions but in SFML and SFGUI im unsure how to do it.

Any advice is greatly appreciated :)

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Advice on window seperation needed
« Reply #1 on: June 02, 2014, 01:50:46 am »
I believe using one View for each region is the best/simplest approach for this.  See http://www.sfml-dev.org/tutorials/2.1/graphics-view.php

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #2 on: June 02, 2014, 04:15:42 pm »
Thanks your answer.

I understood the tutorial so that sf::View is made for anything related to the rendering of the game world.
The menu is not part of that it is merely another layer drawn upon the game view. i dont see why a sf::view would be the way to go

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Advice on window seperation needed
« Reply #3 on: June 02, 2014, 08:03:54 pm »
Just because that's the example the tutorial uses doesn't mean it's the only thing you can do with Views.

sf::Views are a way of telling OpenGL "I want this region of the rendering space to appear in this portion of my window".  The term "game world" is just that tutorial's way of distinguishing between the graphical space things get rendered in and the on-screen pixels the user actually sees.  It is not meant to exclude other drawables like menus.
« Last Edit: June 02, 2014, 08:15:02 pm by Ixrec »

Turbine

  • Full Member
  • ***
  • Posts: 102
    • View Profile
Re: Advice on window seperation needed
« Reply #4 on: June 03, 2014, 09:06:48 am »
A few years ago I did something similar with these libraries and requirements, I'll talk briefly about these things.

So the two main areas of interest are views and SFGUI. I'll start off by picking at the oddities of each.

View
The name is self explanatory, it represents a portion of a larger game world. When drawing you may want to draw as an overlay and then reset draw target to the scroll-able view area for unit drawing. Inheriting sf::View is quite common. However note there's no getPosition() anymore, it's been replaced with getCenter(), which gets the centre most position in view instead of the top left corner.

SFGUI
I used to use this before CEGUI. To get a minimap working, I just used an sf::Image (unless I remember incorrectly), and make it draw the new tiles which come in view as you scroll.

There were a few things which put me off using SFGUI however.

Here's a list on some of the notable good and bad:
  • The documentation is very good, clean and consistent.
  • It integrates well with SFML and is updated regularly regularly.
  • Event handling is simple and effective.
  • The lack of aesthetic fulfillment leaves interfaces looking quite primitive and plain.
  • Layouts can be a real hassle to get absolutely right. We always had to settle for something less

CEGUI was a little more difficult to compile as minor changes had to be made for it to successfully compile under MinGW, also the documentation for the CEGUI integration for SFML is both outdated for the latest SFML and CEGUI. So this helps: http://skyr.at/sfml-and-cegui-083.html

I'd say CEGUI is a lot better for games and can be made to look much better and the layout handling is great in comparison. It works well with dynamic alignment and resizing, SFGUI is a bit of a hassle in alignment. Maybe it's changed, although I don't believe it has.

CEGUI still has some daft qualities to it, some of which has been addressed recently. For instance, event handling related data in the doc has to have a series of if/else statements static casting it into various type of event data until the cast type is accepted. Naming is very inconsistent, there is a close button yet the method name to "close" a window is destroy. Many defaults are a bit strange, like the close button by default won't do anything until an event is added. The cursor/text/windows all stretch and resize on window change, giving blurred edges and strange graphical artifacts. Windows need to be coded to stop them going out of view, a few annoyances here.. I could go on for days, ultimately it's feature complete and much more convenient to theme, making it desirable for game interfaces.

It's just our personal opinion.
« Last Edit: June 03, 2014, 09:23:00 am by Turbine »

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #5 on: June 05, 2014, 03:34:23 am »
Thanks for your indepth answer :) (though the intention of the thread was to learn how to do what i talked about^^ :D).

So im trying to implement the minimap now which is supposed to show the whole "map".
For this i simply made a dummy tilemap which size is greater than the renderwindows one.

I use the following views to render both the gameview and the minimap:
        sf::View mapview(app_window.getDefaultView());
        sf::View minimap(app_window.getDefaultView());

        mapview.setViewport(sf::FloatRect(0.f,0.f,1.f,0.75f));
        minimap.setViewport(sf::FloatRect(0.f, 0.75, 0.5, 0.25));

// some more code to generate tilemap and draw it with respective views
 

i get the following:


Now for a real minimap i want it to show ALL tiles the map consists of (size is 20x20 with 32x32 pixels per tile), but zooming or resizing will somehow stretch the way its drawn in an undesired way (well i get that if you zoom it has to be contracted).
How would i set up a view for the minimap so that it will show all 20x20 tiles inside its viewport?



kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #6 on: June 06, 2014, 04:14:56 am »
im really interested in this as the tutorial is not helping much sadly.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Advice on window seperation needed
« Reply #7 on: June 06, 2014, 08:09:15 am »
I'm not really sure what the problem is.  If the 20x20 tiles take up, say, 400x400 pixels, then set your view to be 400x400 and your viewport to whatever and it'll draw all of those tiles in the region defined by the viewport.

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #8 on: June 06, 2014, 07:02:07 pm »
hi,

sadly that is not entirely true.

when i do this i get this:


the view is shifted by some offset when i set the size of it to the size of the whole tilemap.

all i did was to add one line, which does what you told me:
        sf::View mapview(app_window.getDefaultView());
        sf::View minimap(app_window.getDefaultView());
        //sf::View menu(app_window.getDefaultView());

        mapview.setViewport(sf::FloatRect(0.f,0.f,1.f,0.75f));
        minimap.setViewport(sf::FloatRect(0.f, 0.75, 0.5, 0.25));
        minimap.setSize(20*32,20*32);
 

but i don't want this behaviour, i want the minimap to be drawn at the position specified in "setViewport" (well to be precise i want the map to be drawn at the top left corner of that viewport)

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Advice on window seperation needed
« Reply #9 on: June 06, 2014, 07:49:09 pm »
There's probably a simple bug in your code then.  For instance, are you sure that your tilemap actually starts at 0,0?

If you could provide a complete and minimal example that has this problem then we might be able to help you find the bug.

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #10 on: June 06, 2014, 10:24:03 pm »
There's probably a simple bug in your code then.  For instance, are you sure that your tilemap actually starts at 0,0?

If you could provide a complete and minimal example that has this problem then we might be able to help you find the bug.

Here is my complete code (note: was randomly changing some example stuff from sfGUI thats why the code is so ugly):

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

sf::Texture m_tileset;
sf::VertexArray m_vertices;
void setTilemap()
{
    m_tileset.loadFromFile("Tileset.png");
    m_vertices.setPrimitiveType(sf::Quads);
    m_vertices.resize(20*20*4); // we use some dummy numbers to get a mapwidth > renderwindow_width

    for (unsigned int i = 0; i < 20; ++i)
    {
        for (unsigned int j = 0; j < 20; ++j)
        {
            //get the current tile number
            int tileNumber = 34;

            // find its position in the tileset texture
            int tu = tileNumber % (m_tileset.getSize().x / 32);
            int tv = tileNumber / (m_tileset.getSize().x / 32);

            // get a pointer to the current tile's quad
            sf::Vertex* quad = &m_vertices[(i + j * 20) * 4];

            // define its 4 corners
            quad[0].position = sf::Vector2f(i * 32, j * 32);
            quad[1].position = sf::Vector2f((i + 1) * 32, j * 32);
            quad[2].position = sf::Vector2f((i + 1) * 32, (j + 1) * 32);
            quad[3].position = sf::Vector2f(i * 32, (j + 1) * 32);

            // define its 4 texture coordinates
            quad[0].texCoords = sf::Vector2f(tu * 32, tv * 32);
            quad[1].texCoords = sf::Vector2f((tu + 1) * 32, tv * 32);
            quad[2].texCoords = sf::Vector2f((tu + 1) * 32, (tv + 1) * 32);
            quad[3].texCoords = sf::Vector2f(tu * 32, (tv + 1) * 32);
        }
    }
}



int main() {
        // Create the main SFML window
        float width = 320.f;
        float height = 420.f;
        sf::RenderWindow app_window( sf::VideoMode(width,height), "SFGUI Canvas Example", sf::Style::Titlebar | sf::Style::Close );

        // Start the game loop
        app_window.setFramerateLimit(20);
        setTilemap();
        sf::RenderStates states;
        states = &m_tileset;

        sf::View mapview(app_window.getDefaultView());
        sf::View minimap(app_window.getDefaultView());
        //sf::View menu(app_window.getDefaultView());

        mapview.setViewport(sf::FloatRect(0.f,0.f,1.f,0.75f));
        minimap.setViewport(sf::FloatRect(0.f, 0.75, 0.5, 0.25));
        minimap.setSize(20*32,20*32);




        while ( app_window.isOpen() ) {
                sf::Event event;

                while ( app_window.pollEvent( event ) ) {

                        // Close window : exit
                        if ( event.type == sf::Event::Closed ) {
                                app_window.close();
                        }
                }

                app_window.clear();
        app_window.setView(mapview);
                app_window.draw(m_vertices,states);

        app_window.setView(minimap);
                app_window.draw(m_vertices,states);


                app_window.display();
        }
        return EXIT_SUCCESS;
}
 

the used tileset can be found in the attachment.

the map should start at (0,0), thats what you get for the quads position if i and j are both zero.

« Last Edit: June 06, 2014, 10:30:06 pm by kingcools »

kingcools

  • Jr. Member
  • **
  • Posts: 57
    • View Profile
Re: Advice on window seperation needed
« Reply #11 on: June 09, 2014, 12:41:50 am »
im still wondering why this happens :/