lugre_image_L.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_luabind.h"
00003 #include "lugre_ogrewrapper.h"
00004 #include "lugre_image.h"
00005 #include "lugre_bitmask.h"
00006 #include "lugre_luabind_direct.h"
00007 #include "lugre_luabind_ogrehelper.h"
00008 #include <Ogre.h>
00009 
00010 extern "C" {
00011     #include "lua.h"
00012     #include "lauxlib.h"
00013     #include "lualib.h"
00014 }
00015 
00016 
00017 #include <map>
00018 
00019 using namespace Ogre;
00020 
00021 namespace Lugre {
00022 
00023 cImage::cImage  () {}
00024 cImage::~cImage () {}
00025 
00026 // global static vars to store prepared image stuff
00027 Ogre::PixelFormat iPreparedFormat = Ogre::PF_BYTE_RGBA; // Ogre::PF_BYTE_BGRA;
00028 Ogre::uchar* pPreparedBuf = 0;
00029 unsigned int    iPreparedWidth          = 0; // image size
00030 unsigned int    iPreparedHeight         = 0; // image size
00031 unsigned int    iPreparedBufferSize         = 0; // buffer size in byte
00032 unsigned int    iPreparedRowSize            = 0; // buffer pixel row in bytes
00033 
00034 
00035 int     LugreImage_CreateFromOgreImage  (lua_State *L,Ogre::Image* pImg) { PROFILE return cLuaBind<cImage>::CreateUData(L,new cImage(pImg)); }
00036     
00037 // TODO : move to ogrewrapper?
00038 bool    MySubImage  (Ogre::Image& pImageSrc,Ogre::Image& pImageDst,int iOffsetX,int iOffsetY,int iNewWidth,int iNewHeight) {
00039     if (iNewWidth  <= 0) { printf("SubImage error, iNewWidth(%d) <= 0\n",iNewWidth); return false; }
00040     if (iNewHeight <= 0) { printf("SubImage error, iNewHeight(%d) <= 0\n",iNewHeight); return false; }
00041     if (iOffsetX < 0) { printf("SubImage error, iOffsetX(%d) < 0\n",iOffsetX); return false; }
00042     if (iOffsetY < 0) { printf("SubImage error, iOffsetY(%d) < 0\n",iOffsetY); return false; }
00043     if (iOffsetX+iNewWidth  > pImageSrc.getWidth())  { printf("SubImage error, right(%d) > w\n",iOffsetX+iNewWidth); return false; }
00044     if (iOffsetY+iNewHeight > pImageSrc.getHeight()) { printf("SubImage error, bottom(%d) > h\n",iOffsetY+iNewHeight); return false; }
00045     
00046     // source
00047     Ogre::PixelFormat   iPixelFormat    = pImageSrc.getFormat();
00048     
00049     Ogre::uchar*        dataD           = (Ogre::uchar*)OGRE_MALLOC(Ogre::PixelUtil::getMemorySize(iNewWidth,iNewHeight,1,iPixelFormat), MEMCATEGORY_GENERAL);
00050     Ogre::uchar*        dataS           = pImageSrc.getData(); // m_pBuffer
00051     size_t              pixelsizeS      = pImageSrc.getBPP() / 8; // m_ucPixelSize * 8;
00052     size_t              wS              = pImageSrc.getWidth(); // m_uWidth
00053     
00054     // copy pixels : fast, same format (pixelsizeS==pixelsizeD)
00055     int             rowlenD = pixelsizeS * iNewWidth; // = cpylen
00056     int             rowlenS = pixelsizeS * wS;
00057     Ogre::uchar*    reader  = &dataS[pixelsizeS*(wS * (iOffsetY) + iOffsetX)];
00058     Ogre::uchar*    writer  = dataD;
00059     for (int y=0;y<iNewHeight;++y,reader+=rowlenS,writer+=rowlenD) memcpy(writer,reader,rowlenD);
00060     
00061     pImageDst.loadDynamicImage(dataD,iNewWidth,iNewHeight,1,iPixelFormat,true);
00062     return true;
00063 }
00064 
00065 void    PrintOgreExceptionAndTipps(Ogre::Exception& e);
00066 
00067 class cImage_L : public cLuaBind<cImage> { public:
00069         virtual void RegisterMethods    (lua_State *L) { PROFILE
00070             #define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cImage_L::methodname));
00071             REGISTER_METHOD(Destroy);
00072             REGISTER_METHOD(SaveAsFile);
00073             REGISTER_METHOD(GetWidth);
00074             REGISTER_METHOD(GetHeight);
00075             REGISTER_METHOD(MakeTexture);
00076             REGISTER_METHOD(LoadToTexture);
00077             REGISTER_METHOD(GenerateBitMask);
00078             
00079             LUABIND_QUICKWRAP(  GetQuickHandle,     { return cLuaBindDirectOgreHelper::PushImage(L,&checkudata_alive(L)->mImage); });
00080             LUABIND_QUICKWRAP(  ColorReplace,       { cOgreWrapper::ImageColorReplace(      checkudata_alive(L)->mImage,cLuaBindDirectOgreHelper::ParamColourValue(L,2),cLuaBindDirectOgreHelper::ParamColourValue(L,3)); });
00081             LUABIND_QUICKWRAP(  ColorKeyToAlpha,    { cOgreWrapper::ImageColorKeyToAlpha(   checkudata_alive(L)->mImage,cLuaBindDirectOgreHelper::ParamColourValue(L,2)); });
00082             
00084             LUABIND_QUICKWRAP(  BlitPart,   { cOgreWrapper::ImageBlitPart(checkudata_alive(L,1)->mImage,checkudata_alive(L,2)->mImage,
00085                                                     ParamInt(L,3),ParamInt(L,4),ParamInt(L,5),ParamInt(L,6),ParamInt(L,7),ParamInt(L,8)); });
00086             
00087             lua_register(L,"LoadImageFromFile",     &cImage_L::LoadImageFromFile);
00088             lua_register(L,"LoadImageFromTexture",  &cImage_L::LoadImageFromTexture);
00089             lua_register(L,"SubImage",              &cImage_L::SubImage);
00090             lua_register(L,"ImageScale",            &cImage_L::ImageScale);
00091             lua_register(L,"ImageBlit",             &cImage_L::ImageBlit);
00092             lua_register(L,"CreateImage",           &cImage_L::CreateImage);
00093 
00094             lua_register(L,"PrepareImage",          &cImage_L::PrepareImage);
00095             lua_register(L,"CreatePreparedImage",   &cImage_L::CreatePreparedImage);
00096             lua_register(L,"SetPixelInPreparedImage",   &cImage_L::SetPixelInPreparedImage);
00097         }
00098 
00099     // object methods exported to lua
00100         
00102         static int      Destroy             (lua_State *L) { PROFILE delete checkudata_alive(L); return 0; }
00103         
00105         static int      SaveAsFile          (lua_State *L) { PROFILE
00106             Ogre::Image& mImage = checkudata_alive(L)->mImage;
00107             if (mImage.getWidth() <= 0 || mImage.getHeight() <= 0) return 0; // would trigger ogre exception, and mess up working dir and/or waste vram?
00108             std::string sFileName = luaL_checkstring(L,2);
00109             try {
00110                 mImage.save(sFileName);
00111             } catch( Ogre::Exception& e ) {
00112                 printf("warning, Image:SaveAsFile failed with exception\n"); // messes up working dir and/or waste vram? mainmenu broken after -exportanim, 26.05.2010
00113                 PrintOgreExceptionAndTipps(e);
00114                 return 0; 
00115             }
00116             lua_pushboolean(L,true);
00117             return 1; 
00118         }
00119         
00121         static int      GetWidth            (lua_State *L) { PROFILE
00122             lua_pushnumber(L,checkudata_alive(L)->mImage.getWidth());
00123             return 1; 
00124         }
00125         
00127         static int      GetHeight           (lua_State *L) { PROFILE
00128             lua_pushnumber(L,checkudata_alive(L)->mImage.getHeight());
00129             return 1; 
00130         }
00131             
00135         static int      MakeTexture         (lua_State *L) { PROFILE
00136             std::string sTexName    = (lua_gettop(L) >= 2 && !lua_isnil(L,2)) ? luaL_checkstring(L,2) : cOgreWrapper::GetSingleton().GetUniqueName();
00137             bool        bIsAlpha    = (lua_gettop(L) >= 3 && !lua_isnil(L,3)) ? lua_toboolean(L,3) : false;
00138             
00139             const Ogre::String& group           = Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;
00140             Ogre::TextureType   texType         = TEX_TYPE_2D;
00141             int                 iNumMipmaps     = MIP_DEFAULT;
00142             Ogre::Real          gamma           = 1.0f;
00143             Ogre::PixelFormat   desiredFormat   = PF_UNKNOWN;
00144             
00145             Ogre::TextureManager::getSingleton().loadImage(sTexName,group,checkudata_alive(L)->mImage,texType,iNumMipmaps,gamma,bIsAlpha,desiredFormat);
00146             lua_pushstring(L,sTexName.c_str());
00147             return 1; 
00148         }
00149         
00152         static int          LoadToTexture           (lua_State *L) { PROFILE
00153             std::string         sTexName    = luaL_checkstring(L,2);
00154             Ogre::TexturePtr    tex         = Ogre::TextureManager::getSingleton().load(sTexName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00155             if (tex.isNull()) return 0;
00156             tex->unload();
00157             tex->loadImage(checkudata_alive(L)->mImage);
00158             lua_pushboolean(L,true);
00159             return 1;
00160         }
00161         
00164         static int          GenerateBitMask         (lua_State *L) { PROFILE
00165             cBitMask* pTarget = new cBitMask();
00166             float fMinAlpha = (lua_gettop(L) >= 2 && !lua_isnil(L,2)) ? luaL_checknumber(L,2) : 0.5;
00167             pTarget->SetDataFromOgreImage(checkudata_alive(L)->mImage,fMinAlpha);
00168             return cLuaBind<cBitMask>::CreateUData(L,pTarget);
00169         }
00170         
00171     // static methods exported to lua
00172         
00176         static int          LoadImageFromFile       (lua_State *L) { PROFILE
00177             cImage* pImage = new cImage();
00178             std::string sFileNameOrPath = luaL_checkstring(L,1);
00179             try {
00180                 pImage->mImage.load(sFileNameOrPath,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00181             } catch (...) { delete pImage; return 0; }
00182             return CreateUData(L,pImage);
00183         }
00184         
00187         static int          LoadImageFromTexture            (lua_State *L) { PROFILE
00188             std::string         sTexName    = luaL_checkstring(L,1);
00189             Ogre::TexturePtr    tex         = Ogre::TextureManager::getSingleton().load(sTexName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00190             if (tex.isNull()) return 0;
00191             
00192             // lock and read access buffer
00193             Ogre::HardwarePixelBufferSharedPtr b = tex->getBuffer();
00194             if (b.isNull()) return 0;
00195             
00196             // allocate and fill buffer
00197             cImage* pImage = new cImage();
00198             Ogre::PixelFormat myformat = Ogre::PF_A8R8G8B8;
00199             Ogre::uchar* buf = (Ogre::uchar*)OGRE_MALLOC(Ogre::PixelUtil::getMemorySize(b->getWidth(),b->getHeight(),1,myformat), MEMCATEGORY_GENERAL);
00200             b->blitToMemory(Ogre::PixelBox(Ogre::Box(0,0,b->getWidth(),b->getHeight()),myformat,buf));
00201 
00202             // assign buffer to image
00203             pImage->mImage.loadDynamicImage(buf,b->getWidth(),b->getHeight(),1,myformat,true);
00204             
00205             return CreateUData(L,pImage);
00206         }
00207         
00209         static int      SubImage    (lua_State *L) { PROFILE
00210             // get params
00211             Ogre::Image& pImageS    = checkudata_alive(L)->mImage;
00212             int iOffsetX            = luaL_checkint(L,2);
00213             int iOffsetY            = luaL_checkint(L,3);
00214             int iNewWidth           = luaL_checkint(L,4);
00215             int iNewHeight          = luaL_checkint(L,5);
00216             
00217             cImage* pImageDest      = new cImage();
00218             MySubImage(pImageS,pImageDest->mImage,iOffsetX,iOffsetY,iNewWidth,iNewHeight);
00219             return CreateUData(L,pImageDest);
00220         }
00221         
00222         
00224         static int      ImageScale  (lua_State *L) { PROFILE
00225             // get params
00226             cImage* pImageSource    = checkudata_alive(L);
00227             int iNewWidth           = luaL_checkint(L,2);
00228             int iNewHeight          = luaL_checkint(L,3);
00229             
00230             // source
00231             Ogre::PixelFormat   iPixelFormat    = pImageSource->mImage.getFormat();
00232             Ogre::PixelBox      pPBoxSrc        = pImageSource->mImage.getPixelBox();
00233             
00234             // dest
00235             Ogre::uchar*        pDestBuffer = (Ogre::uchar*)OGRE_MALLOC(Ogre::PixelUtil::getMemorySize(iNewWidth,iNewHeight,1,iPixelFormat), MEMCATEGORY_GENERAL);
00236             Ogre::PixelBox      pPBoxDest   (iNewWidth,iNewHeight,1,iPixelFormat,pDestBuffer);
00237             Ogre::Image::Filter iFilter = Ogre::Image::FILTER_BILINEAR;
00238             Ogre::Image::scale(pPBoxSrc,pPBoxDest,iFilter);
00239             
00240             cImage* pImageDest      = new cImage();
00241             pImageDest->mImage.loadDynamicImage(pDestBuffer,iNewWidth,iNewHeight,1,iPixelFormat,true);
00242             return CreateUData(L,pImageDest);
00243         }
00244         
00247         static int      ImageBlit   (lua_State *L) { PROFILE
00248             Ogre::Image& pImageS    = checkudata_alive(L,1)->mImage;
00249             Ogre::Image& pImageD    = checkudata_alive(L,2)->mImage;
00250             int x                   = luaL_checkint(L,3);
00251             int y                   = luaL_checkint(L,4);
00252             cOgreWrapper::ImageBlit(pImageS,pImageD,x,y);
00253             return 0;
00254         }
00255         
00257         static int      CreateImage (lua_State *L) { PROFILE
00258             return CreateUData(L,new cImage());
00259         }
00260 
00261         
00266         static int      PrepareImage    (lua_State *L) { PROFILE
00267             assert(pPreparedBuf == 0 && "you must call CreatePreparedImage between the PrepareImage calls");
00268             
00269             iPreparedWidth = luaL_checkint(L,1);
00270             iPreparedHeight = luaL_checkint(L,2);
00271             
00272             assert(iPreparedWidth > 0 && iPreparedHeight > 0 && "size must not be 0");
00273             
00274             iPreparedBufferSize = Ogre::PixelUtil::getMemorySize(iPreparedWidth,iPreparedHeight,1,iPreparedFormat);
00275             iPreparedRowSize = Ogre::PixelUtil::getNumElemBytes(iPreparedFormat) * iPreparedWidth;
00276             pPreparedBuf = (Ogre::uchar*)OGRE_MALLOC(iPreparedBufferSize, MEMCATEGORY_GENERAL);
00277             
00278             if(
00279                 lua_gettop(L) >= 3 && !lua_isnil(L,3) &&
00280                 lua_gettop(L) >= 4 && !lua_isnil(L,4) &&
00281                 lua_gettop(L) >= 5 && !lua_isnil(L,5) &&
00282                 lua_gettop(L) >= 6 && !lua_isnil(L,6)
00283             ){
00284                 // set custom background
00285                 float r = luaL_checknumber(L,3);
00286                 float g = luaL_checknumber(L,4);
00287                 float b = luaL_checknumber(L,5);
00288                 float a = luaL_checknumber(L,6);
00289                 
00290                 int pitch = Ogre::PixelUtil::getNumElemBytes(iPreparedFormat);
00291                 
00292                 for(Ogre::uchar *p = pPreparedBuf; (p - pPreparedBuf) < iPreparedBufferSize;p += pitch){
00293                     Ogre::PixelUtil::packColour(r,g,b,a,iPreparedFormat,p);
00294                 }
00295             } else {
00296                 // set 0 background
00297                 memset(pPreparedBuf, 0, iPreparedBufferSize);
00298             }
00299             
00300             return 0;
00301         }
00302         
00305         static int      CreatePreparedImage (lua_State *L) { PROFILE
00306             cImage* pImageDest      = new cImage();
00307             pImageDest->mImage.loadDynamicImage(pPreparedBuf,iPreparedWidth,iPreparedHeight,1,iPreparedFormat,true);
00308             
00309             pPreparedBuf = 0;
00310             iPreparedWidth = 0;
00311             iPreparedHeight = 0;
00312             
00313             return CreateUData(L,pImageDest);
00314         }
00315 
00318         static int      SetPixelInPreparedImage (lua_State *L) { PROFILE
00319                 int x = luaL_checkint(L,1);
00320                 int y = luaL_checkint(L,2);
00321                 
00322                 if(x < 0 || y < 0 || x >= iPreparedWidth || y >= iPreparedHeight)return 0;
00323                 
00324                 float r = luaL_checknumber(L,3);
00325                 float g = luaL_checknumber(L,4);
00326                 float b = luaL_checknumber(L,5);
00327                 float a = luaL_checknumber(L,6);
00328                 
00329                 Ogre::uchar *p = pPreparedBuf + (y * iPreparedRowSize + x * Ogre::PixelUtil::getNumElemBytes(iPreparedFormat));
00330                 Ogre::PixelUtil::packColour(r,g,b,a,iPreparedFormat,p);
00331                 
00332                 return 0;
00333         }
00334 
00335         virtual const char* GetLuaTypeName () { return "lugre.Image"; }
00336 };
00337 
00339 void    cImage::LuaRegister     (lua_State *L) { PROFILE
00340     cLuaBind<cImage>::GetSingletonPtr(new cImage_L())->LuaRegister(L);
00341 }
00342 
00343 };

Generated on Wed Feb 8 06:00:13 2012 for cpp by  doxygen 1.5.6