void tglMakeCurrent(TGlContext context) { if (context) reinterpret_cast<QGLContext *>(context)->makeCurrent(); else tglDoneCurrent(tglGetCurrentContext()); }
DrawableTextureDataP texture_utils::getTextureData(const TXsheet *xsh, int frame) { // Check if an xsheet texture already exists const std::string &texId = ::getImageId(xsh, frame); DrawableTextureDataP data( TTexturesStorage::instance()->getTextureData(texId)); if (data) return data; // No available texture - we must build and load it TRaster32P tex( 1024, 1024); // Fixed texture size. It's the same that currently happens with // vector images' textures - and justified since this is camstand // mode, and besides we want to make sure that textures are limited. // Retrieve the sub-xsheet bbox (world coordinates of the sub-xsheet) TRectD bbox(xsh->getBBox(frame)); // Since xsh represents a sub-xsheet, its camera affine must be applied const TAffine &cameraAff = xsh->getPlacement(xsh->getStageObjectTree()->getCurrentCameraId(), frame); bbox = (cameraAff.inv() * bbox).enlarge(1.0); // Render the xsheet on the specified bbox #ifdef MACOSX xsh->getScene()->renderFrame(tex, frame, xsh, bbox, TAffine()); #else // The call below will change context (I know, it's a shame :( ) TGlContext currentContext = tglGetCurrentContext(); { tglDoneCurrent(currentContext); xsh->getScene()->renderFrame(tex, frame, xsh, bbox, TAffine()); tglMakeCurrent(currentContext); } #endif TRop::depremultiply(tex); // Stored textures are rendered nonpremultiplied // Store the texture for future retrieval return TTexturesStorage::instance()->loadTexture(texId, tex, bbox); }
TImageP ImageRasterizer::build(int imFlags, void *extData) { assert(!(imFlags & ~(ImageManager::dontPutInCache | ImageManager::forceRebuild))); TDimension d(10, 10); TPoint off(0, 0); // Fetch image assert(extData); ImageLoader::BuildExtData *data = (ImageLoader::BuildExtData *)extData; const std::string &srcImgId = data->m_sl->getImageId(data->m_fid); TImageP img = ImageManager::instance()->getImage(srcImgId, imFlags, extData); if (img) { TVectorImageP vi = img; if (vi) { TRectD bbox = vi->getBBox(); d = TDimension(tceil(bbox.getLx()) + 1, tceil(bbox.getLy()) + 1); off = TPoint((int)bbox.x0, (int)bbox.y0); TPalette *vpalette = vi->getPalette(); TVectorRenderData rd(TTranslation(-off.x, -off.y), TRect(TPoint(0, 0), d), vpalette, 0, true, true); TGlContext oldContext = tglGetCurrentContext(); // this is too slow. { QSurfaceFormat format; format.setProfile(QSurfaceFormat::CompatibilityProfile); TRaster32P ras(d); glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_MODELVIEW), glPushMatrix(); glMatrixMode(GL_PROJECTION), glPushMatrix(); { std::unique_ptr<QOpenGLFramebufferObject> fb(new QOpenGLFramebufferObject(d.lx, d.ly)); fb->bind(); assert(glGetError() == 0); glViewport(0, 0, d.lx, d.ly); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, d.lx, 0, d.ly); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); assert(glGetError() == 0); tglDraw(rd, vi.getPointer()); assert(glGetError() == 0); assert(glGetError() == 0); glFlush(); assert(glGetError() == 0); QImage img = fb->toImage().scaled(QSize(d.lx, d.ly), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); int wrap = ras->getLx() * sizeof(TPixel32); uchar *srcPix = img.bits(); uchar *dstPix = ras->getRawData() + wrap * (d.ly - 1); for (int y = 0; y < d.ly; y++) { memcpy(dstPix, srcPix, wrap); dstPix -= wrap; srcPix += wrap; } fb->release(); } glMatrixMode(GL_MODELVIEW), glPopMatrix(); glMatrixMode(GL_PROJECTION), glPopMatrix(); glPopAttrib(); tglMakeCurrent(oldContext); TRasterImageP ri = TRasterImageP(ras); ri->setOffset(off + ras->getCenter()); return ri; } } } // Error case: return a dummy image (is it really required?) TRaster32P ras(d); ras->fill(TPixel32(127, 0, 127, 127)); return TRasterImageP(ras); }