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

Author Topic: Do I really have to use std::vector<sf::CircleShape> ?  (Read 3037 times)

0 Members and 1 Guest are viewing this topic.

Sakman

  • Newbie
  • *
  • Posts: 5
    • View Profile
    • Email
Do I really have to use std::vector<sf::CircleShape> ?
« on: July 17, 2018, 03:53:53 pm »


Hello! Lets say I have collection of circles that I want to draw. They are identical in color, outline etc. Like shown in the picture above.

Let's say I store the positions and radiuses in vectors. I don't want to store every sf::CircleShape individually since that takes too much memory and makes the program slow.

Is there a way to make a single sf::CircleShape and use (tranform?) something to move and scale the circle with the vectors mentioned above? And is there a way to draw them with a single RenderTarget::draw() like with sf::VertexArray?

Responses are greatly appreciated.

tomvidm

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Do I really have to use std::vector<sf::CircleShape> ?
« Reply #1 on: July 17, 2018, 04:00:06 pm »
You can make a vector std::vector<sf::Transformable>. Instead of iterating through a vector of circle shapes, iterate through the transforms. For each transform T, you call draw on the circle shape, pass a sf::RenderStates with T.getTransform() as the transform parameter. (Look at the declaration of sf::RenderStates structure)

This way, the vertices defining the circle itself does not change. The CircleShape itself is logically in the same place all the time, but the vertices are transformed and sent for rendering in turns.
« Last Edit: July 17, 2018, 04:02:02 pm by tomvidm »

Hapax

  • Hero Member
  • *****
  • Posts: 3058
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Do I really have to use std::vector<sf::CircleShape> ?
« Reply #2 on: July 17, 2018, 04:03:53 pm »
See my response to your duplicate post.
(click to show/hide)
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Sakman

  • Newbie
  • *
  • Posts: 5
    • View Profile
    • Email
Re: Do I really have to use std::vector<sf::CircleShape> ?
« Reply #3 on: July 17, 2018, 04:44:20 pm »
Thank you for your response!

I'm a bit confused. So what I need to do is make an empty texture and draw the circles on it?

Could you link a tutorial or an example, please. Thank you.

verdog

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Do I really have to use std::vector<sf::CircleShape> ?
« Reply #4 on: July 17, 2018, 07:18:41 pm »
I'd probably wrap the group of circles into a class/struct:

struct CirclePosition {
  sf::Vector2f position;
  float radius;
}

struct CircleGroup {
  mutable sf::CircleShape base; // mutable so its radius can be changed within the draw function
  std::vector<CirclePosition> positions; // filled with a CirclePosition for each sf::CircleShape

  void draw(sf::RenderTarget& target, sf::RenderStates states) const {
    for (CirclePosition &cPosition : positions) {
      // apply the radius
      base.setRadius(cPosition.radius);

      // move the circle
      sf::Transform circleTransform;
      transform.translate(cPosition.position);
      states.transform = circleTransform;
      target.draw(base, states);
    }
  }
}
 

Pretty sloppy solution, and it might give you issues when you try to compile it (wrote it quickly at work  :P), but maybe this can give you an idea to get started?

Hapax

  • Hero Member
  • *****
  • Posts: 3058
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Do I really have to use std::vector<sf::CircleShape> ?
« Reply #5 on: July 18, 2018, 01:55:27 am »
I'm a bit confused. So what I need to do is make an empty texture and draw the circles on it?

Could you link a tutorial or an example, please. Thank you.
Again, if your circles do not move, yes, you can draw them to a kind of texture and then draw that texture in one draw call. However, if your circles are moving/changing, you'll still need at least as many draw calls (to draw them to the texture).

Basically, set up an sf::RenderTexture to match the window size and draw the circles to that in the same way you draw to a window (and prepare the sprite that draws the render texture):
std::vector<sf::CircleShape> circles;
sf::RenderTexture renderTexture;
// set up render texture and circles
renderTexture.clear();
for (auto& circle : circles)
    renderTexture.draw(circle);
renderTexture.display();
sf::Sprite renderSprite(renderTexture.getTexture());
This can be done before the main loop since they are not changing.
Also, you no longer need the vector of circle shapes...

Then, in the main loop where you are drawing to a window, just draw the render sprite:
while (window.isOpen())
{
    // event loop
    // updates
    window.clear();
    window.draw(renderSprite);
    window.display();
}
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

 

anything