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

Author Topic: Rounded Rectangles  (Read 20118 times)

0 Members and 1 Guest are viewing this topic.

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Rounded Rectangles
« on: January 28, 2009, 08:29:47 pm »
I was wondering, does SFML have a way to do RoundedRectangles (with or without OpenGL)?  If not, would it be more efficient to use primitive shapes to kind of make a rounded rectangle or to use an image?

Just wondering, thanks!

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
Rounded Rectangles
« Reply #1 on: January 28, 2009, 10:57:27 pm »
Use an image.  (You could have a small "round corner" image that you pair with straight line images as necessary.)
You could also do some stuff with alpha masks and texture combiners / shaders, but if you don't know about that stuff, piecing together the rectangles HTML-style for rounded corners should work.
Making a shape primitive with enough segments to appear round is probably not very efficient.

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Rounded Rectangles
« Reply #2 on: January 29, 2009, 03:47:48 pm »
Just wondering, is there a way to edit the Circle to make this? (or is the circle rendered differently than other shapes?)  Basically I am wondering how the circle itself is drawn and also if its possible to maybe take the circle, split it, and add lines (for the rectangle part) .  Does that even make sense?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Rounded Rectangles
« Reply #3 on: January 29, 2009, 04:32:33 pm »
The circle is a regular shape, the Shape::Circle function just computes the points to build it. But you won't be able to modify it, as the list of points has to remain in order, and define a convex shape. Unless you copy them somewhere, insert your own points at the right locations in the list, and rebuild a shape from that.

You'd better create a sf::Shape RoundedRect(...) function which computes all the points directly.
Laurent Gomila - SFML developer

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Rounded Rectangles
« Reply #4 on: February 14, 2009, 10:38:04 pm »
Ok, so I (finally) made my own RoundedRectangle function.  Here are a few pics of what I have so far:



this is just the RoundedRectangle



This is a Rounded Rectangle along with a Rectangle (given the same Rectangle points).  
The radius of the arcs is 15.  I use 40 points total (same as sf::Shape::Circle).  For more or less accuracy you can edit the number of points (right now is a #define statement), but for some reason you can only have an even number (I do a for loop for each corner, so with an N of 10 there's 40 points total).

Can you believe it, I actually had to use Geometry on this... :roll:

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Rounded Rectangles
« Reply #5 on: February 14, 2009, 11:09:51 pm »
Looks good! Would be cool to see that in trunk. :)

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Rounded Rectangles
« Reply #6 on: February 15, 2009, 05:38:01 am »
Here is the code (as a function):
Code: [Select]

#define POINTS 10
sf::Shape& RoundedRectangle(float x, float y, float rectWidth, float rectHeight, float radius, const sf::Color& Col, float Outline, const sf::Color& OutlineCol)
{
sf::Shape* rrect=new sf::Shape();
rrect->SetOutlineWidth(Outline);
float X=0,Y=0;
for(int i=0; i<POINTS; i++)
{
X+=radius/POINTS;
Y=sqrt(radius*radius-X*X);
rrect->AddPoint(X+x+rectWidth-radius,y-Y+radius,Col,OutlineCol);
}
Y=0;
for(int i=0; i<POINTS; i++)
{
Y+=radius/POINTS;
X=sqrt(radius*radius-Y*Y);
rrect->AddPoint(x+rectWidth+X-radius,y+rectHeight-radius+Y,Col,OutlineCol);
}
X=0;
for(int i=0; i<POINTS; i++)
{
X+=radius/POINTS;
Y=sqrt(radius*radius-X*X);
rrect->AddPoint(x+radius-X,y+rectHeight-radius+Y,Col,OutlineCol);
}
Y=0;
for(int i=0; i<POINTS; i++)
{
Y+=radius/POINTS;
X=sqrt(radius*radius-Y*Y);
rrect->AddPoint(x-X+radius,y+radius-Y,Col,OutlineCol);
}
return *rrect;

}

I don't know if it was the most efficient way to go about doing this, but this is how my mind worked when I was coding it.  If there is a way to make this code in any way better, I'd like to know; I'm fairly new to C++ (coming from Java).  Anyone is free to use this code, modify it, etc.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Rounded Rectangles
« Reply #7 on: February 15, 2009, 11:00:47 am »
You produce a nice memory leak. If you use new to allocate memory, you have to free it again by using delete.

But why don't you just create a sf::Shape on the stack?

Code: [Select]
// No reference but a copy is returned
sf::Shape RoundedRectangle(float x, float y, float rectWidth, float rectHeight, float radius, const sf::Color& Col, float Outline, const sf::Color& OutlineCol)
{
    sf::Shape rrect;    // creating a Shape - automatic storage class
    rrect.SetOutlineWidth(Outline);
    ...
    return rrect;
}

And please don't use #define for constants in C++. Either you declare a const int or add a further default-parameter which would make the whole thing more flexible.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
Rounded Rectangles
« Reply #8 on: February 15, 2009, 07:48:10 pm »
Awesome, this is why I ask for help in my code ^_^.  I'll change that right away.  
I guess the reason why I did that is I don't like making copies of objects (always thought that it wasted more memory), but I guess it is deleted after I exit the function (and a memory leak is waaaay worse).

EDIT: ok, changed the function to:
Code: [Select]

sf::Shape RoundedRectangle(float x, float y, float rectWidth, float rectHeight, float radius, const sf::Color& Col, float Outline = 0.f, const sf::Color& OutlineCol = sf::Color(0, 0, 0), int POINTS=10);

the rest of the function is the same, just does not use a pointer.  
Thanks for the help!