SFML community forums

Help => Graphics => Topic started by: ErikPerik on September 23, 2010, 06:51:25 pm

Title: Hide overflown contents from a set boundary
Post by: ErikPerik on September 23, 2010, 06:51:25 pm
I'm currently writing a tiny GUI library, and in my text-input fields I want the text that is longer than the input field boundaries to not be displayed. The example illustrates it:

(http://i.imgur.com/c42Ap.png)

I have looked around a lot in the forum and the solution as I see it: Use sf::View in some way. (And this is SFML 1.6) I don't really know how it works, but it appears to be RenderWindow-only. Maybe I can swap the view when drawing the input field?

AFAIK sf::String, nor sf::Drawable has a BoundingRect-property or something the like. What do you think?
Title: Hide overflown contents from a set boundary
Post by: NoIdea on September 23, 2010, 07:10:41 pm
If I understand right, you want to be able to delimit a part of the screen in which the drawables must be drawn ?

There are to simple ways of achieving this :
-using glScissor. This method is perfect if you are working in screen coordinates. If not, use the second one :
-using glClipPlane. There is an example on the french forum doing exactly what you want. I'll try to get the link.

Here is the link (http://www.sfml-dev.org/forum-fr/viewtopic.php?t=3065).
Title: Hide overflown contents from a set boundary
Post by: Nexus on September 23, 2010, 07:13:45 pm
The easiest way would be to remove the part of the string which isn't displayed from the sf::String object, and pass that cut object to sf::Text. You can get the character's length using sf::Glyph.
Title: Hide overflown contents from a set boundary
Post by: NoIdea on September 23, 2010, 08:00:16 pm
The only problem with your solution in this case is that it can't "cut" letters.
Furthermore, if he ever needs to be able to draw shapes or PostFx, he might want to be able to delimit them too. This works with the system I proposed.
Title: Hide overflown contents from a set boundary
Post by: ErikPerik on September 23, 2010, 08:21:27 pm
Yes, that is exactly what I want. Is this the "recommended" way of dealing with it? As I don't know french I can't really decipher everything in the linked thread by NoIdea, but see the gist of it.

Code: [Select]

glEnable(GL_SCISSOR_TEST);
...
// Draw code
...
glDisable(GL_SCISSOR_TEST);


Is this what's recommended?
Title: Hide overflown contents from a set boundary
Post by: NoIdea on September 23, 2010, 08:45:26 pm
Yes, but as I said, glScissor requires screen coordinates which you usually dont have. Thats why there is a solution with glClipPlane on the same thread.
If necessary, you might want to use google translation... as I am not going to translate my entire thread into english.
Title: Hide overflown contents from a set boundary
Post by: Lupinius on September 23, 2010, 09:10:02 pm
You could render the text to a RenderImage and use subrect to only draw one part of the text.
Title: Hide overflown contents from a set boundary
Post by: ErikPerik on September 23, 2010, 09:16:25 pm
Quote from: "Lupinius"
You could render the text to a RenderImage and use subrect to only draw one part of the text.


But RenderImage is 2.0 and I'm using 1.6 (because I like stability).
Title: Hide overflown contents from a set boundary
Post by: Lynix on September 24, 2010, 05:21:53 pm
SFML 2 is stable
Title: Hide overflown contents from a set boundary
Post by: ErikPerik on September 24, 2010, 05:25:08 pm
From what I've read in recent thread it has problems with ATI-cards?
Title: Hide overflown contents from a set boundary
Post by: NoIdea on September 24, 2010, 05:54:12 pm
Whatever you do with RenderImage, glClipPlane will be faster. Just copy/paste the code...
Title: Hide overflown contents from a set boundary
Post by: ErikPerik on September 24, 2010, 06:00:40 pm
I am currently using this:

Code: [Select]

void drawBoundary(sf::RenderWindow &window, sf::Drawable *d, const sf::FloatRect &boundary)
{
GLdouble eq1[] = {1, 0, 0, 0x0};
GLdouble eq2[] = {-1, 0, 0, 0x0};
GLdouble eq3[] = {0, 1, 0, 0x0};
GLdouble eq4[] = {0, -1, 0, 0x0};

eq1[3] = -boundary.Left;
eq2[3] = boundary.Right;
eq3[3] = -boundary.Top;
eq4[3] = boundary.Bottom;

glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glClipPlane(GL_CLIP_PLANE0, eq1);
glClipPlane(GL_CLIP_PLANE1, eq2);
glClipPlane(GL_CLIP_PLANE2, eq3);
glClipPlane(GL_CLIP_PLANE3, eq4);

window.Draw(*d);

glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE2);
glDisable(GL_CLIP_PLANE3);
}


Edit: Fixed the function