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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Kojay

Pages: [1]
1
General discussions / Microbenchmarks
« on: November 04, 2015, 08:23:25 pm »
Inspired by Chandler Carruth's talk at CppCon2015, I was thinking SFML could have a suite of microbenchmarks.

I have made a prototype at https://github.com/Kojirion/SFML/tree/benchmarks
This is using GoogleBenchmark as a submodule.



These are of course only a few of SFML's classes. It will be far simpler to have these benchmarks if/when there are unit tests.These
  • highlight the differences between getters that return a value in memory and those that perform a calculation.
  • highlight he difference between flipping an image vertically and horizontally
  • if these functions are refactored, they can serve as indication on how performance is affected

There are some differences to what Carruth did in the talk. He goes on to use perf to determine exactly what is being benchmarked, as well as using an assembly trick to prevent the optimizer from optimizing away the things he's interested in.

I have only gone as far as to use volatile for the return value of functions. This is a different strategy (he gets a question about it towards the end of the talk) and seems sufficient for the moment, as the functions which do not return a value do not appear optimized away (note how he had to put std::vector in the loop, while in what I have written so far, the variables can be defined outside).
But I have not gone through perf/assembly to verify.

And surely it looks pretty.

2
General discussions / Invalid read in KDE
« on: June 28, 2015, 11:23:49 pm »
Hello,

I 'm on Kubuntu 15.04 and running SFML applications through valgrind, they produce the following invalid read:

==14802== Invalid read of size 1
==14802==    at 0x4C2F134: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14802==    by 0x5314CC7: sf::String::String(char const*, std::locale const&) (String.cpp:73)
==14802==    by 0x50E10B7: (anonymous namespace)::ewmhSupported() (WindowImplX11.cpp:235)
==14802==    by 0x50E2849: sf::priv::WindowImplX11::WindowImplX11(sf::VideoMode, sf::String const&, unsigned long, sf::ContextSettings const&) (WindowImplX11.cpp:579)
==14802==    by 0x50D9BED: sf::priv::WindowImpl::create(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) (WindowImpl.cpp:71)
==14802==    by 0x50D9188: sf::Window::create(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) (Window.cpp:124)
==14802==    by 0x4E8D9E8: sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) (RenderWindow.cpp:45)
==14802==    by 0x4015F3: main (main.cpp:5)
 

suggesting that a non-null terminated string has been passed to strlen; in fact the string passed to it when valgrind complains is "KWin0/inA" - it is the name of the window manager, obtained from line 233 of WindowImplX11:

const char* name = reinterpret_cast<const char*>(xcb_get_property_value(wmName.get()));
 

If I had to guess, it was supposed to be "KWin" but they got their slash the wrong way round. In any case, if this is correct it is not SFML's fault, but you may have an idea how to guard against receiving such a problematic string; or perhaps you have other thoughts on the issue.

3
Feature requests / Ostream operators << for SFML classes
« on: March 19, 2014, 04:51:38 pm »
I propose that SFML provides ostream operators for its classes to make for easier debugging (like Qt does - but not necessarily all the features of qDebug).

The chief design question in my view is whether those should be provided in a single header or along with each class. The ones for Vector and Rect would be presumably templated and have to be in a header, while the rest could be implemented in the source files.

4
The famous Separating Axis algorithm for determining intersection between arbitrary sf::Shapes:

bool intersect(const sf::Shape& shape_1, const sf::Shape& shape_2) {
    if (existsSeparatingAxisForFirst(shape_1, shape_2))
        return false;

    return (!existsSeparatingAxisForFirst(shape_2, shape_1));
}
 

The functions it is implemented in terms of:

sf::Vector2f getPoint(const sf::Shape& shape, unsigned int index) {
    return shape.getTransform().transformPoint(shape.getPoint(index));
}

sf::Vector2f projectShapeOn(const sf::Shape& shape, const sf::Vector2f& axis) {

    auto point = getPoint(shape, 0);
    auto initial = dotProduct(point, axis);

    sf::Vector2f minmax(initial, initial);

    for (unsigned int i=1; i<shape.getPointCount(); ++i){
        auto point = getPoint(shape, i);
        auto projected = dotProduct(point, axis);

        if (projected < minmax.x)
            minmax.x = projected;
        if (projected > minmax.y)
            minmax.y = projected;
    }

    return minmax;
}

bool existsSeparatingAxisForFirst(const sf::Shape& shape_1, const sf::Shape& shape_2) {
    unsigned int pointCount = shape_1.getPointCount();

    for (unsigned int i=0; i<pointCount; ++i){
        unsigned int next_i = (i + 1) % pointCount;
        auto side = getPoint(shape_1, next_i) - getPoint(shape_1, i);
        auto perpendicular = unitVector(perpendicularVector(side));
        auto minmax_1 = projectShapeOn(shape_1, perpendicular);
        auto minmax_2 = projectShapeOn(shape_2, perpendicular);

        if ((minmax_1.y < minmax_2.x) || (minmax_2.y < minmax_1.x))
            return true;
    }

    return false;
}
 

A simple example:


Arrows to move current shape, W,A,S,D to rotate it, Q,E,Z,C to scale it.
Spacebar to cycle through shapes.
Shapes are red when they don't intersect with any other. They turn green if they intersect with at least one other shape.

Source for this example at:

https://gist.github.com/Kojirion/9635598

(For convenience, vector math functions are included; they are similar to those provided by Thor)

A few notes, possibly to be addressed in the future:

- The algorithm can not be applied to sprites at the moment; it should be easy to accomplish this with a Facade.
- It is assumed the Shape is convex (as stated in the SFML docs), there are no checks that this is so.
- Points are transformed twice. Caching the results would likely improve performance.

Edit: Changed title from "Pixel perfect collision detection" so as not to imply this is a mask based algorithm.

5
SFML wiki / Application class (using sfml, sfgui and thor)
« on: January 02, 2014, 09:19:17 pm »
Hello,

in several projects now I have used these 3 libraries as a sort of lightweight gui framework, with the emphasis on graphical drawing on a canvas. The boilerplate code is contained within the following class:

#include <SFML/Window.hpp>
#include <Thor/Input/ActionMap.hpp>
#include <Thor/Input/EventSystem.hpp>
#include <SFGUI/SFGUI.hpp>

typedef thor::ActionMap<std::string> ActionMap;
typedef ActionMap::CallbackSystem CallbackSystem;

class Application
{
public:
    Application();
    void run();

private:
    sfg::SFGUI sfgui;
    sf::Window window;
    sfg::Desktop desktop;
    sf::Image icon;
    ActionMap actions;
    CallbackSystem system;
};
 
#include "Application.hpp"

Application::Application():
    window(sf::VideoMode(800, 600), "Application")
{
    if (icon.loadFromFile(""))
        window.setIcon(icon.getSize().x, icon.getSize().y, icon.getPixelsPtr());

    window.setFramerateLimit(60);

    actions["Close"] = thor::Action(sf::Event::Closed);
    system.connect("Close", std::bind(&sf::Window::close, &window));
}

void Application::run()
{
    sf::Clock clock;

    while (window.isOpen()){

        actions.clearEvents();

        sf::Event event;
        while (window.pollEvent(event)){
            actions.pushEvent(event);
            desktop.HandleEvent(event);
        }

        actions.invokeCallbacks(system, &window);
        desktop.Update(clock.restart().asSeconds());

        sfgui.Display(window);
        window.display();
    }
}
 

Note that sfml drawing can be done on a sfg::Canvas, therefore a sf::RenderWindow is not required.
Comments welcome.

6
Feature requests / Getting a sprite's vertices
« on: December 19, 2013, 11:56:10 pm »
It is known that the need to draw sprites individually hurts performance and that one should prefer vertex arrays to that end. It is then a shame that sf::Sprite's internal vertices cannot be accessed.

What I 've found myself doing too often is making a class holding an array of four sf::Vertex, that can be appended to a VertexArray or similar container when it is time to draw. Often, this class will also need a getBounds method, setters for the texture rect and so on, making it similar to a sf::Sprite.

I would propose then that there is a way to use sf::Sprite for this purpose; either

a) sf::Sprite::getVertices() that returns an array of the 4 vertices or
b) sf::Sprite::appendTo() taking as parameter either
    i) a sf::VertexArray
    ii) an output iterator, to accomodate the user's container of sf::Vertex.

7
SFML wiki / Line Shape
« on: August 31, 2013, 12:14:50 pm »
Following my suggestion in the features section to add a sf::Line again, I looked to the wiki about adding the proposed class and found there is a page on it already.. I believe though the classes presented there are overkill and would suggest these instead:

Deriving from sf::Drawable

A simple class that derives from sf::Drawable only.

class sfLine : public sf::Drawable
{
public:
    sfLine(const sf::Vector2f& point1, const sf::Vector2f& point2):
        color(sf::Color::Yellow), thickness(5.f)
    {
        sf::Vector2f direction = point2 - point1;
        sf::Vector2f unitDirection = direction/std::sqrt(direction.x*direction.x+direction.y*direction.y);
        sf::Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x);

        sf::Vector2f offset = (thickness/2.f)*unitPerpendicular;

        vertices[0].position = point1 + offset;
        vertices[1].position = point2 + offset;
        vertices[2].position = point2 - offset;
        vertices[3].position = point1 - offset;

        for (int i=0; i<4; ++i)
            vertices[i].color = color;
    }

    void draw(sf::RenderTarget &target, sf::RenderStates states) const
    {
        target.draw(vertices,4,sf::Quads);
    }


private:
    sf::Vertex vertices[4];
    float thickness;
    sf::Color color;
};
 

Deriving from sf::Shape
Header and source for a sf::LineShape, closely modelled after sf::RectangleShape. These can be easily added to one's copy of SFML with minor additions to the relevant CMakeLists.txt and the Graphics master header. Doxygen comments were removed for space.

#ifndef SFML_LINESHAPE_HPP
#define SFML_LINESHAPE_HPP

#include <SFML/Graphics/Export.hpp>
#include <SFML/Graphics/Shape.hpp>


namespace sf
{
        class SFML_GRAPHICS_API LineShape : public Shape
        {
                public :

                explicit LineShape(const Vector2f& point1, const Vector2f& point2);

                void setThickness(float thickness);

                float getThickness() const;

                float getLength() const;

                virtual unsigned int getPointCount() const;

                virtual Vector2f getPoint(unsigned int index) const;

                private :

    Vector2f m_direction; ///< Direction of the line
    float m_thickness;    ///< Thickness of the line
};

} // namespace sf


#endif // SFML_LINESHAPE_HPP
 

#include <SFML/Graphics/LineShape.hpp>
#include <cmath>


namespace sf
{

LineShape::LineShape(const Vector2f& point1, const Vector2f& point2):
    m_direction(point2 - point1)    
{
    setPosition(point1);
    setThickness(2.f);    
}


void LineShape::setThickness(float thickness)
{
    m_thickness = thickness;
    update();
}


float LineShape::getThickness() const
{
    return m_thickness;
}


float LineShape::getLength() const
{
    return std::sqrt(m_direction.x*m_direction.x+m_direction.y*m_direction.y);
}


unsigned int LineShape::getPointCount() const
{
    return 4;
}


Vector2f LineShape::getPoint(unsigned int index) const
{
    Vector2f unitDirection = m_direction/getLength();
    Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x);

    Vector2f offset = (m_thickness/2.f)*unitPerpendicular;

    switch (index)
    {
        default:
        case 0: return offset;
        case 1: return (m_direction + offset);
        case 2: return (m_direction - offset);
        case 3: return (-offset);
    }
}

} // namespace sf
 

8
Feature requests / A simple sf::Line (segment)
« on: August 25, 2013, 07:31:04 pm »
This has been asked for here and on irc. The tutorial claims a line with no thickness is simply two sf::Vertex, whereas a line with thickness is a rotated rectangle.
However, there's a difference: if the user has two points and he wants a line segment between them with thickness, then boilerplate code needs to be written for said rectangle to achieve desired effect.

A simple class for line segments could look like this:

class sfLine : public sf::Drawable
{
public:
    sfLine(const sf::Vector2f& point1, const sf::Vector2f& point2):
        color(sf::Color::Yellow), thickness(5.f)
    {
        sf::Vector2f direction = point2 - point1;
        sf::Vector2f unitDirection = direction/std::sqrt(direction.x*direction.x+direction.y*direction.y);
        sf::Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x);

        float halfThick = thickness/2;

        vertices[0].position = point1 + halfThick*unitPerpendicular;
        vertices[1].position = point2 + halfThick*unitPerpendicular;
        vertices[2].position = point2 - halfThick*unitPerpendicular;
        vertices[3].position = point1 - halfThick*unitPerpendicular;

        for (auto& vertex : vertices)
            vertex.color = color;
    }

    void draw(sf::RenderTarget &target, sf::RenderStates states) const
    {
        target.draw(vertices.data(),4,sf::Quads);
    }


private:
    std::array<sf::Vertex,4> vertices;
    float thickness;
    sf::Color color;
};
 

The c++11 keywords can be done away with, setters for color and thickness added, assert that the points are distinct.

Note how Thor library offers a line shape and given point1 and point2 a segment could be obtained this way:

auto myLine = thor::Shapes::line(point2-point1,sf::Color::Yellow, 3.f);
myLine.setPosition(point1);
 

But I do think this results in a 'heavier' myLine than the class presented above.




9
SFML projects / Black Wolf, an open source chess gui - play on FICS!
« on: August 11, 2013, 06:27:56 am »
Black Wolf is an open source cross platform chess gui to play on the Free Internet Chess Server



Source at: https://github.com/Kojirion/blackWolf

10
General / Constraining movement of a draggable object
« on: July 20, 2013, 05:15:29 pm »
Hello,

I 've put together a small puzzle game:



The yellow balls can be dragged around. However, I would like to constrain their movement onto the red lines. I imagine this is a common thing to do and I don't want to be reinventing the wheel.

The code is not big.

There are two issues as I see it:
-when clicking on a ball to move it, it needs to decide which edge to follow along
-when moving it needs to stick to the edge.

I 'm not necessarily looking for code as much as a general guideline on how to implement such a thing. If my current design would need to be scrapped, that's fine. Thanks.

11
SFML projects / Group theory nightmares
« on: April 03, 2013, 09:04:55 am »
Hello,

this is a program aimed at putting a bit of life into Caley tables:

https://dl.dropbox.com/u/105214643/screenie.jpg

Currently, it can show the Caley table of several groups of permutations. Choosing a permutation from the top row displays a brief animation of the permutation acting on the polygon (although atm these are not the rotations or reflections you 'd expect). Then, in Subgroup Hunt mode it is possible to select multiple elements to identify a subgroup (highlighted red if it isn't, green if it is). If it is a subgroup it's then possible to construct the left or right cosets - elements will be rearranged automatically to show how the cosets partition the group.
Probably SFML is overkill for what it is at the moment, but I 'm hoping to get more ambitious with it; possible next steps could include asking the user to fill the table/identify subgroups & cosets; showing the permutations act on 3d objects and how they may be used to solve coloring problems; conjugacy classes etc

Compiled on windows: https://dl.dropbox.com/u/105214643/advan.zip

Compiled on ubuntu 12: https://dl.dropbox.com/u/105214643/advan.tar.gz

The ubuntu one I 've not been sure what to include in. Currenty it contains the application compiled, as well as the library files. I advise those who would run it to extract and do
export LD_LIBRARY_PATH=.
./ aan

to run it, so they do not have to install the libraries. Is this a good idea? Is there an easier way to do it still? I understand many linux users would rather build it themselves but not some of those I 'd like to share it with.

More features will be coming soon.


12
General / Flipping a polygon animation
« on: March 25, 2013, 12:42:43 am »
Hello,

I wish to animate the flip of a polygon (say, reflect it across the y axis): I 'd like to show it "sticking out" of the screen as it is flipped. This borders on 3d, however I don't want to actually use opengl simply for this. On the other hand, the polygon may be freely rotated, so I cannot prepare still images for the animation.

Any pointers as to what would be the best approach/tools would be appreciated.

13
General / Default font gone?
« on: October 21, 2012, 01:00:32 am »
Hello,

First post here so I should start by saying a great thank you to the creators of this pretty neat library. I 've been toying with in since a few months and it's been easy to learn and use and anything I 'd like to do I pretty much always find there's a tool for it.

On to my question then; I seem to have got two different builds of sfml2 (both 32-bit vs2010), with a slight difference in the sf::Text constructor;

Code: [Select]
explicit Text(const String& string, const Font& font = Font::getDefaultFont(), unsigned int characterSize = 30);
vs

Code: [Select]
explicit Text(const String& string, const Font& font, unsigned int characterSize = 30);

ie the second one doesn't provide a default font. Is the second piece the newer version or have I got that wrong? If it is, may I ask the reason for this change? Thanks.

Pages: [1]