From 320587cd11ded2adeb8172becadfbc88f1fbaef8 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Sun, 21 Feb 2021 02:22:33 +0100 Subject: [PATCH] Main: allow creating cubic shadow textures --- OgreMain/include/OgreSceneManager.h | 5 +- OgreMain/src/OgreShadowRenderer.cpp | 84 ++++++++++++----------- OgreMain/src/OgreShadowTextureManager.cpp | 14 ++-- 3 files changed, 55 insertions(+), 48 deletions(-) diff --git a/OgreMain/include/OgreSceneManager.h b/OgreMain/include/OgreSceneManager.h index ece58df333a..31b69ea675d 100644 --- a/OgreMain/include/OgreSceneManager.h +++ b/OgreMain/include/OgreSceneManager.h @@ -63,13 +63,16 @@ namespace Ogre { /** Structure containing the configuration for one shadow texture. */ struct ShadowTextureConfig { + TextureType type; unsigned int width; unsigned int height; PixelFormat format; unsigned int fsaa; uint16 depthBufferPoolId; - ShadowTextureConfig() : width(512), height(512), format(PF_X8R8G8B8), fsaa(0), depthBufferPoolId(1) {} + ShadowTextureConfig() + : type(TEX_TYPE_2D), width(512), height(512), format(PF_X8R8G8B8), fsaa(0), depthBufferPoolId(1) + {} }; typedef std::vector ShadowTextureConfigList; diff --git a/OgreMain/src/OgreShadowRenderer.cpp b/OgreMain/src/OgreShadowRenderer.cpp index 5d588c39fd8..f2a11bd8a34 100644 --- a/OgreMain/src/OgreShadowRenderer.cpp +++ b/OgreMain/src/OgreShadowRenderer.cpp @@ -658,12 +658,6 @@ void SceneManager::ShadowRenderer::ensureShadowTexturesCreated() // Material names are global to SM, make specific String matName = shadowTex->getName() + "Mat" + mSceneManager->getName(); - RenderTexture *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); - - //Set appropriate depth buffer - if(!PixelUtil::isDepth(shadowRTT->suggestPixelFormat())) - shadowRTT->setDepthBufferPool( mShadowTextureConfigList[__i].depthBufferPoolId ); - // Create camera for this texture, but note that we have to rebind // in prepareShadowTextures to coexist with multiple SMs Camera* cam = mSceneManager->createCamera(camName); @@ -671,18 +665,25 @@ void SceneManager::ShadowRenderer::ensureShadowTexturesCreated() mSceneManager->getRootSceneNode()->createChildSceneNode(camName)->attachObject(cam); mShadowTextureCameras.push_back(cam); - // Create a viewport, if not there already - if (shadowRTT->getNumViewports() == 0) + for (size_t f = 0; f < shadowTex->getNumFaces(); f++) { - // Note camera assignment is transient when multiple SMs - Viewport *v = shadowRTT->addViewport(cam); - v->setClearEveryFrame(true); - // remove overlays - v->setOverlaysEnabled(false); - } + RenderTexture* shadowRTT = shadowTex->getBuffer(f)->getRenderTarget(); - // Don't update automatically - we'll do it when required - shadowRTT->setAutoUpdated(false); + // Set appropriate depth buffer + if (!PixelUtil::isDepth(shadowRTT->suggestPixelFormat())) + shadowRTT->setDepthBufferPool(mShadowTextureConfigList[__i].depthBufferPoolId); + // Create a viewport, if not there already + if (shadowRTT->getNumViewports() == 0) + { + // Note camera assignment is transient when multiple SMs + Viewport* v = shadowRTT->addViewport(cam); + v->setClearEveryFrame(true); + // remove overlays + v->setOverlaysEnabled(false); + } + // Don't update automatically - we'll do it when required + shadowRTT->setAutoUpdated(false); + } // Also create corresponding Material used for rendering this shadow MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); @@ -697,14 +698,13 @@ void SceneManager::ShadowRenderer::ensureShadowTexturesCreated() { mat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); // create texture unit referring to render target texture - TextureUnitState* texUnit = - p->createTextureUnitState(shadowTex->getName()); + TextureUnitState* texUnit = p->createTextureUnitState(); + texUnit->setTexture(shadowTex); // set projective based on camera texUnit->setProjectiveTexturing(!p->hasVertexProgram(), cam); // clamp to border colour texUnit->setSampler(mBorderSampler); mat->touch(); - } // insert dummy camera-light combination @@ -827,11 +827,7 @@ void SceneManager::ShadowRenderer::prepareShadowTextures(Camera* cam, Viewport* for (size_t j = 0; j < textureCountPerLight && si != siend; ++j) { TexturePtr &shadowTex = *si; - RenderTarget *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); - Viewport *shadowView = shadowRTT->getViewport(0); Camera *texCam = *ci; - // rebind camera, incase another SM in use which has switched to its cam - shadowView->setCamera(texCam); // Associate main view camera as LOD camera texCam->setLodCamera(cam); @@ -841,31 +837,39 @@ void SceneManager::ShadowRenderer::prepareShadowTextures(Camera* cam, Viewport* if (light->getType() != Light::LT_DIRECTIONAL) texCam->getParentSceneNode()->setPosition(light->getDerivedPosition()); - // Use the material scheme of the main viewport - // This is required to pick up the correct shadow_caster_material and similar properties. - shadowView->setMaterialScheme(vp->getMaterialScheme()); - - // Set the viewport visibility flags - shadowView->setVisibilityMask(vp->getVisibilityMask()); - // update shadow cam - light mapping ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( texCam ); assert(camLightIt != mShadowCamLightMapping.end()); camLightIt->second = light; - if (!light->getCustomShadowCameraSetup()) - mDefaultShadowCameraSetup->getShadowCamera(mSceneManager, cam, vp, light, texCam, j); - else - light->getCustomShadowCameraSetup()->getShadowCamera(mSceneManager, cam, vp, light, texCam, j); + for (size_t f = 0; f < shadowTex->getNumFaces(); f++) + { + RenderTarget *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); + Viewport *shadowView = shadowRTT->getViewport(0); + // rebind camera, incase another SM in use which has switched to its cam + shadowView->setCamera(texCam); + + // Use the material scheme of the main viewport + // This is required to pick up the correct shadow_caster_material and similar properties. + shadowView->setMaterialScheme(vp->getMaterialScheme()); - // Setup background colour - shadowView->setBackgroundColour(ColourValue::White); + // Set the viewport visibility flags + shadowView->setVisibilityMask(vp->getVisibilityMask()); - // Fire shadow caster update, callee can alter camera settings - mSceneManager->fireShadowTexturesPreCaster(light, texCam, j); + if (!light->getCustomShadowCameraSetup()) + mDefaultShadowCameraSetup->getShadowCamera(mSceneManager, cam, vp, light, texCam, j); + else + light->getCustomShadowCameraSetup()->getShadowCamera(mSceneManager, cam, vp, light, texCam, j); + + // Setup background colour + shadowView->setBackgroundColour(ColourValue::White); - // Update target - shadowRTT->update(); + // Fire shadow caster update, callee can alter camera settings + mSceneManager->fireShadowTexturesPreCaster(light, texCam, j + f); + + // Update target + shadowRTT->update(); + } ++si; // next shadow texture ++ci; // next camera diff --git a/OgreMain/src/OgreShadowTextureManager.cpp b/OgreMain/src/OgreShadowTextureManager.cpp index 357e5e8f13c..42ec84459bc 100644 --- a/OgreMain/src/OgreShadowTextureManager.cpp +++ b/OgreMain/src/OgreShadowTextureManager.cpp @@ -35,9 +35,10 @@ namespace Ogre //----------------------------------------------------------------------- bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) { - if ( lhs.width != rhs.width || + if (lhs.type != rhs.type || + lhs.width != rhs.width || lhs.height != rhs.height || - lhs.format != rhs.format ) + lhs.format != rhs.format) { return false; } @@ -88,8 +89,9 @@ namespace Ogre if (usedTextures.find(tex.get()) != usedTextures.end()) continue; - if (config.width == tex->getWidth() && config.height == tex->getHeight() - && config.format == tex->getFormat() && config.fsaa == tex->getFSAA()) + if (config.width == tex->getWidth() && config.height == tex->getHeight() && + config.format == tex->getFormat() && config.fsaa == tex->getFSAA() && + config.type == tex->getTextureType()) { // Ok, a match listToPopulate.push_back(tex); @@ -104,9 +106,7 @@ namespace Ogre static const String baseName = "Ogre/ShadowTexture"; String targName = baseName + StringConverter::toString(mCount++); TexturePtr shadowTex = TextureManager::getSingleton().createManual( - targName, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - TEX_TYPE_2D, config.width, config.height, 0, config.format, + targName, RGN_INTERNAL, config.type, config.width, config.height, 0, config.format, TU_RENDERTARGET, NULL, false, config.fsaa); // Ensure texture loaded shadowTex->load();