Stretching a Texture (source code!)

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
Post Reply
Blizzard
Posts: 71
Joined: Thu Apr 20, 2006 5:27 pm
Location: Italy

Stretching a Texture (source code!)

Post by Blizzard »

Hi,

I've coded a function that stretch a texture in the size that you want.
I've coded that for help a friend to scale textures, so I've not made lots of tests, I've just verified that the code works correctly.

So, if you make tests notify me if it works.

FILE: BlizStretch.h
/*
Copyright (C) 2006-2007 Santostefano Giovanni contact: idmgiovanni@libero.it

This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more
details.

You should have received a copy of the
GNU General Public License along with this program;
if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/

#ifndef BLIZSTRETCH
#define BLIZSTRETCH

#include <irrlicht.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


using namespace irr;
using namespace scene;
using namespace video;
using namespace core;

#pragma comment(lib, "Irrlicht.lib")

/* FUNCTION TEXTURE STRETCHING
* This function stretch a texture and adapt it to new dimensions
* defined by the programmer
*/
ITexture* BlizStretchTexture(IrrlichtDevice *device, char* name, ITexture* source, core::dimension2d<s32> newdim);


#endif

FILE: BlizStretch.cpp

Code: Select all

/*
Copyright (C) 2006-2007 Santostefano Giovanni contact: idmgiovanni@libero.it

This program is free software; you can redistribute it 
and/or modify it under the terms of the GNU General Public 
License as published by the Free Software Foundation; 
either version 2 of the License, or (at your option) any 
later version.

This program is distributed in the hope that it will be 
useful, but WITHOUT ANY WARRANTY; without even the implied 
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE. See the GNU General Public License for more 
details.

You should have received a copy of the 
GNU General Public License along with this program; 
if not, write to the 
Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
Boston, MA 02111-1307 USA
*/

#include "BlizStretch.h"

/* FUNCTION TEXTURE STRETCHING
 * This function stretch a texture and adapt it to new dimensions
 * defined by the programmer
 */
ITexture* BlizStretchTexture(IrrlichtDevice *device, char* name, ITexture* source, core::dimension2d<s32> newdim)
{

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

	//dimension of the original texture
	core::dimension2d<s32> dim=source->getOriginalSize();

	//color format of the original texture
	video::ECOLOR_FORMAT cformat=source->getColorFormat();

	if(cformat!=video::ECF_A8R8G8B8)
		return NULL;

	//calculating scaling factors

	//X factor
	float Xfactor= dim.Width/newdim.Width;
	//int Xfactor = (int)floor(sf); //call to floor is to avoid bugs

	//Y factor
	float Yfactor= dim.Height/newdim.Height;
	//int Yfactor = (int)floor(sf); //call to floor is to avoid bugs

	//creating the new texture
	char *tname=(char*)malloc(sizeof(char)* strlen(name));
	strcpy(tname, name);

	printf("Texture %s Created!\n", tname);

	//populating the texture
	int i=0, j=0;
	SColor *sbuffer=(SColor*)source->lock();
	SColor *dbuffer= new SColor[newdim.Height*newdim.Width];//(SColor*)texture->lock();

	if(!sbuffer)
	{
		printf("ERROR WHILE LOCKING SOURCE TEXTURE\n");
		return NULL;
	}

	for(i=0; i<newdim.Height; i++)
		for(j=0 ; j<newdim.Width; j++)
		{
			//source index
			/*int sXindex=j * Xfactor;
			int sYindex=i * Yfactor;*/
			int sindex=(int)floor((dim.Width*i*Yfactor)+(j*Xfactor));
			int dindex=(i*newdim.Width)+j;
			dbuffer[dindex]=sbuffer[sindex];
			//printf("");
		}

	source->unlock();

	video::IImage* image=driver->createImageFromData(video::ECF_A8R8G8B8,newdim,dbuffer,false);
	video::ITexture* texture=driver->addTexture(tname,image);
	
	return texture;

}

EXAMPLE USAGE:

Code: Select all

driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true);
video::ITexture* images = driver->getTexture("../../media/2ddemo.bmp");
video::ITexture* tex=BlizStretchTexture(device,"BlizTexture",images,core::dimension2d<s32>(458,64));
That's an important thing!
You must use 32 bit textures and you must pass the name of the new texture according to the texture creation function of irrlicht.

Let me know what do you think!

Bye
Giovanni
Everyone for the game and the game for everyone
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

There are lots of methods for color conversion and image manipulation in Irrlicht. Image resizing as well, should work with most supported Irrlicht image formats. did you check the Irrlicht code for overwriting textures? You might introduce memory holes if this is not carefully handled.
And what do you need this for? Textures can be scaled by hardware using the proper UV coords.
Blizzard
Posts: 71
Joined: Thu Apr 20, 2006 5:27 pm
Location: Italy

Post by Blizzard »

Hi,
did you check the Irrlicht code for overwriting textures?
No I didn't. Sorry but I've written this code in half an hour... so it isn't programmed well.
And what do you need this for? Textures can be scaled by hardware using the proper UV coords.
This is for my friend. He need to stretching a texture for a 2D program.
User load an image and the size is adapted to certain conditions.
It's not used to texture triangles but only 2D image rendering

driver->draw2DImage(tex, core::position2d<s32>(20,20),core::rect<s32>(120,120,1500,1200));
Everyone for the game and the game for everyone
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

So better load the image directly, stretch the image using a designated method and make a texture from it. Otherwise you'll mess around with gfx card memory, maybe also create mipmaps etc. And since draw2DImage also stretches the image you might get better results that way. If it becomes too blurred you can change the filtering (though only by changing the library).
Blizzard
Posts: 71
Joined: Thu Apr 20, 2006 5:27 pm
Location: Italy

Post by Blizzard »

Hi hybrid,

Thanks for the advices :P

As soon as I can (I've not lot's of free time these days) I reprogram the function fallowing your system...

Thanks a lot :wink:

Bye
Giovanni
Everyone for the game and the game for everyone
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The above code has several memory leaks.

You shouldn't need to malloc a new memory buffer just so you can print a string. The second allocation could be avoided if you created the destination image, locked it and wrote directly into the images pixel buffer. Also, it might be wise to do all of your work with IImages instead of textures.

It might be easier if you had a look at the CImage code and just copied it.
Post Reply