Want to draw only a certain part of an image to a billboard

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
trnrez
Posts: 28
Joined: Wed Dec 27, 2006 5:56 pm
Location: Murfreesboro, TN
Contact:

Want to draw only a certain part of an image to a billboard

Post by trnrez »

I am trying to write an app where I show plain 2d images on the left and right. These will be loaded in by the user so the size is unknown to me.

I started using the draw2DImage() function but couldn't find a way to scale the image down if the user was to give me an image that did not fit within the renderer. I searched the forums and didn't find anything that gave a clear answer on how to use this. Saw something about using Magic Library but it isn't set up for the latest version of Irrlicht which I am using.

Seeing as I couldn't scale that way I did the next logical thing and attempted to use Billboards. Now my issue is that the user will be loading in a 2d image and I want to allow them to state what part of that image to render. So lets say that you load in a power of two file and only want to show topL(0,0) bottomR(200,200). How do I go about stating that I want the billboard to only show that part of the image?

Also, if someone knows of a way to go about scaling draw2DImage() I would love to know. Thanks for looking this over and if you need clarification please let me know.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

The draw2DImage function has a source and a destination rect !!!
with the source rect you can specify the rectangle that should be taken from the image/texture and with the destination rect you can scale it...

Now, for a billboard it's not that simple...
There are no functions to get a specified rect from the texture !!!
But you always can create a new image/texture "on the fly" and write a function to copy the wanted rect from the original image into the new created image !!! ;)
For creating an image/texture have a look for addImage(...) and addTexture(...) !!!
And for manipulating an image/texture use the lock() and unlock() functions of them !!!
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 »

You can use the texture matrix for such purposes. Simply set it to a scaling texture as you wish. Simply get the texture transformation and set it to the desired scaling matrix.
petrucci
Posts: 1
Joined: Fri Dec 29, 2006 5:58 pm

how to scale images if using draw2DImage()

Post by petrucci »

try scaling the texture before you actually pass it to draw2DImage(), such as the following:

video::ITexture* texture = driver->getTexture( texturePath );
texture->getTransformation().setScale( core::vector3df( 1/x, 1/y, 1/z) );
then of course
driver->draw2DImage(texture, ...);

where x, y, z are floats. If you want to scale the x-dimension up by 2, the x-coordinate of the scale vector is 1/2, not 2.
trnrez
Posts: 28
Joined: Wed Dec 27, 2006 5:56 pm
Location: Murfreesboro, TN
Contact:

Post by trnrez »

I tried getting the transformation then using setScale but no matter what I change the values to I get no difference in rendering. It still renders the 2d image the exact same width and height. I get the feeling im doing something simple and just over looking it.

Code: Select all

	
	IrrlichtDevice *device = createDevice(
		EDT_SOFTWARE,
		dimension2d<s32>(ResX, ResY),
		16,
		false,
		false,
		false,
		0
		);

	// Store a pointer to the video driver
	IVideoDriver	*driver	= device->getVideoDriver();

	ITexture		*images = driver->getTexture("media/2ddemo.bmp");
	driver->makeColorKeyTexture(images, position2d<s32>(0,0));

	// Now we render everything until we are told to stop by an exit
	while(device->run())
	{
		// All rendering is done between begin and end
		// The begin scene clears the screen with a color and also
		// the depth buffer if so needed
		driver->beginScene(true, true, SColor(0, 0, 200, 200));
			
			// Scale
			images->getTransformation().setScale(vector3df(0.5f, 1.0f, 1.0f));

			driver->draw2DImage(images, position2d<s32>(50,50),
				rect<s32>(0,0,342,224), 0,
				SColor(255,255,255,255), true);

			driver->draw2DImage(images, position2d<s32>(164,125),
				rect<s32>(349,15,385,78),0,
				SColor(255,255,255,255),true);
		
		driver->endScene();
	}

	// Now we delete the Irrlicht Device we created.
	device->drop();
edit:
I attempted to use draw2DImage(...) setting a DestRect and SourceRect. When I do this nothing gets rendered to the screen. I reread the documentation and noticed that the function doesn't take in a position. My question would then be how do I tell it the position on the screen that I want to render to. Perhaps I misunderstand how this form of draw2DImage works all together.

Code: Select all

 
driver->draw2DImage(
				images,
				rect<s32>(0,0,500,600),
				rect<s32>(0,0,342,224), 
				0,
				&SColor(255,255,255,255),
				true
				);
Ohh and thanks for all the replies! I appreciate the help immensely.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

don't use the draw2DImage with position2d (it's another function that uses an array of rects) !!!
use it with 2 rects the destRect is the rectangle where the image should be drawn at:

Code: Select all

virtual void irr::video::IVideoDriver::draw2DImage  (  video::ITexture *  texture,  
  const core::rect< s32 > &  destRect,  
  const core::rect< s32 > &  sourceRect,  
  const core::rect< s32 > *  clipRect = 0,  
  video::SColor *  colors = 0,  
  bool  useAlphaChannelOfTexture = false 
 )  [pure virtual] 
It should work, maybe your rects are not correct ???
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
trnrez
Posts: 28
Joined: Wed Dec 27, 2006 5:56 pm
Location: Murfreesboro, TN
Contact:

Post by trnrez »

Acki wrote:It should work, maybe your rects are not correct ???
I simply made the code state that I want the dest rect to be the same size as the source rect. If I don't use dest and source it draws everything.

with dest and source: Image using position: Image

Code: Select all

	ITexture		*images = driver->getTexture("media/2ddemo.bmp");
	driver->makeColorKeyTexture(images, position2d<s32>(0,0));

	while(device->run())
	{
		driver->beginScene(true, true, SColor(0, 0, 200, 200));

			driver->draw2DImage(
				images,
				rect<s32>(0,0,342,224), //position2d<s32>(50,50),
				rect<s32>(0,0,342,224),
				0,
				&SColor(255,255,255,255),
				false
				); 

		driver->endScene();
	}
Edit:
I was using EDT_SOFTWARE so I thought just to make sure that wasn't the issue I changed it to EDT_OPENGL and it rendered the part but extremly weird. So I changed it to EDT_DIRECT3D9 got pretty much the same result so here it is.

Image

Edit2:
Seems that if useAlphaChannelOfTexture is set to false it renders that rainbow effect under it. so I set it to true and it rendered it right but it has a ghosting effect over it.

Image

Code: Select all

driver->draw2DImage(
				images,
				rect<s32>(0,0,342,224),
				rect<s32>(0,0,342,224),
				0,
				&SColor(255,255,255,255),
				true
				); 
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

ahhh, try it like this:

Code: Select all

        driver->draw2DImage(
            images,
            rect<s32>(0,0,342,224),
            rect<s32>(0,0,342,224),
            0,
            0,
            true
            );
because the color in this function is an array of 4 colors to specify the colors of the 4 corners (look at the api for more info)... ;)
So you can't just pass a pointer to a single color to it...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
trnrez
Posts: 28
Joined: Wed Dec 27, 2006 5:56 pm
Location: Murfreesboro, TN
Contact:

Post by trnrez »

Acki wrote:ahhh, try it like this:

Code: Select all

        driver->draw2DImage(
            images,
            rect<s32>(0,0,342,224), //position2d<s32>(50,50),
            rect<s32>(0,0,342,224),
            0,
            0,
            true
            );
because the color in this function is an array of 4 colors to specify the colors of the 4 corners (look at the api for more info)... ;)
Awesomeness! It works...Thanks for the help.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

No problem !!! ;)

But the effect you got was verry interesting... :lol:
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply