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
}