3

Hey i'm working on a class called a "Body" which holds shapes and sprites together as one object. I would like to get into the source code and add a new overload RenderWindow's Draw() function, so this new object can be taken in and drawn easily. How do i do this?

I'm currently using

  • Windows 7
  • SFML 1.6
  • Newly msVS++ 2010 compiled static debug libraries and dlls
  • original include folder

EDIT:

I also found this in the Drawable.hpp header:

private :

    friend class RenderTarget;

////////////////////////////////////////////////////////////
/// Draw the object into the specified window
///
/// \param Target : Target into which render the object
///
////////////////////////////////////////////////////////////
void Draw(RenderTarget& Target) const;

////////////////////////////////////////////////////////////
/// Render the specific geometry of the object
///
/// \param Target : Target into which render the object
///
////////////////////////////////////////////////////////////
virtual void Render(RenderTarget& Target) const = 0;

but i can't figure out where the full code of each function is, just the declarations. I didn't find a mini tutorial there either unfortunately...

Griffin
  • 2,399
  • 7
  • 48
  • 83
  • To what "Windows Draw()" function are you referring? – Nicol Bolas Jul 10 '11 at 00:10
  • Well i know i draw stuff by the typing Window.Draw(obj); – Griffin Jul 10 '11 at 00:17
  • SFML's Window class does not have a Draw function. So I reiterate: to what `Windows.Draw` function are you referring? Is this in your own code or is this in some library? – Nicol Bolas Jul 10 '11 at 00:25
  • oh its a RenderWindow, let me put that in the Question. – Griffin Jul 10 '11 at 01:28
  • @Griffin The full code (implementation) will be in the corresponding `.cpp` file, not in the header files. Compare `Sprite.hpp` and `Sprite.cpp`. – Zack The Human Jul 10 '11 at 02:46
  • @Griffin: The bug I sent to SFML was closed with [this message](https://github.com/LaurentGomila/SFML/issues/74#issuecomment-1541057). It seems that Drawable isn't going to be an abstract base class in the future. So you may want to avoid doing this entirely. Just give your object a `draw` function that will in turn draw each of the things it contains. – Nicol Bolas Jul 10 '11 at 08:12

2 Answers2

4

Note:

Before you derive from and implemented your own Drawable, you may want to consider if you need to do it at all. The author of SFML has stated that sf::Drawable was not initially meant to be subclassed outside of SFML.

That aside,

For SFML 1.6:

It appears that all you need to do is derive your class from sf::Drawable, and then implement a virtual Render function.

class MyDrawable : public sf::Drawable {

private:

    virtual void Render(RenderTarget& target) const {
        // Do some rendering of whatever...
        target.Draw(mySubSprite);
    }

    sf::Sprite mySubSprite;

};

An example of this can be found on the SFML forums.

For SFML 2.0:

The Drawable header file from SFML contains comments that describe how to derive your own Drawable classes. You do not need to modify the SFML source code to create new Drawables.

It also includes a simple example:

class MyDrawable : public sf::Drawable
{
public :
   ...
private :
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // You can draw other high-level objects
        target.draw(m_sprite, states);
        // ... or use the low-level API
        states.texture = &m_texture;
        target.draw(m_vertices, states);
        // ... or draw with OpenGL directly
        glBegin(GL_QUADS);
        ...
        glEnd();
    }
    sf::Sprite m_sprite;
    sf::Texture m_texture;
    sf::VertexArray m_vertices;
};

This example may apply to SFML 2.0, but if you inspect the Drawable.hpp from whatever version of SFML you have it should contain a similar example.

Zack The Human
  • 8,373
  • 7
  • 39
  • 60
0

RenderWindow::Draw takes an object of the abstract class type Drawable. Which means that, in theory, you can just make your Body class a child of Drawable and overload some virtual methods to make it render.

But that doesn't seem to be the case. The docs for Drawable show that there's only one virtual function in that class: the destructor. Which is... kinda stupid.

However, looks can be deceiving. I was checking the 2.0 documentation to see if they had figured out how to make an inheritance hierarchy correctly, and it turns out that they do have virtual methods to override. It's just that they're all private (which itself is fine, and in fact a very good thing), and the SFML guys didn't tell Doxygen to generate documentation for private members. I filed a bug with them on this.

Until they update their docs, the only thing I can say is to look at the header, and maybe the source code to Sprite, and try to figure out how to create a derived Drawable class correctly.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • ok thanks! also would it not be possible just simply add a draw function to drawable that simply draws each shape and sprite, so i can just use their draw() functions? – Griffin Jul 10 '11 at 02:05
  • @Griffin: Besides the fact that it would involve changing a library that isn't yours, that you don't really know how it works, and that would almost certainly introduce bugs that the library wouldn't have if you just did it _their_ way? Yes, you could do that. But you could also rewrite SFML yourself. I would suggest taking the time to figure out how to do things the way the library wants you to, rather than breaking the library and forcing it to do things your way. – Nicol Bolas Jul 10 '11 at 02:11
  • alright so i went through the source and edited the question, does the new info help at all? I can't find the full function definitions though.... – Griffin Jul 10 '11 at 02:41