Page 1 of 1

Image widget RTT and down-sampling

Posted: Fri Aug 15, 2008 02:18
by EvilClown
hi

first of all, thanks Crazy Eddie for CEGUI, it's great!

Now for my problem, for which i hope a solution exists.

I'm using an image widget to display a Render-to-Texture from Ogre3d. So far so good. I can resize the image ok. But the image is pixelated - like, no anti-aliasing. So i tried sizing up the render-texture to be 2x, 4x, etc, the image size, in the hope that it would downsample and look a bit smoother. However this is not the case. Even when the texture is much larger that the image, the image remains blocky.

So, what's going on here? Is there a way to set the down-sampling technique of the image widget?

Or could this be caused by something else entirely?

Posted: Sat Aug 16, 2008 00:19
by daves
I have not had any kind of problem with the kind of operation you describe, and I do quite a bit of this kind of image sizing with cegui/ogre.

Can you post the source image, an image of the pixellated image on your window? It might also help to have a glance at the section of your code that creates/sizes/textures this window.

Posted: Wed Aug 20, 2008 08:44
by EvilClown
Just to illustrate the problem a bit clearer, here are some screenshots.

Here's a regular image. In this screenshot, the image size is the same as the texture size. There are some jagged edges around the model's outline.

Image

In this screenshot, the texture size is 4 times the image size. So the texture is scaled down to 1/4 to fit the image. In theory, this should simulate anti-aliasing. To me it looks just as jaggy as the above image.

Image

In the image below, i manually rescaled a screenshot to about 1/2 size using an image manipulation program. To me it looks smoother, and this is the effect i'm aiming for.

Image

Any thoughts?

Posted: Mon Aug 25, 2008 13:59
by daves
Unfortunately none. Though the effect that you highlight is clear. Let us know if you find a satisfactory resolution.

Re: Image widget RTT and down-sampling

Posted: Thu Dec 22, 2011 02:16
by zuur
I've just run into this same problem, and also found the same question in another post here (from 2007). Wondering if there's any way to fix this problem in CEGUI 7.x?

The problem is that if you take a large image and render it using a StaticImage widget that's smaller, the image is rendered with "nearest neighbour" sampling and looks really bad (in my case it's not just that the image has "jaggy edges", but that the writing on the image is unreadable).

This might be because there are no mip-maps created for the texture in CEGUI? (just guessing there), or just because of the sampling mode CEGUI uses?

Thanks in advance for any thoughts..

Re: Image widget RTT and down-sampling

Posted: Fri Jan 20, 2012 19:14
by czuger
Hi, I am trying to do the same thing, this is how far I've gotten:

I am trying to render an Ogre scene into a texture target and draw this in a CEGUI component. This works fine.
What I am now trying to do is make the render-texture larger than the CEGUI component it is being drawn into, to get AA.

What I do is as follows:

Code: Select all


if(!mWrappedStaticImage->isUsingAutoRenderingSurface())
    mWrappedStaticImage->setUsingAutoRenderingSurface(true);
CEGUI::RenderingSurface *const surface = mWrappedStaticImage->getRenderingSurface();
if(surface == NULL)
{
    LOG_MSG(String("Attempting to render ") + sceneManagerName + String(" to StaticImage, but it does not have a RenderSurface"), IO::Log::LEVEL_ERRORS, "Gui");
    return;
}

CEGUI::OgreTextureTarget& ceguiTextureTarget = dynamic_cast<CEGUI::OgreTextureTarget&>(surface->getRenderTarget());
CEGUI::Size orgTexSize = ceguiTextureTarget.getTexture().getSize();
// Double the size of the render-target to get AA
ceguiTextureTarget.declareRenderSize(CEGUI::Size(orgTexSize.d_width * SFloat(2), orgTexSize.d_height * SFloat(2)));

Ogre::RenderTexture *const ogreRenderTexture = dynamic_cast<CEGUI::OgreTexture&>(ceguiTextureTarget.getTexture()).getOgreTexture()->getBuffer()->getRenderTarget();

if(!sceneMan->hasCamera(cameraName))
{
    LOG_MSG(String("Attempting to use Camera ") + cameraName + String("for OgreScene in StaticImage, but it does not exist!"), IO::Log::LEVEL_ERRORS, "Gui");
    return;
}
Ogre::Camera *const camera = sceneMan->getCamera(cameraName);

//Add a Viewport to the render texture with our camera.
Ogre::Viewport *const vp = ogreRenderTexture->addViewport(camera);
vp->setOverlaysEnabled(false);
vp->setBackgroundColour(Ogre::ColourValue(SFloat(0), SFloat(0), SFloat(0), SFloat(0)));
vp->setClearEveryFrame(true);



The problem: The static-image draws the image as though it is 'left and top aligned' instead of 'stretched'.
Calling the 'declareRenderSize' function sets both the 'd_size' and the 'd_dataSize' to be the same value, so when it computes the texel-scaling in CEGUI::OgreTexture, it computes a scaling value assuming that the CEGUI::Window that is drawing this texture IS the same size as the texture. Manually changing d_texelScaling via debugger in CEGUI::OgreTexture achieves the effect I am looking for (i.e. I have to double the d_texelScaling, since I doubled the texture size, giving me the AA effect I am looking for). I think what I need is some way to set 'd_dataSize', or have CEGUI set 'd_dataSize' in CEGUI::OgreTexture to the correct value (in my case, 1/2 of d_size). Is there a way to do this?

What I have done, is modified CEGUI::OgreTexture, I have added 'adjustCachedTexelScaling(float factor) { d_texelScaling = d_texelScaling * factor; }' function. This is a hack, and I am looking for the 'correct' way of doing this.
However, my final, functional code:

Code: Select all


if(!mWrappedStaticImage->isUsingAutoRenderingSurface())
    mWrappedStaticImage->setUsingAutoRenderingSurface(true);
CEGUI::RenderingSurface *const surface = mWrappedStaticImage->getRenderingSurface();
if(surface == NULL)
{
    LOG_MSG(String("Attempting to render ") + sceneManagerName + String(" to StaticImage, but it does not have a RenderSurface"), IO::Log::LEVEL_ERRORS, "Gui");
    return;
}

CEGUI::OgreTextureTarget& ceguiTextureTarget = dynamic_cast<CEGUI::OgreTextureTarget&>(surface->getRenderTarget());
CEGUI::Size orgTexSize = ceguiTextureTarget.getTexture().getSize();
// Double the size of the render-target to get AA
ceguiTextureTarget.declareRenderSize(CEGUI::Size(orgTexSize.d_width * SFloat(2), orgTexSize.d_height * SFloat(2)));

CEGUI::OgreTexture& tex = dynamic_cast<CEGUI::OgreTexture&>(ceguiTextureTarget.getTexture());
tex.adjustCachedTexelScaling(SFloat(2));
Ogre::RenderTexture *const ogreRenderTexture = tex.getOgreTexture()->getBuffer()->getRenderTarget();

if(!sceneMan->hasCamera(cameraName))
{
    LOG_MSG(String("Attempting to use Camera ") + cameraName + String("for OgreScene in StaticImage, but it does not exist!"), IO::Log::LEVEL_ERRORS, "Gui");
    return;
}
Ogre::Camera *const camera = sceneMan->getCamera(cameraName);

//Add a Viewport to the render texture with our camera.
Ogre::Viewport *const vp = ogreRenderTexture->addViewport(camera);
vp->setOverlaysEnabled(false);
vp->setBackgroundColour(Ogre::ColourValue(SFloat(0), SFloat(0), SFloat(0), SFloat(0)));
vp->setClearEveryFrame(true);



Christian

Re: Image widget RTT and down-sampling

Posted: Mon Jan 23, 2012 08:04
by CrazyEddie
You should have made your own thread for this - because my response is likely not to apply to anybody else who posted here, and I'm not re-reading three year old threads to find out. So, that's a black mark against your name; your transgression has been noted; you are on the list, dude... ;)

If you basically want to render a 3d scene to the texture, and use that later as an Image in CEGUI, then messing around with AutoRenderingSurface and such is - in my opinion - entirely the wrong approach. One right way is to create the RTT texture (using Ogre), and then use this texture as the basis for a CEGUI Imageset (with autoscaling disabled), and define a single image that covers the entire area of the texture. You then use this to render to a window via either a StaticImage or perhaps a more lightweight component you could define via looknfeel and scheme XML.

Another approach would be to side-step the Imageset/Image parts, and create a custom window subclass that you can set an CEGUI::Texture to, and the drawing function for the window subclass would render geometry (into the window's already existing CEGUI::GeometryBuffer) that basically covers the entire window surface with a quad which uses the texture you set previously. This allows the Texture to be sized according to what you desire, and should get filtered correctly when drawn. Btw, in order to get the CEGUI::Texture to use here, you again set it up in Ogre first, then pass the RTT to the CEGUI::OgreRenderer when creating a Texture.

There are other options too, though I think these two are pretty basic and should get most people the effect they want.

CE.