bool ShadowUpdateTask::executeTaskInMainThread() { if (!mPageGeometries.empty()) { auto pageGeometry = mPageGeometries.back(); mPageGeometries.pop_back(); auto& page = pageGeometry->getPage(); if (page.getSurface()) { auto shadow = page.getSurface()->getShadow(); if (shadow) { auto& shadowTextureName = shadow->getShadowTextureName(); if (!shadowTextureName.empty()) { Ogre::TexturePtr texture = Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(shadowTextureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); if (texture) { Ogre::Image ogreImage; shadow->loadIntoImage(ogreImage); texture->loadImage(ogreImage); //blit the whole image to the hardware buffer Ogre::PixelBox sourceBox(ogreImage.getPixelBox()); //blit for each mipmap for (unsigned int i = 0; i <= texture->getNumMipmaps(); ++i) { Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(texture->getBuffer(0, i)); hardwareBuffer->blitFromMemory(sourceBox); } } } } } } return mPageGeometries.empty(); }
Ogre::TexturePtr Simple::updateShadowTexture(Ogre::MaterialPtr material, const TerrainPageShadow* terrainPageShadow, std::set<std::string>& managedTextures) const { auto shadowTextureName = getShadowTextureName(material); Ogre::TexturePtr texture = static_cast<Ogre::TexturePtr>(Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(shadowTextureName)); if (texture.isNull()) { texture = Ogre::Root::getSingletonPtr()->getTextureManager()->createManual(shadowTextureName, "General", Ogre::TEX_TYPE_2D, mPage.getBlendMapSize(), mPage.getBlendMapSize(), 1, Ogre::PF_L8, Ogre::TU_DYNAMIC_WRITE_ONLY); managedTextures.insert(texture->getName()); } Ogre::Image ogreImage; terrainPageShadow->loadIntoImage(ogreImage); texture->loadImage(ogreImage); //blit the whole image to the hardware buffer Ogre::PixelBox sourceBox(ogreImage.getPixelBox()); //blit for each mipmap for (unsigned int i = 0; i <= texture->getNumMipmaps(); ++i) { Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(texture->getBuffer(0, i)); hardwareBuffer->blitFromMemory(sourceBox); } return texture; }
Ogre::TexturePtr Simple::updateShadowTexture(Ogre::MaterialPtr material, const TerrainPageShadow* terrainPageShadow) { //we need an unique name for our alpha texture std::stringstream shadowTextureNameSS; shadowTextureNameSS << material->getName() << "_shadow"; const Ogre::String shadowTextureName(shadowTextureNameSS.str()); Ogre::TexturePtr texture = static_cast<Ogre::TexturePtr> (Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(shadowTextureName)); if (texture.isNull()) { texture = Ogre::Root::getSingletonPtr()->getTextureManager()->createManual(shadowTextureName, "General", Ogre::TEX_TYPE_2D, mPage.getAlphaTextureSize(), mPage.getAlphaTextureSize(), 1, Ogre::PF_L8, Ogre::TU_DYNAMIC_WRITE_ONLY); } Ogre::Image ogreImage; terrainPageShadow->loadIntoImage(ogreImage); texture->loadImage(ogreImage); //blit the whole image to the hardware buffer Ogre::PixelBox sourceBox(ogreImage.getPixelBox()); //blit for each mipmap for (unsigned int i = 0; i <= texture->getNumMipmaps(); ++i) { Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(texture->getBuffer(0, i)); hardwareBuffer->blitFromMemory(sourceBox); } return texture; }
/**************************************************************************** ** ** Copyright (C) 2016 - 2017 ** ** This file is part of the Magus toolkit ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ #include "constants.h" #include "texturelayer.h" #include "OgreHlmsPbs.h" #include "OgreHlmsManager.h" #include "OgreLogManager.h" #include "OgreStringConverter.h" #include <fstream> #include <ctime> //****************************************************************************/ TextureLayer::TextureLayer(void) : mTextureOnWhichIsPaintedWidth(0), mTextureOnWhichIsPaintedHeight(0), mTextureOnWhichIsPaintedHasAlpha(false), mNumMipMaps(0), mTextureTypeDefined(false), mMaxSequence(0) { mTextureType = Ogre::PBSM_DIFFUSE; mDatablockId = ""; mTextureFileName = ""; } //****************************************************************************/ TextureLayer::~TextureLayer(void) { } //****************************************************************************/ void TextureLayer::setDatablockIdAndTexture (const Ogre::IdString& datablockId, Ogre::PbsTextureTypes textureType, const Ogre::String& textureFileName) { mDatablockId = datablockId; mTextureType = textureType; mTextureFileName = textureFileName; mTextureTypeDefined = true; // Load the texture as image; assume it can be loaded, because it was already loaded as part of the material setFirstTextureGeneration(); // Create the pixelbox of the original texture; this MUST be a separate image mOriginalTexture.load(textureFileName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mPixelboxOriginalTexture = mOriginalTexture.getPixelBox(0, 0); // Debug texture //Ogre::LogManager::getSingleton().logMessage("Debug texture: " + textureFileName); //Ogre::LogManager::getSingleton().logMessage("Depth: " + Ogre::StringConverter::toString(mOriginalTexture.getDepth())); //Ogre::LogManager::getSingleton().logMessage("Pixel format: " + Ogre::StringConverter::toString(mOriginalTexture.getFormat())); //Ogre::LogManager::getSingleton().logMessage("Alpha: " + Ogre::StringConverter::toString(mOriginalTexture.getHasAlpha())); //Ogre::LogManager::getSingleton().logMessage("Height: " + Ogre::StringConverter::toString(mOriginalTexture.getHeight())); //Ogre::LogManager::getSingleton().logMessage("Number of faces: " + Ogre::StringConverter::toString(mOriginalTexture.getNumFaces())); //Ogre::LogManager::getSingleton().logMessage("Number of mipmaps: " + Ogre::StringConverter::toString(mOriginalTexture.getNumMipmaps())); //Ogre::LogManager::getSingleton().logMessage("Width: " + Ogre::StringConverter::toString(mOriginalTexture.getWidth())); } //****************************************************************************/ void TextureLayer::blitTexture (void) { /* Always get the actual pointers, because they may change. That is the reason why the datablock pointer cannot be cached. * The same seems to apply to the texture pointer. */ Ogre::HlmsDatablock* datablock; Ogre::HlmsPbsDatablock* datablockPbs; Ogre::TexturePtr texture; Ogre::HlmsManager* hlmsManager = Ogre::Root::getSingletonPtr()->getHlmsManager(); Ogre::HlmsPbs* hlmsPbs = static_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS)); datablock = hlmsPbs->getDatablock(mDatablockId); if (!datablock) return; datablockPbs = static_cast<Ogre::HlmsPbsDatablock*>(datablock); try { // Get texture on GPU if (!datablockPbs->getTexture(mTextureType).isNull()) { texture = datablockPbs->getTexture(mTextureType); // TextureType MUST exist, otherwise the application crashes mNumMipMaps = texture->getNumMipmaps(); } } catch (Ogre::Exception e){} if (texture.isNull()) return; Ogre::uint8 maxMipMaps = mNumMipMaps + 1; // Increase with one, because there is always one image to blit maxMipMaps = maxMipMaps > PAINT_MAX_MIP_MAPS ? PAINT_MAX_MIP_MAPS : maxMipMaps; // Just paint a few mipmaps (not all) Ogre::Image textureOnWhichIsPaintedScaled = mTextureOnWhichIsPainted; // Temporary image must be used, otherwise painting doesn't work size_t w = mTextureOnWhichIsPaintedWidth; size_t h = mTextureOnWhichIsPaintedHeight; Ogre::v1::HardwarePixelBuffer* buffer; for (Ogre::uint8 i = 0; i < maxMipMaps; ++i) { buffer = texture->getBuffer(0, i).getPointer(); buffer->blitFromMemory(textureOnWhichIsPaintedScaled.getPixelBox(0, 0), Ogre::Box(0, 0, 0, w, h, 1)); w*=0.5f; // Mipmaps always are half of the previous one h*=0.5f; if (w < 1.0f || h < 1.0f) break; // Stop when the mipmaps are too small textureOnWhichIsPaintedScaled.resize(w, h); } textureOnWhichIsPaintedScaled.freeMemory(); }
void Simple::addLightingPass(Ogre::Technique* technique, std::set<std::string>& managedTextures) const { Ogre::Pass* lightingPass = technique->createPass(); lightingPass->setSceneBlending(Ogre::SBT_MODULATE); lightingPass->setLightingEnabled(false); Ogre::TextureUnitState * textureUnitStateSplat = lightingPass->createTextureUnitState(); //we need an unique name for our alpha texture std::stringstream lightingTextureNameSS; lightingTextureNameSS << technique->getParent()->getName() << "_lighting"; const Ogre::String lightingTextureName(lightingTextureNameSS.str()); Ogre::TexturePtr texture = static_cast<Ogre::TexturePtr>(Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(lightingTextureName)); if (texture.isNull()) { texture = Ogre::Root::getSingletonPtr()->getTextureManager()->createManual(lightingTextureName, "General", Ogre::TEX_TYPE_2D, mPage.getBlendMapSize(), mPage.getBlendMapSize(), 1, Ogre::PF_L8, Ogre::TU_DYNAMIC_WRITE_ONLY); managedTextures.insert(texture->getName()); } Ogre::Image ogreImage; ogreImage.loadDynamicImage(const_cast<unsigned char*>(mLightingImage->getData()), mLightingImage->getResolution(), mLightingImage->getResolution(), 1, Ogre::PF_L8); texture->loadImage(ogreImage); //blit the whole image to the hardware buffer Ogre::PixelBox sourceBox(ogreImage.getPixelBox()); //blit for each mipmap for (unsigned int i = 0; i <= texture->getNumMipmaps(); ++i) { Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(texture->getBuffer(0, i)); hardwareBuffer->blitFromMemory(sourceBox); } textureUnitStateSplat->setTextureName(texture->getName()); textureUnitStateSplat->setTextureCoordSet(0); textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP); textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC); }