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

Author Topic: SFML 2.0 and Custom Shape  (Read 7001 times)

0 Members and 1 Guest are viewing this topic.

IHaveSomeQuestions

  • Newbie
  • *
  • Posts: 6
    • View Profile
SFML 2.0 and Custom Shape
« on: November 30, 2012, 01:57:49 pm »
Hi, i tried to implement a Custom Shape:

class Hexagon : public sf::Shape {
                private:
                        static std::vector<sf::Vector2f> m_Coordinates;
                protected:                     
                        virtual unsigned int getPointCount() const {
                                return 6;
                        }

                        virtual sf::Vector2f getPoint(unsigned int index) const {
                                return m_Coordinates[index];
                        }
};

//In the Constructor
        if(m_Coordinates.empty()) {
                //More Details in image /Misc/hex_geometry.jpg
                const float s = 1.f;
                const float h = 0.5f;                   //sin(30°)
                const float r = 0.86602540f;    //cos(30°)

                m_Coordinates.reserve(6);
                m_Coordinates.push_back(sf::Vector2f(0.f, -s)); //Top
                m_Coordinates.push_back(sf::Vector2f( +r, -h)); //Top-Right
                m_Coordinates.push_back(sf::Vector2f( +r, +h)); //Bottom-Right
                m_Coordinates.push_back(sf::Vector2f(0.f, +s)); //Bottom
                m_Coordinates.push_back(sf::Vector2f( -r, +h)); //Bottom-Left
                m_Coordinates.push_back(sf::Vector2f( -r, -h)); //Top-Left

                Shape::scale(1000.f, 1000.f);
                Shape::setFillColor(sf::Color(255.f, 0.f, 0.f));
                Shape::setPosition(sf::Vector2f(200.f, 200.f));
        }
 

but it won't appear if i use
Hexagon myShape;
App.draw(myShape);

i scaled it to 1000.f to be sure i can see it...

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #1 on: November 30, 2012, 02:06:07 pm »
Maybe set the points in the other order ?

Also, check the ConvexShape (and its examples) :
http://www.sfml-dev.org/documentation/2.0/classsf_1_1ConvexShape.php

Its source code is pretty basic :
https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/ConvexShape.cpp

Maybe what you're missing is a call to update ? (This might deserve a mention at the top of the page, when describing what to do to subclass Shape...)
« Last Edit: November 30, 2012, 02:10:57 pm by gyscos »

IHaveSomeQuestions

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #2 on: November 30, 2012, 02:17:54 pm »
Indeed, i did not update the Shape, inserted it at the end of the Constructor, but still can't see any Hexagon...
also tryed to align the Points CCW and CW, both doesn't work.

And i tried that one, which works:

                        sf::ConvexShape polygon;
                        polygon.setPointCount(6);
                        const float s = 1.f*100.f;
                        const float h = 0.5f*100.f;                     //sin(30°)
                        const float r = 0.86602540f*100.f;      //cos(30°)
                        polygon.setPoint(0, sf::Vector2f(0.f, -s));
                        polygon.setPoint(1, sf::Vector2f( -r, -h));
                        polygon.setPoint(2, sf::Vector2f( -r, +h));
                        polygon.setPoint(3, sf::Vector2f(0.f, +s));
                        polygon.setPoint(4, sf::Vector2f( +r, +h));
                        polygon.setPoint(5, sf::Vector2f( +r, -h));
                        //polygon.setOutlineColor(sf::Color::Red);
                        //polygon.setOutlineThickness(5);
                        polygon.setPosition(200, 200);
                        App.draw(polygon);

so, i decided to update imediatly after inserting a point:
class Hexagon : public sf::Shape {
        private:
            static std::vector<sf::Vector2f> m_Coordinates;
        protected:        
            virtual unsigned int getPointCount() const {
                return m_Coordinates.size();
            }

            virtual sf::Vector2f getPoint(unsigned int index) const {
                return m_Coordinates[index];
            }
};

//In the Constructor
    if(m_Coordinates.empty()) {
        //More Details in image /Misc/hex_geometry.jpg
        const float s = 1.f;
        const float h = 0.5f;           //sin(30°)
        const float r = 0.86602540f;    //cos(30°)

        m_Coordinates.reserve(6);
        m_Coordinates.push_back(sf::Vector2f(0.f, -s)); //Top
        Shape::update();
        m_Coordinates.push_back(sf::Vector2f( -r, -h)); //Top-Left
        Shape::update();
        m_Coordinates.push_back(sf::Vector2f( -r, +h)); //Bottom-Left
        Shape::update();
        m_Coordinates.push_back(sf::Vector2f(0.f, +s)); //Bottom
        Shape::update();
        m_Coordinates.push_back(sf::Vector2f( +r, +h)); //Bottom-Right
        Shape::update();
        m_Coordinates.push_back(sf::Vector2f( +r, -h)); //Top-Right
        Shape::update();

        Shape::scale(1000.f, 1000.f);
        Shape::setFillColor(sf::Color(255.f, 0.f, 0.f));
        Shape::setPosition(sf::Vector2f(200.f, 200.f));
    }

But it does not work...

Well, now i derived from sf::ConvexShape. It works, but i still want to know why it doesn't work with sf::Shape, also i don't want to create the same points for every Hexagon over and over again, it's  a waste, the solution would be to make ConvexShape a static member, but that's ugly again. I really want to inherit from sf::Shape, as it makes the most sense...
 
« Last Edit: November 30, 2012, 02:41:04 pm by IHaveSomeQuestions »

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #3 on: November 30, 2012, 02:43:52 pm »
Just read the source code for ConvexShape, it's only a few lines. Try to add them to your code, see what differs, and when it starts working / not working...

IHaveSomeQuestions

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #4 on: November 30, 2012, 03:11:51 pm »
Ok, i started from scratch and it works now, sadly i have no clue what went wrong in first place.

But now comes the next problem, creating a 15x15 Hexagonboard is not possible, because the Framerate drops to ~10fps in release mode, in debug mode it's like a screenshot. 15x15, that's 225 Hexagons, assume that a Hexagon is 6 Triangles = 1'350 Triangles or 675 "Sprites".

If i create 2'000 sprites with texture and draw them the Framerate is much higher. Am i missing here something??

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: SFML 2.0 and Custom Shape
« Reply #5 on: November 30, 2012, 03:15:29 pm »
Shapes use more triangles (6 for an hexagon, 2 for a sprite).

If your background is static, you'd better put all your 225 hexagons in a single vertex array. This way you'll get maximum performances.

PS: an easy way to construct a N-sided regular polygon is to create a sf::CircleShape with N edges ;)
Laurent Gomila - SFML developer

IHaveSomeQuestions

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #6 on: November 30, 2012, 03:37:50 pm »
Ok, thanks for the advise. But i want to click on the Hexagons, color them, etc., and it has to be somewhat OOP.
I just testet 50x50 Sprites(50*50*2=5'000 Triangles) and 20x20 Hexagons(20*20*6=2'400 Triangles). All fit's on the screen, with no overlaping. The FPS with Sprites is OK, the FPS with Hexagons is horroble, even though the Hexagons have no Outline and no Texture. Can you explain why's this? And how can i improve performance without packing everything into a Vertexarray.

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: SFML 2.0 and Custom Shape
« Reply #7 on: December 02, 2012, 05:47:56 am »
Quote
The FPS with Sprites is OK, the FPS with Hexagons is horrible, even though the Hexagons have no Outline and no Texture.

Quote
Shapes use more triangles (6 for an hexagon, 2 for a sprite).

This means more vertices even with the same amount of draw calls. Since a sprite is a quad it's better than a hexagon when used in large amounts. Texturing isn't really that expensive when done correctly so it's not that much of an issue regarding FPS.

Quote
And how can i improve performance without packing everything into a Vertexarray.

I can't think of any other, since all you do is render the hexagons. The low level API may seem scary at first, but it gives you much more choices than you could expect with little payload, straight OpenGL VertexArrays require more code and may be more confusing to use at first so actually having VertexArray is a great time saver.

Also note that with the Shapes approach you have to set every single point yourself, just like you do with a VertexArray, so if you did one, you can perfectly do the other.
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

IHaveSomeQuestions

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #8 on: December 02, 2012, 08:22:31 pm »
Ok, i just implemented it as a single Vertexarray within a HexagonBorad class and yeah it's Fast as Hell(compared to before, where 15x15 wasn't possible), 200x200 Hexagons in Debugmode no Problem. But implementing the Mousechecks was quite a pain, because the tiles have Spacings between them, what made it difficult for me to calculate mouse coordinates to Board tiles. Before i just used Hexagon.isInside(Vector2i MouseCoordinates).

gyscos

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
Re: SFML 2.0 and Custom Shape
« Reply #9 on: December 03, 2012, 09:49:12 am »
Checking if a point is inside a polygon is not so hard :
http://en.wikipedia.org/wiki/Point_in_polygon