SFML community forums

Help => Graphics => Topic started by: kubawal on November 20, 2014, 07:23:14 pm

Title: Stop drawing pixels out of region
Post by: kubawal on November 20, 2014, 07:23:14 pm
I'm drawing lots of rotated sprites.
And i have to draw some of this sprites partly - that ones, that are partly out of given region.
Briefly, I want do draw only that pixels of sprites that are in specified region.
Effect have to be like using sf::View but on single drawable object

PS I do it in my own Drawable component so i can't use sf::View::setViewport().

Any ideas?
Title: Re: Stop drawing pixels out of region
Post by: Gambit on November 20, 2014, 07:24:54 pm
You will probably have to use an OpenGL stencil for this sort of operation, I'm not sure that SFML supports partially drawing sprites or textures. Alternatively you could probably use a shader but that might be a little more work.
Title: Re: Stop drawing pixels out of region
Post by: kubawal on November 20, 2014, 07:29:34 pm
Shaders isn't my best side :)
Title: Re: Stop drawing pixels out of region
Post by: Laurent on November 20, 2014, 07:37:59 pm
Why can't you use sf::View? It's your best option to implement clipping without doing OpenGL stuff.
Title: Re: Stop drawing pixels out of region
Post by: kubawal on November 21, 2014, 05:26:58 pm
So i have another question: does view transformations applies on end of frame or for each draw()?
I'm asking it because i have idea:
virtual void draw(RenderTarget& target, RenderStates rs)
{
rs.transform *= getTransform();

View oldV = target.getView();

View newV;
// setting parameters of new view
target.setView(newV);

// draw my stuff

target.setView(oldV);
 
Does my stuff draw with newV wiew or oldV view?
Can I apply view on only a few of objects?
Title: Re: Stop drawing pixels out of region
Post by: eXpl0it3r on November 21, 2014, 05:50:11 pm
Once you set the view, all objects that get drawn after, will be drawn with the set view.

Keep in mind though that the draw function from sf::Drawable is const (http://sfml-dev.org/documentation/2.1/classsf_1_1Drawable.php#a90d2c88bba9b035a0844eccb380ef631), so you can't change objects states in there.
Title: Re: Stop drawing pixels out of region
Post by: kubawal on November 21, 2014, 07:23:47 pm
It doesn't work or I do something wrong.
The whole problem is because I'm rendering a physics simulation that have its own coordinates.
And I want to render specified rect of physics simulation to specified rect on window (not on whole window)

// some useful inlines that are missing in SFML
inline Vector2f size(const FloatRect& rect)
{
    return Vector2f(rect.width, rect.height);
}

inline Vector2f pos(const FloatRect& rect)
{
    return Vector2f(rect.left, rect.top);
}

inline Vector2f localCenter(const FloatRect& rect)
{
    return size(rect) * 0.5f;
}

inline Vector2f globalCenter(const FloatRect& rect)
{
    return pos(rect) + localCenter(rect);
}

void WorldRender::draw(RenderTarget &target, RenderStates states) const
{
    //states.transform *= getTransform(); // i don't need Transformable transform because i use the same transform in view

// vp is source region of simulation

    // view set
    View oldV = target.getView();
    View newV;
newV.setRotation(getRotation());
    newV.setSize(size(vp));
    newV.setCenter(globalCenter(vp));
    newV.setViewport(FloatRect(getPosition(), Vector2f(size(vp).x * getScale().x, size(vp).y * getScale().y)));
    target.setView(newV);

// only for example    
CircleShape cs(50);
    cs.setPosition(0, 0);
    cs.setFillColor(Color::Black);
    target.draw(cs, states);

//...

target.setView(oldV); // restore old view
}
 
And in this case NOTHING renders. Even simple circle  (cs in my code).
But out of this function everything works properly.
Title: Re: Stop drawing pixels out of region
Post by: Laurent on November 21, 2014, 09:11:51 pm
The viewport is defined in normalized coordinates. Please read the documentation carefully.
Title: Re: Stop drawing pixels out of region
Post by: kubawal on November 22, 2014, 02:30:32 pm
Thanks, it works.
Here's my code. Maybe it will help someone.
View newV;
newV.setSize(size(vp));
newV.setCenter(globalCenter(vp));
newV.setRotation(getRotation());
Vector2f vpPos(getPosition().x / target.getSize().x, getPosition().y / target.getSize().y);
Vector2f vpSz((size(vp).x * getScale().x) / target.getSize().x, (size(vp).y * getScale().y) / target.getSize().y);
newV.setViewport(FloatRect(vpPos, vpSz));
target.setView(newV);
 
Title: Re: Stop drawing pixels out of region
Post by: Nexus on November 22, 2014, 02:48:30 pm
I don't know how expensive these function calls are, but as a general rule, I would store results in variables instead of calling the same function multiple times. It's also more readable. That concerns getPosition(), getScale() and getSize().

Alternatively, you can use thor::cwiseProduct() or thor::cwiseQuotient() to multiply/divide vectors component-wise, see here (http://www.bromeon.ch/libraries/thor/v2.0/doc/group___vectors.html).