addTexture from IImage gets distorted?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

addTexture from IImage gets distorted?

Post by BMF »

So I create an IImage* using "createScreenShot ()".

Convert it to ITexture* using: "addTexture(const c8 * name, IImage* image)"

Draw it on screen using draw2DImage, but it doesn't look that good. It's a bit "distorted", like if some pixels were moved down or something. My game's running on 640x480 resolution.

Why is this? How to fix it?

Thanks in advance!
Image
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I think createScreenShot takes the screen resolution...
Then 640 and 480 (in your case) are not powers of 2 !!! ;)
But a texture must be in power of 2 (2^0, 2^1, 2^2, 2^3, ...) or it will be streched !!!
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

Hm... any way I could possibly overcome this problem?
Image
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I'm not sure but maybe this function of IImage can help: IImage::copyToScaling(...) (look at the api for the parameters)
so create an empty texture with dimensions in next powers of 2 of the image resolution (in your case 1024 * 512) and use this function to copy the image into the texture...

I'm not really sure if this works, but I think so... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

At the api I find:

Code: Select all

virtual void  copyToScaling (IImage *target)=0 
  copies the image into the target, scaling the image to fit 
 
virtual void  copyToScaling (void *target, s32 width, s32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0)=0 
  copies the image into the target, scaling the image to fit 
How can I use that function to copy the image into the texture? Those funcitons don't ask for a ITexture*. Hm...
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Either create a new Image and use the first method, or create a texture, lock it and use the second method.
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

I'm not sure about how to do it. Could you elaborate a little, please?

Currently, my code is:

Code: Select all

//at startup
IImage* paused_image;
ITexture* paused_texture;
...
//when you press the pause button
paused = true;
paused_image = irrDriver->createScreenShot();
paused_texture = irrDriver->addTexture("paused_texture", paused_image);
...
//before endScene
irrDriver->draw2DImage(paused_texture, position2d<s32>(0,0));
Here you have a link to a screenshot. To the left, the normal image, to the right, after a screenshot. It looks like only the HUD gets distorted, but I wouldn't be sure. Take a look at the healthbar and the score text, that's where it's easier to see the effect.
Image
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

BMF wrote:Those funcitons don't ask for a ITexture*. Hm...
but the 2nd asks for a void* !!! ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Hmm, I couldn't see any problems...
Anyway, yu can create a new empty image with some dimension and color format. Then call paused_image.copyToScaling(newImage)
Or pass the pointer you get from lock() to the second method (don't give it the ITexture pointer!)
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

I've tried doing this like this:

Code: Select all

paused_image = irrDriver->createScreenShot();
paused_texture = irrDriver->addTexture(dimension2d<s32>(1024,512), "screenshot", ECF_A8R8G8B8);
const dimension2d<s32> sz = paused_image->getDimension();
paused_image->copyToScaling(paused_texture->lock(), sz.Width, sz.Height, ECF_A8R8G8B8, paused_image->getPitch());
And the result is totally messy, things drawn at several places, multiple times... etc. A mess. What am I doing wrongly?

@hybrid: Don't you see anything wrong on my uploaded screenshot? Take a look at the 'score' text on the one to the right. It's different from in the original game (to the left).

Thanks for the help so far!

I have tried writing the image to a file and it works perfectly. It's the "creating a texture from an image" that is causing me problems.
Particularly, I would say that it is "creating a texture from an image that is not power of two in size". I'm using Irrlicht 1.3.1 and D3D.

:)
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Hmm, I did not check the text, why would one create text in an image?
Anyway, you should not give the dimensions of your current image, but of the target image. The current dimensions are known from the image you call the method on. So set 1024 and 512 as parmeters. Also the pitch should be the one from the destination, but you can also leave it open, then the default pitch for the target will be used (which is ok in most cases).
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

hybrid wrote:Hmm, I did not check the text, why would one create text in an image?
Anyway, you should not give the dimensions of your current image, but of the target image. The current dimensions are known from the image you call the method on. So set 1024 and 512 as parmeters. Also the pitch should be the one from the destination, but you can also leave it open, then the default pitch for the target will be used (which is ok in most cases).
I'm creating a screenshot and then displaying it in game, and since there's text shown, I want it to look well in the screenshot, that's why.

I set 1024 and 512 as parameters, and leave pitch open. Now a 1024x512 texture is created.

If I display it on screen, I only see the 640x480 top-left part of it. Maybe if I know scale it down when rendering it'll work?
Nah, I have tried that and the image looks distorted again.

I need to create a 640x480 texture in the first place. That's my problem.
Image
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

You should be able to use draw2DImage that takes a source rect and a dest rect. The source rect would be (0, 0, 640, 480) and the dest rect would be the viewport rect, which would the same.

Travis
BMF
Posts: 62
Joined: Mon Jul 16, 2007 11:10 am
Location: Spain
Contact:

Post by BMF »

vitek wrote:You should be able to use draw2DImage that takes a source rect and a dest rect. The source rect would be (0, 0, 640, 480) and the dest rect would be the viewport rect, which would the same.

Travis
That's how to draw the texture on screen. But since the texture is created with a size of 1024x512 (the whole texture being "used"), when drawing it on screen at at 640x480 region, it's scalled down, and thus distorted.

This is how I'm creating the image and texture from it. The problem is at the second line.

Code: Select all

paused_image = irrDriver->createScreenShot();
paused_texture = irrDriver->addTexture("paused_texture", paused_image);
Image
Post Reply