[solved] DX9 texture filtering problems (OpenGL is fine)

Problems building or running the engine, queries about how to use features etc.
ryandeboer
Halfling
Posts: 84
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

[solved] DX9 texture filtering problems (OpenGL is fine)

Post by ryandeboer »

I am using a manually created ogre texture that is 800x600 containing text and fine 1 pixel wide lines. This texture is displayed on a Rectangle2D background. In OpenGL mode it is crisp and perfect, but in DX9 mode it is blurry and the 1 pixel lines become at least 2. I have tried:

Code: Select all

    texUnit1->setTextureFiltering(FO_NONE,FO_NONE,FO_NONE);
But that makes it look crap in DX9 mode with lots of pixels missing. But OpenGL mode still looks crisp and fine.

Does OpenGL support non power of 2 dimensions and DX9 can't?

The only other thing I can think of is if I stored it as a portion of a 1024x1024 texture, and made some custom object that worked like a Rectangle2D with texture coordinates that only used the 800x600 region. But it might have the same problem still.

Is there some way of blitting a 800x600 texture perfectly on the screen in DX9 mode without losing pixels or any texture filtering being done? It's annoying that OpenGL seems to work fine no matter what I do.
Last edited by ryandeboer on Sat Dec 09, 2006 5:49 pm, edited 1 time in total.
ryandeboer
Halfling
Posts: 84
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

Post by ryandeboer »

I found a way to improve the DX9 look by changing the Rectangle2D.

Changing this:

Code: Select all

rect->setCorners(-1, 1, 1, -1);
To this:

Code: Select all

rect->setCorners(-1, 1, 1.01, -1.01);
It makes the pixels come back. It's kind of hacky though, stretching the rectangle around until the texture filtering works as you wanted. I would prefer the corner at 1 without fudge factors.

Those are relative screen coordinates, but changing the window width makes no difference. The RenderWindow dimension is 800x600 and the texture is 800x600. From a screenshot the client area is 800x600 and the window with borders etc is 808x627.

If anyone knows a better way of having control over blitting to a client area than using Rectangle2D with fudge factors please post. For now I might need different fudge factors for OpenGL, DirectX and different screen resolutions.
ryandeboer
Halfling
Posts: 84
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

Post by ryandeboer »

It looks like overlay panels are even better, not losing pixels when their dimensions are the client area. Unfortunately you can't set them to render in RENDER_QUEUE_BACKGROUND, so I still need to use rects with 1.01.

Code: Select all

panel->setMetricsMode(Ogre::GMM_PIXELS);
panel->setPosition(0, 0);
panel->setDimensions(800, 600);
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66

Post by sinbad »

The pixel issue is simple - D3D and GL have different texel origins. D3D says it's the top-left, GL says it's the middle. Use RenderSystem::getHorizontalTexelOffset and RenderSystem::getVerticalTexelOffset to compensate (compositors use this).
User avatar
radioman
Greenskin
Posts: 132
Joined: Sun Dec 31, 2006 3:59 pm
Location: lithuania

Post by radioman »

How to exactly use RenderSystem::getHorizontalTexelOffset and RenderSystem::getVerticalTexelOffset ? I use rect or overlay.
ryandeboer
Halfling
Posts: 84
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

Post by ryandeboer »

I'm not sure either. Those offsets gave values of "1" I think. And since I set corners of a rectangle to values like -1,1,1,-1, I need some offset of 0.01 or so. Assuming your width of the window is 800 then 1 pixel offset might be 1/800 = 0.00125. So maybe then the rect can be something like

Code: Select all

rect->setCorners(-1, 1, 1.00125, -1); 
(you would also need to do the same for vertical)
I haven't got that far yet, I'm still just using the first value that looked ok for 800x600.
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

For overlays you don't have to do anything, the texel offsets are applied by Ogre internally, so the easy solution would be to use an overlay panel. For rectanlges (Rectangle2D), you'll have to calculate the correct offsets according to the viewport size. IIRC the texel offset in D3D is 0.5 in each direction, but of course get these values from the render system.
User avatar
radioman
Greenskin
Posts: 132
Joined: Sun Dec 31, 2006 3:59 pm
Location: lithuania

Post by radioman »

i use overly, it stilll BLURED, or OFSET ;[[[ Rects too, wtf ;/

Image
peace & serenity
ryandeboer
Halfling
Posts: 84
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

Post by ryandeboer »

You did do this for your material didn't you?

Code: Select all

texUnit1->setTextureFiltering(FO_NONE,FO_NONE,FO_NONE); 
The offset problem is when you are not doing filtering, but if it doesn't map 1texel to 1pixel then you may "lose" pixels (eg a 1 pixel thick line may disappear totally). But overlays don't have this issue.

Since you have bluring you must have texture filtering set.
User avatar
radioman
Greenskin
Posts: 132
Joined: Sun Dec 31, 2006 3:59 pm
Location: lithuania

Post by radioman »

thanks, i add "filtering none" and my background now looks good :D

Code: Select all

texture_unit
{
   filtering none
   texture gui/bg.jpg
}

[img]
http://radioman.9999mb.com/data/pics/ogre/ok.png
[/img]
peace & serenity