Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/textureutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "imagebuilders.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    TXshSimpleLevel Texture Utilities  locals
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 6f0974
Toshihiro Shimizu 890ddd
TRasterImageP convert32(const TImageP &img)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		static TRasterImageP depremultiplied(const TRasterImageP &ri)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			assert(ri->getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRop::depremultiply(ri->getRaster());
Toshihiro Shimizu 890ddd
			return ri;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (TRasterImageP ri = img) {
Toshihiro Shimizu 890ddd
		TRasterP ras(ri->getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRaster32P ras32;
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			if (TRaster32P(ras))
Toshihiro Shimizu 890ddd
				ras32 = ras->clone();
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				ras32 = TRaster32P(ras->getSize());
Toshihiro Shimizu 890ddd
				TRop::convert(ras32, ras);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD dpi;
Toshihiro Shimizu 890ddd
		ri->getDpi(dpi.x, dpi.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterImageP ri32(ras32);
Toshihiro Shimizu 890ddd
		ri32->setDpi(dpi.x, dpi.y);
Toshihiro Shimizu 890ddd
		ri32->setSubsampling(ri->getSubsampling());
Toshihiro Shimizu 890ddd
		ri32->setOffset(ri->getOffset());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return locals::depremultiplied(ri32);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = img) {
Toshihiro Shimizu 890ddd
		TRasterCM32P rasCM32(ti->getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRaster32P ras32(rasCM32->getSize());
Toshihiro Shimizu 890ddd
		TRop::convert(ras32, rasCM32, ti->getPalette());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD dpi;
Toshihiro Shimizu 890ddd
		ti->getDpi(dpi.x, dpi.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterImageP ri32(ras32);
Toshihiro Shimizu 890ddd
		ri32->setDpi(dpi.x, dpi.y);
Toshihiro Shimizu 890ddd
		ri32->setSubsampling(ti->getSubsampling());
Toshihiro Shimizu 890ddd
		ri32->setOffset(ti->getOffset());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return locals::depremultiplied(ri32);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRasterImageP();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterImageP getTexture(const TXshSimpleLevel *sl, const TFrameId &fid, int subsampling)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (sl->getType() != PLI_XSHLEVEL) {
Toshihiro Shimizu 890ddd
		TImageP texImg = sl->getFrame(fid, ImageManager::dontPutInCache, subsampling);
Toshihiro Shimizu 890ddd
		return convert32(texImg);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Vector case
Shinya Kitaoka 6f0974
	std::string id = sl->getImageId(fid) + "_rasterized";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ImageLoader::BuildExtData extData(sl, fid);
Shinya Kitaoka 6f0974
	TRasterImageP ri(ImageManager::instance()->getImage(id, ImageManager::dontPutInCache, &extData));
Shinya Kitaoka 6f0974
Shinya Kitaoka 6f0974
	return ri;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    TXshSimpleLevel Texture Utilities  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DrawableTextureDataP texture_utils::getTextureData(
Toshihiro Shimizu 890ddd
	const TXshSimpleLevel *sl, const TFrameId &fid, int subsampling)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const std::string &texId = sl->getImageId(fid);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Now, we must associate a texture
Toshihiro Shimizu 890ddd
	DrawableTextureDataP data(TTexturesStorage::instance()->getTextureData(texId));
Toshihiro Shimizu 890ddd
	if (data)
Toshihiro Shimizu 890ddd
		return data;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// There was no associated texture. We must bind the texture and repeat
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// First, retrieve the image to be used as texture
Toshihiro Shimizu 890ddd
	TRasterImageP ri(::getTexture(sl, fid, subsampling));
Toshihiro Shimizu 890ddd
	if (!ri)
Toshihiro Shimizu 890ddd
		return DrawableTextureDataP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P ras(ri->getRaster());
Toshihiro Shimizu 890ddd
	assert(ras);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6f0974
	TRectD geom(0, 0, ras->getLx(), ras->getLy());
Shinya Kitaoka 6f0974
	geom = TScale(ri->getSubsampling()) *
Shinya Kitaoka 6f0974
		   TTranslation(convert(ri->getOffset()) - ras->getCenterD()) *
Shinya Kitaoka 6f0974
		   geom;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TTexturesStorage::instance()->loadTexture(texId, ras, geom);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void texture_utils::invalidateTexture(const TXshSimpleLevel *sl, const TFrameId &fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const std::string &texId = sl->getImageId(fid);
Toshihiro Shimizu 890ddd
	TTexturesStorage::instance()->unloadTexture(texId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void texture_utils::invalidateTextures(const TXshSimpleLevel *sl)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int f, fCount = sl->getFrameCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (f = 0; f != fCount; ++f)
Toshihiro Shimizu 890ddd
		invalidateTexture(sl, sl->getFrameId(f));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    TXsheet Texture Utilities  locals
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::string getImageId(const TXsheet *xsh, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "X" + toString(xsh->id()) + "_" + toString(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
//    TXsheet Texture Utilities  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DrawableTextureDataP texture_utils::getTextureData(const TXsheet *xsh, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Check if an xsheet texture already exists
Toshihiro Shimizu 890ddd
	const std::string &texId = ::getImageId(xsh, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DrawableTextureDataP data(TTexturesStorage::instance()->getTextureData(texId));
Toshihiro Shimizu 890ddd
	if (data)
Toshihiro Shimizu 890ddd
		return data;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// No available texture - we must build and load it
Toshihiro Shimizu 890ddd
	TRaster32P tex(1024, 1024); // Fixed texture size. It's the same that currently happens with
Toshihiro Shimizu 890ddd
								// vector images' textures - and justified since this is camstand
Toshihiro Shimizu 890ddd
								// mode, and besides we want to make sure that textures are limited.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Retrieve the sub-xsheet bbox (world coordinates of the sub-xsheet)
Toshihiro Shimizu 890ddd
	TRectD bbox(xsh->getBBox(frame));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Since xsh represents a sub-xsheet, its camera affine must be applied
Toshihiro Shimizu 890ddd
	const TAffine &cameraAff = xsh->getPlacement(xsh->getStageObjectTree()->getCurrentCameraId(), frame);
Toshihiro Shimizu 890ddd
	bbox = (cameraAff.inv() * bbox).enlarge(1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Render the xsheet on the specified bbox
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// The call below will change context (I know, it's a shame :( )
Toshihiro Shimizu 890ddd
	TGlContext currentContext = tglGetCurrentContext();
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		tglDoneCurrent(currentContext);
Toshihiro Shimizu 890ddd
		xsh->getScene()->renderFrame(tex, frame, xsh, bbox, TAffine());
Toshihiro Shimizu 890ddd
		tglMakeCurrent(currentContext);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRop::depremultiply(tex); // Stored textures are rendered nonpremultiplied
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Store the texture for future retrieval
Toshihiro Shimizu 890ddd
	return TTexturesStorage::instance()->loadTexture(texId, tex, bbox);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void texture_utils::invalidateTexture(const TXsheet *xsh, int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const std::string &texId = ::getImageId(xsh, frame);
Toshihiro Shimizu 890ddd
	TTexturesStorage::instance()->unloadTexture(texId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void texture_utils::invalidateTextures(const TXsheet *xsh)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int f, fCount = xsh->getFrameCount();
Toshihiro Shimizu 890ddd
	for (f = 0; f != fCount; ++f)
Toshihiro Shimizu 890ddd
		invalidateTexture(xsh, f);
Toshihiro Shimizu 890ddd
}