Sign in to follow this  

Quick question about textures

This topic is 3727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am currently working on a pet project partially as a learning exercise and partially because I think it would be a pretty nifty thing to have :D In short, it involves wrapping a C# app around a console to display the output in a creative way (ie. as Direct3D objects, offering some interesting possibilities for visualising things such as multiple consoles open simultaneously etc). The issue I'm currently having is this: I am displaying each line output from the console as a rendered texture on a simple mesh primitive (four vertices making a rectangle). As you can see from the pictures below, when zoomed in close these textures have a nice anti-aliased appearance. HOWEVER when zoomed out to the level I wish to be zoomed at, this anti aliased look is all but gone and the text becomes barely discernible. Is there something I can do to easily fix this or do I need to look into things such as mip mapping and texture filtering? Zoomed out Zoomed in Also to actually generate these textures (using Graphics.DrawString currently) can be considerably slow. Is there a more efficient way?

Share this post


Link to post
Share on other sites
What minification, magnification and mip filters are you using? In general LINEAR filtering breaks down beyond a scale of 2 so you may need to be careful what size you render your text with.

Also, the text rendering should be handed over to Win32 (although not 100% sure with MDX) so you're limited in the AA effect you can achieve - any flag suggesting this to DrawString() will use Windows-provided methods rather than Direct3D-provided ones...

As for text rendering performance - yes, it is slow. Always has been, always will be [smile] You can mitigate it using clever algorithms though. I had great success with temporal caching based on the simple observation that if the text doesn't change every frame why am I re-rendering it every frame?

hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
What minification, magnification and mip filters are you using? In general LINEAR filtering breaks down beyond a scale of 2 so you may need to be careful what size you render your text with.

As far as I'm aware I'm not using any. That's part of the problem, I'm not sure how to go about doing it. Like if it's as simple as

device.RenderState.TextureFiltering = TextureFiltering.Bilinear; // Ya I just made this up >_>



then feel free to fill me in. Otherwise I'll go away and do some research on how to properly do mip mapping etc.

Quote:
Original post by jollyjeffers
Also, the text rendering should be handed over to Win32 (although not 100% sure with MDX) so you're limited in the AA effect you can achieve - any flag suggesting this to DrawString() will use Windows-provided methods rather than Direct3D-provided ones...

As for text rendering performance - yes, it is slow. Always has been, always will be [smile] You can mitigate it using clever algorithms though. I had great success with temporal caching based on the simple observation that if the text doesn't change every frame why am I re-rendering it every frame?



Not entirely sure what you mean by handing rendering over to Win32. I currently use a setup/teardown system where the textures I use are generated only on instantiation of a new line and on a device reset. It still takes a good 250-500ms to generate a single line though. The code used to generate the texture is as follows:

// Set up the line texture
Bitmap b = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(b);

// Calculate the text metrics
SizeF stringSize = g.MeasureString(_line, new System.Drawing.Font(_fontFace, _fontSize));

_lineWidth = Size.Truncate(stringSize).Width;
_lineHeight = Size.Truncate(stringSize).Height;

b = new Bitmap(_lineWidth, _lineHeight);

g = Graphics.FromImage(b);

// Antialiasing
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

// Fill a black background then draw the text over top
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, b.Width, b.Height));
g.DrawString(_line, new System.Drawing.Font(_fontFace, _fontSize), new SolidBrush(Color.White), new PointF(0, 0));

_lineTexture = Texture.FromBitmap(device, b, Usage.Dynamic, Pool.Default);

Share this post


Link to post
Share on other sites
Uploaded a vid so you can see what I mean about how slow it is to generate lines. I just did "cd \" then "dir" to get it to spew a few lines. Interestingly it doesn't block rendering or anything while it is creating the textures. You can also see where my animation is at currently when I hit page up/down a few times near the end.

http://www.youtube.com/watch?v=UYH7ifOV0fA

Share this post


Link to post
Share on other sites
When optimizing you need to find out exactly where the bottleneck is. I'd recommend timing each of the calls in that texture generation code first of all to get an idea where the slowness is coming from.

I'd also investigate the performance effect of those antialiasing settings. Maybe you don't really need bicubic.

My guess is that it's probably related to this problem. Have you tried running without the debugger attached?

Also why are you using default pool dynamic textures, when I presume they won't actually ever change, or at least only change rarely? I'd recommend managed pool and non dynamic.

Share this post


Link to post
Share on other sites
Ahh yes it appears you are correct. Runs fine without the debugger attached, and the line

_lineTexture = Texture.FromBitmap(device, b, Usage.Dynamic, Pool.Default);


takes in the region of 500ms with the debugger attached. Very frustrating. Not too keen on writing unsafe code and using Texture.FromStream instead seemed to have no effect at all. At least I know what is causing it though, I'm sure I can work around it :)

Share this post


Link to post
Share on other sites
Probably not best practice, but this seems to solve the problem for the lacking minification:

if (device.DeviceCaps.TextureFilterCaps.SupportsMinifyAnisotropic)
device.SamplerState[0].MinFilter = TextureFilter.Anisotropic;

Share this post


Link to post
Share on other sites

This topic is 3727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this