BitmapPtr BmpTextureMover::moveTextureToBmp(GLTexture& tex, int mipmapLevel) { GLContext* pContext = GLContext::getCurrent(); unsigned fbo = pContext->genFBO(); glproc::BindFramebuffer(GL_FRAMEBUFFER, fbo); glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.getID(), mipmapLevel); FBO::checkError("BmpTextureMover::moveTextureToBmp"); IntPoint size = tex.getMipmapSize(mipmapLevel); BitmapPtr pBmp(new Bitmap(size, getPF())); if (GLContext::getMain()->isGLES() && getPF() == B5G6R5) { BitmapPtr pTmpBmp(new Bitmap(size, R8G8B8)); glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, pTmpBmp->getPixels()); FilterFlipRGB().applyInPlace(pTmpBmp); pBmp->copyPixels(*pTmpBmp); } else { int glPixelFormat = tex.getGLFormat(getPF()); glReadPixels(0, 0, size.x, size.y, glPixelFormat, tex.getGLType(getPF()), pBmp->getPixels()); } GLContext::checkError("BmpTextureMover::moveTextureToBmp: glReadPixels()"); glproc::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); pContext->returnFBOToCache(fbo); glproc::BindFramebuffer(GL_FRAMEBUFFER, 0); return pBmp; }
void GPUImage::setBitmap(BitmapPtr pBmp, TexCompression comp) { assertValid(); if (!pBmp) { throw Exception(AVG_ERR_UNSUPPORTED, "setBitmap(): bitmap must not be None!"); } if (comp == TEXCOMPRESSION_B5G6R5 && pBmp->hasAlpha()) { throw Exception(AVG_ERR_UNSUPPORTED, "B5G6R5-compressed textures with an alpha channel are not supported."); } unload(); changeSource(BITMAP); m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), pBmp->getPixelFormat(), "")); m_pBmp->copyPixels(*pBmp); if (comp == TEXCOMPRESSION_B5G6R5) { BitmapPtr pDestBmp = BitmapPtr(new Bitmap(pBmp->getSize(), B5G6R5, "")); if (!BitmapLoader::get()->isBlueFirst()) { FilterFlipRGB().applyInPlace(m_pBmp); } pDestBmp->copyPixels(*m_pBmp); m_pBmp = pDestBmp; } if (m_State == GPU) { setupBitmapSurface(); } assertValid(); }
void Image::setFilename(const std::string& sFilename, TextureCompression comp) { assertValid(); AVG_TRACE(Logger::category::MEMORY, Logger::severity::INFO, "Loading " << sFilename); BitmapPtr pBmp = loadBitmap(sFilename); if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) { throw Exception(AVG_ERR_UNSUPPORTED, "B5G6R5-compressed textures with an alpha channel are not supported."); } changeSource(FILE); m_pBmp = pBmp; m_sFilename = sFilename; switch (comp) { case TEXTURECOMPRESSION_B5G6R5: m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), B5G6R5, sFilename)); if (!BitmapLoader::get()->isBlueFirst()) { FilterFlipRGB().applyInPlace(pBmp); } m_pBmp->copyPixels(*pBmp); break; case TEXTURECOMPRESSION_NONE: break; default: assert(false); } if (m_State == GPU) { m_pSurface->destroy(); setupSurface(); } assertValid(); }
BitmapPtr SVG::internalRenderElement(const SVGElementPtr& pElement, const glm::vec2& renderSize, const glm::vec2& size) { glm::vec2 pos = pElement->getPos(); glm::vec2 scale(renderSize.x/size.x, renderSize.y/size.y); IntPoint boundingBox = IntPoint(renderSize) + IntPoint(int(scale.x+0.5), int(scale.y+0.5)); BitmapPtr pBmp(new Bitmap(boundingBox, B8G8R8A8)); FilterFill<Pixel32>(Pixel32(0,0,0,0)).applyInPlace(pBmp); cairo_surface_t* pSurface; cairo_t* pCairo; pSurface = cairo_image_surface_create_for_data(pBmp->getPixels(), CAIRO_FORMAT_ARGB32, boundingBox.x, boundingBox.y, pBmp->getStride()); pCairo = cairo_create(pSurface); cairo_scale(pCairo, scale.x, scale.y); cairo_translate(pCairo, -pos.x, -pos.y); rsvg_handle_render_cairo_sub(m_pRSVG, pCairo, pElement->getUnescapedID().c_str()); FilterUnmultiplyAlpha().applyInPlace(pBmp); cairo_surface_destroy(pSurface); cairo_destroy(pCairo); if (!BitmapLoader::get()->isBlueFirst()) { FilterFlipRGB().applyInPlace(pBmp); } return pBmp; }
BitmapPtr BitmapLoader::load(const UTF8String& sFName, PixelFormat pf) const { AVG_ASSERT(s_pBitmapLoader != 0); GError* pError = 0; GdkPixbuf* pPixBuf; { ScopeTimer timer(GDKPixbufProfilingZone); pPixBuf = gdk_pixbuf_new_from_file(sFName.c_str(), &pError); } if (!pPixBuf) { string sErr = pError->message; g_error_free(pError); throw Exception(AVG_ERR_FILEIO, sErr); } IntPoint size = IntPoint(gdk_pixbuf_get_width(pPixBuf), gdk_pixbuf_get_height(pPixBuf)); PixelFormat srcPF; if (gdk_pixbuf_get_has_alpha(pPixBuf)) { srcPF = R8G8B8A8; } else { srcPF = R8G8B8; } if (pf == NO_PIXELFORMAT) { if (m_bBlueFirst) { if (srcPF == R8G8B8A8) { pf = B8G8R8A8; } else if (srcPF == R8G8B8) { pf = B8G8R8X8; } } else { if (srcPF == R8G8B8A8) { pf = R8G8B8A8; } else if (srcPF == R8G8B8) { pf = R8G8B8X8; } } } BitmapPtr pBmp(new Bitmap(size, pf, sFName)); { ScopeTimer timer(ConvertProfilingZone); int stride = gdk_pixbuf_get_rowstride(pPixBuf); guchar* pSrc = gdk_pixbuf_get_pixels(pPixBuf); BitmapPtr pSrcBmp(new Bitmap(size, srcPF, pSrc, stride, false)); { ScopeTimer timer(RGBFlipProfilingZone); if (pixelFormatIsBlueFirst(pf) != pixelFormatIsBlueFirst(srcPF)) { FilterFlipRGB().applyInPlace(pSrcBmp); } } pBmp->copyPixels(*pSrcBmp); } g_object_unref(pPixBuf); return pBmp; }
void Image::setBitmap(BitmapPtr pBmp, TextureCompression comp) { assertValid(); if (!pBmp) { throw Exception(AVG_ERR_UNSUPPORTED, "setBitmap(): bitmap must not be None!"); } if (comp == TEXTURECOMPRESSION_B5G6R5 && pBmp->hasAlpha()) { throw Exception(AVG_ERR_UNSUPPORTED, "B5G6R5-compressed textures with an alpha channel are not supported."); } bool bSourceChanged = changeSource(BITMAP); PixelFormat pf; switch (comp) { case TEXTURECOMPRESSION_NONE: pf = pBmp->getPixelFormat(); break; case TEXTURECOMPRESSION_B5G6R5: pf = B5G6R5; if (!BitmapLoader::get()->isBlueFirst()) { FilterFlipRGB().applyInPlace(pBmp); } break; default: assert(false); } m_pBmp = BitmapPtr(new Bitmap(pBmp->getSize(), pf, "")); m_pBmp->copyPixels(*pBmp); if (m_State == GPU) { MCTexturePtr pTex = m_pSurface->getTex(); if (bSourceChanged || m_pSurface->getSize() != m_pBmp->getSize() || m_pSurface->getPixelFormat() != pf) { pTex = GLContextManager::get()->createTexture(m_pBmp->getSize(), pf, m_Material.getUseMipmaps(), m_Material.getWrapSMode(), m_Material.getWrapTMode()); m_pSurface->create(pf, pTex); } GLContextManager::get()->scheduleTexUpload(pTex, m_pBmp); } assertValid(); }