Texture Scaling

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
LordNyson
Posts: 31
Joined: Tue Nov 11, 2008 12:02 pm
Location: Perth, Australia

Texture Scaling

Post by LordNyson »

Hello there,

I'm creating a game and I have been loading my dialogs through xml files. I am looking to expand this game quite a bit to include over 15 individual dialogs, mostly in new windows.

When my event receiver notices a button press it adds to a que which is of a "dialog index", then in my loop if not currently loaded this new dialog will be loaded. Unfortunately my resolution is adjustable. So what I really need is the ability to scale textures applied to these elements. Now I cycle through the actualy elements in their base form and change the rect to be inline with the selected resolution/aspect ratio, I also have code that will take an image and scale it. What I now need is the ability to retrieve the texture from an element then apply the remade texture to that element.

Unfortunately, I don't see a way to do this seeing as I'm working with them in IGUIElement or whatever base form, and in this there is no function to get or set the texture of the element. I'm hoping to get the code functioning so I can cycle through say 50 possible elements and scale their rects and textures (of all different element types). Sounds like a task and a bit more perhaps and could create significant lag, but if the texture is already loaded then it will bypass that step and only scale the elements. Wondering if someone could help me achieve this.

Scale Texture

Code: Select all

ITexture* Element::scaleTexture(stringc textureName, const dimension2di& destSize)
{
   stringc textureNameEdit = textureName;
   stringc work = "";

   for(int position = textureNameEdit.findLast('/');position != textureNameEdit.findLast('.');)
   {
	   if(position != '/')work += textureNameEdit[position];
	   textureNameEdit.erase(position);
   }
   for(int position = textureNameEdit.findLast('.');textureNameEdit[position] != NULL;)
   {
	   textureNameEdit.erase(position);
   }

   stringc filename = textureNameEdit;
   filename += "/Generated";
   filename += work;
   filename += destSize.Width;
   filename += 'x';
   filename += destSize.Height;
   filename += ".png";

   TCHAR pwzPath[MAX_PATH];
   GetCurrentDirectory(MAX_PATH, pwzPath);
   stringw t = pwzPath;
   stringc anotherTemp = "/"; 
   anotherTemp.append(textureNameEdit);
   t += anotherTemp;
   t += "/Generated";
   stringc aThirdTemp = "";

   for(int position = 0;t[position] != NULL;position++)
   {
	   if(t[position] == '/')t[position] = 92;
	   aThirdTemp.append((c8)t[position]);
	   if(t[position] == 92)aThirdTemp.append(92);
   };

   CreateDirectory((LPCSTR)aThirdTemp.c_str(),NULL);

   ITexture* tex = driver->getTexture(filename);
   if(tex)return tex;
	
   ITexture* SrcTexture = driver->getTexture(textureName);
   if(!SrcTexture){MessageBox(NULL,"Error in image loading. This can be caused by an incorrect parameter or filename, it could also be caused by missing or corrupt images.","Fatal Error",MB_OK | MB_ICONSTOP);exit(-4);};

   irr::video::IImage* SrcImage = 0; 
   IImage* AlphaImage = 0;
   irr::video::IImage* DestImage = 0; 
   irr::video::ITexture* IntTexture = 0; 

   driver->setTextureCreationFlag(irr::video::ETCF_CREATE_MIP_MAPS, false); 

   try{
		IntTexture = driver->addTexture(destSize, "IntermediateTexture"); 
		SrcImage = driver->createImageFromData(ECF_A8R8G8B8, SrcTexture->getSize(), SrcTexture->lock()); 
		DestImage = driver->createImageFromData(ECF_A8R8G8B8, destSize, IntTexture->lock()); 
	  }
   catch(...)
      {
		  MessageBox(NULL,"Error in image scaling. This can be caused by incorrect resolution settings. \n\n To reset your graphics settings delete file: Resources/Config Files/Graphics.dat \n\n If the problem persists after this, contact the development team with a bug report.","Serious Error",MB_OK | MB_ICONSTOP);
	  };
   
   IntTexture->unlock(); 
   SrcImage->copyToScaling(DestImage); 
   SrcTexture->unlock(); 

   driver->removeTexture(IntTexture); 
   IntTexture = driver->addTexture(filename.c_str(), DestImage); 
   SrcImage->drop(); 
   DestImage->drop(); 

   
   driver->setTextureCreationFlag(irr::video::ETCF_CREATE_MIP_MAPS, true); 
   bool errorCheck = driver->writeImageToFile(driver->createImageFromData(ECF_A8R8G8B8, IntTexture->getSize(), IntTexture->lock()),filename.c_str());
   if(errorCheck){}
   else{MessageBox(NULL,"Error in image writing. This can be caused by an incorrect parameter, filename, missing or corrupt images, incorrect write privledges on your hard drive or scaling issues which may be caused by resolution difficulties.","Serious Error",MB_OK | MB_ICONSTOP);};
   IntTexture->unlock();

   return IntTexture; 
} 
This code of course will be able to be edited so it takes an ITexture if I can get it in that form.

Scale Element

Code: Select all

int Element::scaleElement(IGUIElement* t)
{
	try
	{
	rect<s32> pos = t->getRelativePosition();
	
	position2d<s32> tempLR = pos.LowerRightCorner;
	position2d<s32> tempUL = pos.UpperLeftCorner;

	tempLR.X *= (s32)hrat;
	tempLR.Y *= (s32)vrat;
	tempUL.X *= (s32)hrat;
	tempUL.Y *= (s32)vrat;

	pos = rect<s32>(tempUL, tempLR);

	t->setRelativePosition(pos);
	}
	catch(...)
	{
		return -1;
	};
	return 0;
};
Scaling multiple elements simply loops through the scale element untill it is null. Each dialog is allocated a max of 50 elements.

Thanks,
Lord Nyson.
But the cage only had "Warning: Vicious Lions" on it! Im a programmer! I only listen to errors!
LordNyson
Posts: 31
Joined: Tue Nov 11, 2008 12:02 pm
Location: Perth, Australia

Post by LordNyson »

Basically what I did is in the scale elemnt loop accessed the type of element it is and then based on the element id loaded the scaled image... unfortunately this leaves me with multiplications of the same element, So I have yet to get around this problem but for anyone else with the same problem:

Code: Select all

EGUI_ELEMENT_TYPE type = t->getType();
	stringc path = "Resources/2d/";
	path += t->getID();
	path += ".png";

	switch(type)
	{
		case EGUIET_BUTTON:
			{
				IGUIButton* temp = (IGUIButton*)t;
				temp->setImage(scaleTexture(path,dimension2di((tempLR.X - tempUL.X),(tempLR.Y - tempUL.Y))));
				break;
			};
		case EGUIET_IMAGE:
			{
				IGUIImage* temp = (IGUIImage*)t;
				temp->setImage(scaleTexture(path,dimension2di((tempLR.X - tempUL.X),(tempLR.Y - tempUL.Y))));
				break;
			};
		case EGUIET_STATIC_TEXT:{break;};
		case EGUIET_WINDOW:{break;};
		default:{break;};
	};//end switch
But the cage only had "Warning: Vicious Lions" on it! Im a programmer! I only listen to errors!
Post Reply