Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/glrasterpainter.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "texturemanager.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tvectorgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void doDrawRaster(const TAffine &aff,
Toshihiro Shimizu 890ddd
				  UCHAR *buffer, int wrap, int bpp, const TDimension &rasDim,
Toshihiro Shimizu 890ddd
				  const TRect &bbox,
Toshihiro Shimizu 890ddd
				  bool showBBox,
Toshihiro Shimizu 890ddd
				  GLenum magFilter,
Toshihiro Shimizu 890ddd
				  GLenum minFilter,
Toshihiro Shimizu 890ddd
				  bool premultiplied)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!buffer)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isRGBM = (bpp == 4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isRGBM) {
Toshihiro Shimizu 890ddd
		if (bpp != 1)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDimension maxSize = TextureManager::instance()->getMaxSize(isRGBM);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (bbox.getLx() > maxSize.lx) {
Toshihiro Shimizu 890ddd
		TRect leftBox(bbox.getP00(), TDimension(maxSize.lx, bbox.getLy()));
Toshihiro Shimizu 890ddd
		TRect rightBox(TPoint(bbox.getP00().x + maxSize.lx, bbox.getP00().y), bbox.getP11());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(leftBox.getLx() == maxSize.lx);
Toshihiro Shimizu 890ddd
		assert(rightBox.getLx() == bbox.getLx() - maxSize.lx);
Toshihiro Shimizu 890ddd
		assert(leftBox.getLy() == bbox.getLy());
Toshihiro Shimizu 890ddd
		assert(rightBox.getLy() == bbox.getLy());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		doDrawRaster(aff, buffer, wrap, bpp, rasDim, leftBox, showBBox, magFilter, minFilter, premultiplied);
Toshihiro Shimizu 890ddd
		doDrawRaster(aff, buffer, wrap, bpp, rasDim, rightBox, showBBox, magFilter, minFilter, premultiplied);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (bbox.getLy() > maxSize.ly) {
Toshihiro Shimizu 890ddd
		TRect bottomBox(bbox.getP00(), TDimension(bbox.getLx(), maxSize.ly));
Toshihiro Shimizu 890ddd
		TRect topBox(TPointI(bbox.getP00().x, bbox.getP00().y + maxSize.ly), bbox.getP11());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(bottomBox.getLy() == maxSize.ly);
Toshihiro Shimizu 890ddd
		assert(topBox.getLy() == bbox.getLy() - maxSize.ly);
Toshihiro Shimizu 890ddd
		assert(bottomBox.getLx() == bbox.getLx());
Toshihiro Shimizu 890ddd
		assert(topBox.getLx() == bbox.getLx());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		doDrawRaster(aff, buffer, wrap, bpp, rasDim, bottomBox, showBBox, magFilter, minFilter, premultiplied);
Toshihiro Shimizu 890ddd
		doDrawRaster(aff, buffer, wrap, bpp, rasDim, topBox, showBBox, magFilter, minFilter, premultiplied);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glPushMatrix();
Toshihiro Shimizu 890ddd
	TTranslation T((bbox.getP00().x - (rasDim.lx - bbox.getLx()) / 2.),
Toshihiro Shimizu 890ddd
				   (bbox.getP00().y - (rasDim.ly - bbox.getLy()) / 2.));
Toshihiro Shimizu 890ddd
	tglMultMatrix(aff * T);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
Toshihiro Shimizu 890ddd
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glTexEnvf(GL_TEXTURE_ENV,
Toshihiro Shimizu 890ddd
			  GL_TEXTURE_ENV_MODE,
Toshihiro Shimizu 890ddd
			  GL_REPLACE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glEnable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
	glEnable(GL_BLEND);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (premultiplied)
Toshihiro Shimizu 890ddd
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Toshihiro Shimizu 890ddd
	TDimension ts = TextureManager::instance()->selectTexture(bbox.getSize(), isRGBM);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	GLenum fmt, type;
Toshihiro Shimizu 890ddd
	TextureManager::instance()->getFmtAndType(isRGBM, fmt, type);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int width = bbox.getLx();
Toshihiro Shimizu 890ddd
	int height = bbox.getLy();
Toshihiro Shimizu 890ddd
	int y = bbox.getP00().y;
Toshihiro Shimizu 890ddd
	int x = bbox.getP00().x;
Toshihiro Shimizu 890ddd
	buffer += (x + y * wrap) * bpp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glPixelStorei(GL_UNPACK_ROW_LENGTH, wrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glTexSubImage2D(
Toshihiro Shimizu 890ddd
		GL_TEXTURE_2D, // target (is a 2D texture)
Toshihiro Shimizu 890ddd
		0,			   // is one level only
Toshihiro Shimizu 890ddd
		0,
Toshihiro Shimizu 890ddd
		0,
Toshihiro Shimizu 890ddd
		width,
Toshihiro Shimizu 890ddd
		height,
Toshihiro Shimizu 890ddd
		fmt,
Toshihiro Shimizu 890ddd
		type,
Toshihiro Shimizu 890ddd
		buffer);
Toshihiro Shimizu 890ddd
	CHECK_ERRORS_BY_GL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double halfWidth = 0.5 * bbox.getLx();
Toshihiro Shimizu 890ddd
	double halfHeight = 0.5 * bbox.getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD v0((-halfWidth), (-halfHeight));
Toshihiro Shimizu 890ddd
	TPointD v1((halfWidth), (-halfHeight));
Toshihiro Shimizu 890ddd
	TPointD v2((-halfWidth), (halfHeight));
Toshihiro Shimizu 890ddd
	TPointD v3((halfWidth), (halfHeight));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double s = (bbox.getLx()) / (double)ts.lx;
Toshihiro Shimizu 890ddd
	double t = (bbox.getLy()) / (double)ts.ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glColor3d(0, 0, 0);
Toshihiro Shimizu 890ddd
	glBegin(GL_QUAD_STRIP);
Toshihiro Shimizu 890ddd
	glTexCoord2d(0, 0);
Toshihiro Shimizu 890ddd
	glVertex2d(v0.x, v0.y);
Toshihiro Shimizu 890ddd
	glTexCoord2d(s, 0);
Toshihiro Shimizu 890ddd
	glVertex2d(v1.x, v1.y);
Toshihiro Shimizu 890ddd
	glTexCoord2d(0, t);
Toshihiro Shimizu 890ddd
	glVertex2d(v2.x, v2.y);
Toshihiro Shimizu 890ddd
	glTexCoord2d(s, t);
Toshihiro Shimizu 890ddd
	glVertex2d(v3.x, v3.y);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glDisable(GL_BLEND);
Toshihiro Shimizu 890ddd
	glDisable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (showBBox) {
Toshihiro Shimizu 890ddd
		glBegin(GL_LINE_LOOP);
Toshihiro Shimizu 890ddd
		glVertex2d(v0.x, v0.y);
Toshihiro Shimizu 890ddd
		glVertex2d(v1.x, v1.y);
Toshihiro Shimizu 890ddd
		glVertex2d(v3.x, v3.y);
Toshihiro Shimizu 890ddd
		glVertex2d(v2.x, v2.y);
Toshihiro Shimizu 890ddd
		glEnd();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	glPopMatrix();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void doDrawRaster(const TAffine &aff,
Toshihiro Shimizu 890ddd
				  const TRasterImageP &ri,
Toshihiro Shimizu 890ddd
				  const TRectI &bbox,
Toshihiro Shimizu 890ddd
				  bool showBBox,
Toshihiro Shimizu 890ddd
				  GLenum magFilter,
Toshihiro Shimizu 890ddd
				  GLenum minFilter,
Toshihiro Shimizu 890ddd
				  bool premultiplied)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP r = ri->getRaster();
Toshihiro Shimizu 890ddd
	r->lock();
Toshihiro Shimizu 890ddd
	doDrawRaster(aff,
Toshihiro Shimizu 890ddd
				 r->getRawData(), r->getWrap(), r->getPixelSize(),
Toshihiro Shimizu 890ddd
				 r->getSize(),
Toshihiro Shimizu 890ddd
				 bbox,
Toshihiro Shimizu 890ddd
				 showBBox,
Toshihiro Shimizu 890ddd
				 magFilter,
Toshihiro Shimizu 890ddd
				 minFilter,
Toshihiro Shimizu 890ddd
				 premultiplied);
Toshihiro Shimizu 890ddd
	r->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void GLRasterPainter::drawRaster(const TAffine &aff, UCHAR *buffer, int wrap, int bpp, const TDimension &rasSize, bool premultiplied)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!buffer)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	doDrawRaster(
Toshihiro Shimizu 890ddd
		aff, buffer, wrap, bpp, rasSize, rasSize,
Toshihiro Shimizu 890ddd
		false, GL_NEAREST, GL_LINEAR, premultiplied);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void GLRasterPainter::drawRaster(const TAffine &aff, const TRasterImageP &ri, bool premultiplied)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!ri || !ri->getRaster())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	doDrawRaster(
Toshihiro Shimizu 890ddd
		aff, ri, ri->getRaster()->getBounds(),
Toshihiro Shimizu 890ddd
		false, GL_NEAREST, GL_LINEAR, premultiplied);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void GLRasterPainter::drawRaster(const TAffine &aff, const TToonzImageP &ti, bool showSavebox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRect saveBox = ti->getSavebox();
Toshihiro Shimizu 890ddd
	if (saveBox.isEmpty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterCM32P ras = ti->getRaster();
Toshihiro Shimizu 890ddd
	TPaletteP palette = ti->getPalette();
Toshihiro Shimizu 890ddd
	TRaster32P ras32(ras->getSize());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRop::convert(ras32, ras, palette, saveBox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterImageP rasImg(ras32);
Toshihiro Shimizu 890ddd
	double dpix, dpiy;
Toshihiro Shimizu 890ddd
	ti->getDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
	rasImg->setDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool premultiplied = true;
Toshihiro Shimizu 890ddd
	doDrawRaster(aff, rasImg, saveBox, showSavebox, GL_NEAREST, GL_LINEAR, premultiplied);
Toshihiro Shimizu 890ddd
}