SFML community forums
Help => Graphics => Topic started by: Astrof 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!
-
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.
-
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?
-
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.
-
Ok, so I (finally) made my own RoundedRectangle function. Here are a few pics of what I have so far:
(http://ashwindec11.googlepages.com/RoundedRectangle.jpg)
this is just the RoundedRectangle
(http://ashwindec11.googlepages.com/RoundedRectangleWithRectangle.jpg)
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:
-
Looks good! Would be cool to see that in trunk. :)
-
Here is the code (as a function):
#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.
-
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?
// 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.
-
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:
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!