Cell-tabled texture

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Cell-tabled texture

Post by IPv6 »

Hi all!
This is snippet for working with big-size/non pow2 textures. It is knows that it is not recommended to use non-square textures or textures with size!=16,128,256,512,etc (you got the point). This class takes ANY image as source and creates array (table) of textures. each cell in that table is square sized (if you want) and represent corresponding part of the original image.

it works for me, but any comments (especially for lines with // Do i have to do this ????) are welcome

Code: Select all

// ICellTableTexture.h: cell-tabled texture
// By IPv6 (wiredplane.com). Free for use
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CTTexture_H__28206755_382F_417B_B99A_8F6AAB1EC2AE__INCLUDED_)
#define AFX_CTTexture_H__28206755_382F_417B_B99A_8F6AAB1EC2AE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class CCTTexture
{
public:

	CCTTexture(video::IVideoDriver* pVideo, video::IImage* imgSource, u32 horiCellRes=512, u32 vertCellRes=512, u32 tableWidth=2, u32 tableHeight=2)
	{
		imgSource->grab();
		m_cellXSize=horiCellRes;
		m_cellYSize=vertCellRes;
		m_tableXSize=tableWidth;
		m_tableYSize=tableHeight;
		BYTE* SrcData=(BYTE*)imgSource->lock();
		m_imgSourceDimensions=imgSource->getDimension();
		u32 SrcPixels=m_imgSourceDimensions.Width*m_imgSourceDimensions.Height;
		dimension2d<s32> cellSize(horiCellRes,vertCellRes);
		ECOLOR_FORMAT iSrcFormat=imgSource->getColorFormat();
		if(iSrcFormat==ECF_R8G8B8){
			int iFTypeSize=3;//pixel size for ECF_R8G8B8
			// Creating textures
			for(int y=0;y<tableHeight;y++){
				for(int x=0;x<tableWidth;x++){
					BYTE* TrgData=new BYTE[horiCellRes*vertCellRes*iFTypeSize];
					for(u32 yPx=0;yPx<vertCellRes;yPx++){
						u32 iYPosInSource=(y*vertCellRes)+yPx;
						if(iYPosInSource>=m_imgSourceDimensions.Height){
							break;
						}
						u32 posInSrc=yPx*m_imgSourceDimensions.Width+x*horiCellRes+(y*vertCellRes*m_imgSourceDimensions.Width);
						u32 posInTrg=yPx*horiCellRes;
						u32 len=horiCellRes;
						if(posInTrg>=SrcPixels){
							break;
						}
						if(posInTrg+len>=SrcPixels){
							len=SrcPixels-posInTrg;
						}
						memcpy(TrgData+iFTypeSize*posInTrg,SrcData+iFTypeSize*posInSrc,len*iFTypeSize);
					}
					IImage* imageCell=pVideo->createImageFromData(ECF_R8G8B8,cellSize,TrgData,true);
					char szName[32]={0};
					static u32 iDullCounter=0;
					sprintf(szName,"CT_T%i",iDullCounter++);
					ITexture* pCell=pVideo->addTexture(szName, imageCell);
					//imageCell->drop(); // Do i have to do this ????
					m_aTextures.push_back(pCell);
				}
			}
		}
		imgSource->unlock();
		imgSource->drop();
	}

	virtual ~CCTTexture()
	{
		//m_aTextures[pos]->drop() // Do i have to do this ????
	}

	ITexture* GetCell(int iX, int iY)
	{
		u32 pos=iY*m_tableXSize+iX;
		if(pos>=m_aTextures.size()){
			return NULL;
		}
		return m_aTextures[pos];
	};
	core::dimension2d<s32> getDimension(){return m_imgSourceDimensions;};
	u32 GetCellXSize(){return m_cellXSize;};
	u32 GetCellYSize(){return m_cellYSize;};
	u32 GetTableXSize(){return m_tableXSize;};
	u32 GetTableYSize(){return m_tableYSize;};
	array<ITexture*>& GetTexturesArray(){return m_aTextures;}
private:
	core::dimension2d<s32> m_imgSourceDimensions;
	irr::core::array<ITexture*> m_aTextures;
	u32 m_cellXSize;
	u32 m_cellYSize;
	u32 m_tableXSize;
	u32 m_tableYSize;
};


#endif // !defined(AFX_CTTexture_H__28206755_382F_417B_B99A_8F6AAB1EC2AE__INCLUDED_)
Last edited by IPv6 on Tue Aug 22, 2006 2:48 pm, edited 1 time in total.
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Another case

Post by IPv6 »

other case when this class can be useful: if you want to convert bitmap with animation frames (placed in one line or several lines) into array of textures for example for textureAnimator. you can also convert font bitmap into list of textures for each font character. and so on :)

usage example:

Code: Select all

CCTTexture* imgBackground=new CCTTexture(driver,bgFile,128,128,8,6);

for(int i=0;i<imgBackground->GetTableXSize();i++){
			for(int j=0;j<imgBackground->GetTableYSize();j++){
				double dXSize=1.0f/imgBackground->GetTableXSize();
				double dYSize=1.0f/imgBackground->GetTableYSize();
				vector3df pos=core::vector3df(double(i)*dXSize-0.5f,double(j)*dYSize-0.5f,-0.3f);
				IBillboardSceneNode *bill=smgr->addBillboardSceneNode(0,core::dimension2d<f32>(dXSize, dYSize),pos);
				bill->setMaterialType(video::EMT_SOLID);
				bill->setMaterialTexture(0, imgBackground->GetCell(imgBackground->GetTableXSize()-i-1,imgBackground->GetTableYSize()-j-1));
			}

Last edited by IPv6 on Tue Aug 22, 2006 2:55 pm, edited 1 time in total.
IPv6
Posts: 188
Joined: Tue Aug 08, 2006 11:58 am

Example

Post by IPv6 »

Example application that demonstrates usage of this class (updated!, BTW) and introduces funny trigonometric animator. it uses 1024/768 image as input and makes part of that image fly over scene on random trigonometric paths

http://www.upload2.net/page/download/r7 ... e.zip.html
Post Reply