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