Creating a custom image

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
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Creating a custom image

Post by pippy »

I have a large map (of a Tile class), and I want to make a 'map preview'.

So far I have

Code: Select all

void Map::createMapPreview(){
	char chmapPreview[20];
	mapPreview = driver->addTexture(core::dimension2d<s32> (256,256),
		chmapPreview, video::ECF_A1R5G5B5);

}
Which is a no-brainer, but how would I set the individual pixels?

I noticed Iimage has a setPixel() function, so would I convert the texture a Iimage, set the map preview, and convert it back, or is there another way?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Not sure I understand what you want. Do you want a preview of what the image looks like, but smaller? If so, you can just load the image and display it into a smaller area using draw2DImage(). You might even be able to use the IGUIImage type to render the image also. You would create the texture with a simple call to driver->getTexture().

Travis
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Heres my solution

Post by pippy »

Surfing a while I found a way to do it. I'm still hammering out some of the bugs, but it works

Code: Select all

/**	createMapPreview - builds chmapPreview 
 * texture from the Scolor inTile class
 *
 *	@return void nothing
 */
void Map::createMapPreview(){
	// name of the map
	char chmapPreview[11] = "mapPreview";
	std::cout << "creating " << chmapPreview << std::endl;
	
	// dimensions of the minimap to be created 
	core::dimension2d<s32> minMapDim(128,128);

	// populate the texture
	video::SColor *dbuffer = new video::SColor[minMapDim.Height * minMapDim.Width];
	if(!dbuffer){
		std::cerr << "Error creating "<< chmapPreview << std::endl;
		return;
	}

	// fill the texture
	for(int i=0; i<minMapDim.Width; i++) {
		for(int j=0; j<minMapDim.Height; j++) {
			int index = (i * minMapDim.Width) + j;
			double mapposX = i/(minMapDim.Width/width);
			double mapposY = j/(minMapDim.Height/height);
			dbuffer[index] = getTile((int)(mapposX),(int)(mapposY))->getColor();
		}
	}

	// create an image
	video::IImage* image = driver->createImageFromData(
		video::ECF_A8R8G8B8, minMapDim, dbuffer, false);

	// create texture from image
	mapPreview = driver->addTexture(chmapPreview,image);
}
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

With your code you created empty texture. To change its pixels you would use lock() function which return pointer in to pixel data. You need to call unlock() at the end to apply changes:

example:

Code: Select all

// create empty texture
	ITexture *txt = driver->addTexture(dimension2d<s32>(32,32), "texture", ECF_A8R8G8B8);
	
	// get pointer
	u32 *p = (u32*)txt->lock();
	
	// set all pixels to red
	SColor color(255,255,0,0);
	
	for(u32 j=0; j<txt->getSize().Height; j++)
	  for(u32 i=0; i<txt->getSize().Width; i++)
	  {// you need some simple math to calculate position in simple array from 
     //2D coordinates
     p[j * txt->getSize().Width + i] = color.color;
     }
	
	// set pixel 10,5 to green
	u32 xpos = 10;
	u32 ypos = 5;
	
	color = SColor(255,0,255,0);
	p[ypos * txt->getSize().Width + xpos] = color.color;
	
	// apply changes
	txt->unlock();
For 16bit textures you would use:

Code: Select all

...
u16 *p = (u16*) txt->lock();
...
p[ypos * txt->getSize().Width + xpos] = color.toA1R5G5B5();
Another possibility is to create IImage from array using IVideoDriver::createImageFromData() function. Than create ITexture from IImage with one of IVideoDriver::addTexture() functions.
Post Reply