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

Author Topic: Stop drawing pixels out of region  (Read 2929 times)

0 Members and 1 Guest are viewing this topic.

kubawal

  • Newbie
  • *
  • Posts: 9
    • View Profile
Stop drawing pixels out of region
« 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?

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Stop drawing pixels out of region
« Reply #1 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.

kubawal

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Stop drawing pixels out of region
« Reply #2 on: November 20, 2014, 07:29:34 pm »
Shaders isn't my best side :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Stop drawing pixels out of region
« Reply #3 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.
Laurent Gomila - SFML developer

kubawal

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Stop drawing pixels out of region
« Reply #4 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?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Stop drawing pixels out of region
« Reply #5 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, so you can't change objects states in there.
« Last Edit: November 21, 2014, 06:55:14 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kubawal

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Stop drawing pixels out of region
« Reply #6 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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Stop drawing pixels out of region
« Reply #7 on: November 21, 2014, 09:11:51 pm »
The viewport is defined in normalized coordinates. Please read the documentation carefully.
Laurent Gomila - SFML developer

kubawal

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Stop drawing pixels out of region
« Reply #8 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);
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Stop drawing pixels out of region
« Reply #9 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.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: