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