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_)