Scissor issues in DirectX, please assist.

Started by
9 comments, last by AvengerDr 16 years, 8 months ago
I'm working on a GUI atm and Have the basic components covered. The big hurdle, I believe, is the textbox or editbox whatever people prefer. I had the issue partially solved, in terms of: Drwing the box, text, "walking" through text with caret, pushing text in either direction once caret hit left or right side, inserting, deleting etc. That covers the behaviour of the textbox. But since I'm moving and resizing the rectangle that is passed to my Direct3D.Font.DrawText call the text is visible outside the actual textbox. I found a solution to this on this very site, a clever individual mentioned the use of Sisscor. I tried it and it worked. BUT ... When switching from windowed to full screen (on startup or at runtime) the sciccoring is ignored and I'm back with text floating outside bounds. So to formulate a question: Why is this so? Another question: How can I Scissor in fullscreen? I had no idea why this behaviour occurs and I find no detailed documentation on the issue. I'm hoping it's a bug or driver/OS issues. My rush was kinda spoiled by that. I'm running Vista Ultimate on a solid machine with Geforce 7900GTX and using the april 2007 DX SDK. Regards ... me :)
Advertisement
Can I ask you what is this scissoring method that you are talking of? I'm also developing a MDX UI (link in the signature). I compute the text length on screen and only display the relevant part.

MMM now that I think of, that's what I'do :D right now I use the size of the textbow as the boundary, not allowing user input other thank backspace. But If I understood this correctly, try using the Font.MeasureString (I thnk that's the name).
--Avengers UTD Chronicles - My game development blog
I've never used scissor but in my GUI code i use SetViewport. This will obviously only clip rectangular regions, but that shouldn't stop you.

I only ever once had a driver problem with SetViewport on an old ATI Rage Pro 3d, where the SetViewport messed with the currently set texture. Apart from that it worked flawlessly.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Thank you for replyning.

AventgerDr:

I tried cutting text and only displaying what falls inside the actual textbox.
First I think it gave a bit messy code, and strange behaviour when using fonts with variable width (ie. Verdana). Courier New is obviously the answer to that.

The rectangle is pass to my Font.DrawText comes from the Font.MeasureString
But first i translate the rectangle so that the text is placed correctly.
The scissor rectangle i use is equivalent dimensioned as my text box but inflated to simulate margin.

I find this solution quite elegant if I may say so my self ... If only it worked in full screen :(

to use Scissoring you need to call Device.RenderState.ScissorTestEnable = true (once is enough)

Then in your render method you can call ie:

Rectangle temp = device.ScissorRectangle (store the original scissor)
device.ScissorRectangle = myCustomRectangle

font.DrawText(mySprite,text,myTextFormat,rectFromMeasureString,Color.Black.ToArgb())

device.ScissorRectangle = temp (restore original scissor)

The idea is that anything outside myCustomRectangle is discarded by the rasterizer.


Endurion:

Thanks I'm gonna try that one.
Update:

Scissoring does work in full screen, there is something else going on.
According to my experimentation it is not trivial when you apply it. Ie calling it after a Sprite.Begin() it is ignored while calliing it before is another matter.

In any case, even if it works, I cannot recoment this method unless used on small texts since it give severe performance impacts.

with a aprox 2k character string i dropped from 300 fps to 100 fps in my curret setup.

I was told Scissoring was good for performance, but this is aparently beyond that.

[Edited by - Annoyed on July 24, 2007 8:50:39 AM]
Thanks for the tip about scissoring, I really didn't know about that feature. So you say that it's not good performance wise? So how are you going to fix that problem?
--Avengers UTD Chronicles - My game development blog
I wasn't being all clear on the performance issue. Scissoring isn't the problem.

It's simply a matter of how much text you draw, scissor or no scissor. Too much text in one sprite draw batch kills fps.
The GUI sample from the DX SDK also does this if you add too much text.

But in small measures ie. a single line textbox with max 256 chars input you hardly notice the diffrence.

I noticed the big drop in fps while creating a multilined rich textbox that i used for logging, incoming chat, whatever adding text programatically.

If you wonder how to go multiline, simply resize the rectangle returned by MeasureString.
Since MeasureString returns a singleline representation (DrawTextFormat being ignored for what i know), you set the rectangle height = Math.Ceil(rectWidth / desiredWidth) * rectHeight and then the rectangle width= desiredWidth.
Position it and draw.

I'm not quite sure what I'm going to do to solve it, considering breaking texts into smaller batches when drawing, but somehow I don't feel convinced. Thats why I went Amazon and bought a book >.<

I'll have to get back to you once i figure it out :)

Book: link
Mhm, are you rendering the text every frame?? Because if you do, no wonder you get low fps.

@ AvengerDr :
Nice GUI, wow! =)
Current project - http://d20project.blogspot.com/
Efficient text rendering goes way beyond GPU-specific optimizations such as scissor rects.

Even though D3DX tends to be optimized it really has absolutely nothing on a custom text renderer. When I wrote up the D3D front-end to F1CM a few years ago I had to tackle this issue as the F1CM UI was very text-heavy (as in, entire screens of text).

Writing your own renderer can be tricky if you want to cover all the special cases, but it can be effort well-spent. In the end I had an entire screen of text being rendered at the same speed as without text - 1800fps [wink]. If I used trivial D3DX rendering I was down into single-figure frame rates for the same scenario.


Look into caching text in render-targets or static VB's. Even with the user able to type/edit text it rarely changes as fast as the screen is being drawn - a lot of times you'll be reconstructing VB's or IB's with identical data which is just silly!!


hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Thanks Jack, nice input.

I'm a little short on knowledge when it comes to efficient text rendering as you have noticed =P

But yea I had the feeling a lot of redundancy was going on.

Now to dig up some know how.

/cheers

This topic is closed to new replies.

Advertisement