Added: Creating texture from data:image/type

feature/pre-code-move
Nimetu 5 years ago
parent d2ccc09b7d
commit b208c0b805

@ -267,6 +267,8 @@ namespace NLGUI
bool bReleasable=true bool bReleasable=true
); );
// Create texture from dataURL "data:image/png;base64," string
sint32 createTextureFromDataURL(const std::string &data, bool uploadDXTC=true, bool bReleasable=true);
// change position of a sub-texture (inside its big texture) from the sub-texture filename // change position of a sub-texture (inside its big texture) from the sub-texture filename
void updateTexturePos(const std::string &texturefileName, void updateTexturePos(const std::string &texturefileName,

@ -481,7 +481,7 @@ namespace NLGUI
} }
} }
else else
_TextureId.setTexture (toLower(TxName).c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false); _TextureId.setTexture (TxName.c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

@ -24,6 +24,8 @@
#include "nel/misc/file.h" #include "nel/misc/file.h"
#include "nel/misc/uv.h" #include "nel/misc/uv.h"
#include "nel/misc/hierarchical_timer.h" #include "nel/misc/hierarchical_timer.h"
#include "nel/misc/base64.h"
#include "nel/misc/md5.h"
using namespace NLMISC; using namespace NLMISC;
using namespace std; using namespace std;
@ -998,6 +1000,10 @@ namespace NLGUI
) )
{ {
if (sGlobalTextureName.empty()) return -1; if (sGlobalTextureName.empty()) return -1;
if (startsWith(sGlobalTextureName, "data:image/"))
return createTextureFromDataURL(sGlobalTextureName, uploadDXTC, bReleasable);
// Look if already existing // Look if already existing
string sLwrGTName = toLower(sGlobalTextureName); string sLwrGTName = toLower(sGlobalTextureName);
TGlobalTextureList::iterator ite = _GlobalTextures.begin(); TGlobalTextureList::iterator ite = _GlobalTextures.begin();
@ -1062,6 +1068,93 @@ namespace NLGUI
return TextID; return TextID;
} }
sint32 CViewRenderer::createTextureFromDataURL(const std::string &data, bool uploadDXTC, bool bReleasable)
{
if (!startsWith(data, "data:image/"))
return -1;
size_t pos = data.find(";base64,");
if (pos == std::string::npos)
{
nlwarning("Failed to parse dataURL (not base64?) '%s'", data.c_str());
return -1;
}
std::string md5hash = getMD5((uint8 *)data.c_str(), (uint32)data.size()).toString();
TGlobalTextureList::iterator ite = _GlobalTextures.begin();
while (ite != _GlobalTextures.end())
{
if (md5hash == ite->Name)
break;
ite++;
}
// If global texture not exists create it
if (ite == _GlobalTextures.end())
{
std::string decoded = base64::decode(data.substr(pos + 8));
if (decoded.empty())
{
nlwarning("base64 decode failed '%s'", data.substr(pos + 8).c_str());
return -1;
}
//
CMemStream buf;
if (buf.isReading()) buf.invert();
buf.serialBuffer((uint8 *)(decoded.data()), decoded.size());
buf.invert();
CBitmap btm;
btm.load(buf);
SGlobalTexture gtTmp;
gtTmp.FromGlobaleTexture = false;
gtTmp.Width = gtTmp.DefaultWidth = btm.getWidth();;
gtTmp.Height = gtTmp.DefaultHeight = btm.getHeight();
if (gtTmp.Width == 0 || gtTmp.Height == 0)
{
nlwarning("Failed to load the texture '%s', please check image format", data.c_str());
return -1;
}
UTextureMem *texture = driver->createTextureMem(btm.getWidth(), btm.getHeight(), CBitmap::RGBA);
if (!texture)
{
nlwarning("Failed to create mem texture (%d,%d)", btm.getWidth(), btm.getHeight());
return -1;
}
memcpy(texture->getPointer(), btm.getPixels().getPtr(), btm.getSize() * 4);
gtTmp.Texture = texture;
gtTmp.Name = md5hash;
gtTmp.Texture->setFilterMode(UTexture::Nearest, UTexture::NearestMipMapOff);
gtTmp.Texture->setReleasable(bReleasable);
if(uploadDXTC)
gtTmp.Texture->setUploadFormat(UTexture::DXTC5);
_GlobalTextures.push_back(gtTmp);
ite = _GlobalTextures.end();
ite--;
}
// Add a texture with reference to the i th global texture
SImage iTmp;
// Set default parameters
iTmp.Name = data;
iTmp.GlobalTexturePtr = &(*ite);
iTmp.UVMin = CUV(0.f , 0.f);
iTmp.UVMax = CUV(1.f , 1.f);
sint32 TextID = addSImage(iTmp);
return TextID;
}
void CViewRenderer::updateTexturePos(const std::string &texturefileName, sint32 offsetX /*=0*/, sint32 offsetY /*=0*/, sint32 width /*=-1*/, sint32 height /*=-1*/) void CViewRenderer::updateTexturePos(const std::string &texturefileName, sint32 offsetX /*=0*/, sint32 offsetY /*=0*/, sint32 width /*=-1*/, sint32 height /*=-1*/)
{ {
sint32 id = getTextureIdFromName (texturefileName); sint32 id = getTextureIdFromName (texturefileName);
@ -1159,6 +1252,11 @@ namespace NLGUI
{ {
driver->deleteTextureFile (tf); driver->deleteTextureFile (tf);
} }
else
{
UTextureMem *tf = dynamic_cast<NL3D::UTextureMem *>(iteGT->Texture);
if (tf) driver->deleteTextureMem(tf);
}
_GlobalTextures.erase (iteGT); _GlobalTextures.erase (iteGT);
return; return;
} }

Loading…
Cancel
Save