Hi,
I'm trying to create a minimap with fog of war.
The minimap rendering is working, but if I also use fog of war texture. I get no error, but also I see nothing.
The theoretical approach is as follows:
- Create minimapTexture
- Create fogOfWarTexture
-> Render scene to minimapTexture
-> Use QUAD_PASS and material to blend the fogOfWarTexture over the miniMapTexture
-> UpdateFogOfWarTexture, to change the pixels, where the target SceneNode is located to discover the place.
This is my code:
Code: Select all
Ogre::String minimapTextureName = "MinimapRT";
this->minimapTexture = this->createMinimapTexture(minimapTextureName, 256, 256);
Ogre::String fogOfWarTextureName = "FogOfWarTexture";
this->fogOfWarTexture = this->createFogOfWarTexture(fogOfWarTextureName, 256, 256);
this->fogOfWarStagingTexture = this->textureManager->getStagingTexture(this->fogOfWarTexture->getWidth(), this->fogOfWarTexture->getHeight(), 1u, 1u, this->fogOfWarTexture->getPixelFormat());
Ogre::CompositorManager2* compositorManager = WorkspaceModule::getInstance()->getCompositorManager();
// Create minimap node
Ogre::CompositorNodeDef* nodeDef = compositorManager->addNodeDefinition("MinimapNode");
#if 1
Ogre::TextureDefinitionBase::TextureDefinition* texDef = nodeDef->addTextureDefinition("MinimapRT");
texDef->format = Ogre::PFG_RGBA8_UNORM_SRGB;
RenderTargetViewDef* rtv = nodeDef->addRenderTextureView("MinimapRT");
RenderTargetViewEntry attachment;
attachment.textureName = "MinimapRT";
rtv->colourAttachments.push_back(attachment);
#else
nodeDef->addTextureSourceName("MinimapRT", 0, Ogre::TextureDefinitionBase::TEXTURE_INPUT);
#endif
nodeDef->setNumTargetPass(2);
{
Ogre::CompositorTargetDef* targetDef = nodeDef->addTargetPass("MinimapRT");
targetDef->setNumPasses(1);
{
// Clear Pass
{
Ogre::CompositorPassSceneDef* passClear;
passClear = static_cast<Ogre::CompositorPassSceneDef*>(targetDef->addPass(Ogre::PASS_CLEAR));
passClear->mClearColour[0] = Ogre::ColourValue(0.2f, 0.4f, 0.6f);
// passClear->setAllStoreActions(Ogre::StoreAction::Store);
passClear->mStoreActionColour[0] = Ogre::StoreAction::Store;
passClear->mStoreActionDepth = Ogre::StoreAction::Store;
passClear->mStoreActionStencil = Ogre::StoreAction::Store;
}
{
// Scene pass for minimap
Ogre::CompositorPassSceneDef* passScene = static_cast<Ogre::CompositorPassSceneDef*>(
targetDef->addPass(Ogre::PASS_SCENE));
passScene->mCameraName = cameraCompPtr->getCamera()->getName();
passScene->setAllLoadActions(Ogre::LoadAction::Clear);
passScene->mClearColour[0] = Ogre::ColourValue::Black;
passScene->mStoreActionColour[0] = Ogre::StoreAction::StoreOrResolve;
passScene->mStoreActionDepth = Ogre::StoreAction::DontCare;
passScene->mStoreActionStencil = Ogre::StoreAction::DontCare;
passScene->mVisibilityMask = 0x00000001; // Custom mask for minimap objects
passScene->mIncludeOverlays = false;
}
}
}
nodeDef->mapOutputChannel(0, "MinimapRT");
// Create blending node
Ogre::CompositorNodeDef* nodeDef = compositorManager->addNodeDefinition("BlendingNode");
nodeDef->addTextureSourceName("MinimapRT", 0, Ogre::TextureDefinitionBase::TEXTURE_INPUT);
nodeDef->addTextureSourceName("FogOfWarTexture", 1, Ogre::TextureDefinitionBase::TEXTURE_INPUT);
nodeDef->setNumTargetPass(1);
{
Ogre::CompositorTargetDef* targetDef = nodeDef->addTargetPass("FogOfWarTexture");
targetDef->setNumPasses(1);
{
Ogre::CompositorPassQuadDef* quadPass = static_cast<Ogre::CompositorPassQuadDef*>(targetDef->addPass(Ogre::PASS_QUAD));
quadPass->mMaterialName = "Minimap/FogOfWar";
quadPass->addQuadTextureSource(0, "MinimapRT");
quadPass->addQuadTextureSource(1, "FogOfWarTexture");
}
}
nodeDef->mapOutputChannel(0, "FogOfWarTexture");
// Create workspace
this->minimapWorkspaceName = "MinimapWorkspaceWithFoW";
Ogre::CompositorWorkspaceDef* workspaceDef = compositorManager->addWorkspaceDefinition(this->minimapWorkspaceName);
workspaceDef->clearAllInterNodeConnections();
this->externalChannels.resize(1);
this->externalChannels[0] = this->minimapTexture;
this->workspace = compositorManager->addWorkspace(this->gameObjectPtr->getSceneManager(), this->externalChannels, cameraCompPtr->getCamera(), this->minimapWorkspaceName, true);
// Create MyGUI widget for the minimap
this->minimapWidget = MyGUI::Gui::getInstancePtr()->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0.0f, 0.0, 0.2f, 0.2f), MyGUI::Align::HCenter, "Overlapped");
minimapWidget->setImageTexture(this->minimapTexture->getNameStr());
// Update fog of war:
void MinimapComponent::updateFogOfWarTexture(const Ogre::Vector2& position, Ogre::Real radius)
{
this->fogOfWarStagingTexture->startMapRegion();
TextureBox texBox = this->fogOfWarStagingTexture->mapRegion(this->fogOfWarTexture->getWidth(), this->fogOfWarTexture->getHeight(), 1u, 1u, this->fogOfWarTexture->getPixelFormat());
// Assuming a 2D texture, the z-coordinate will be 0
size_t z = 0;
const size_t bytesPerPixel = texBox.bytesPerPixel;
for (uint32 y = 0; y < this->fogOfWarTexture->getHeight(); y++)
{
uint8* RESTRICT_ALIAS pixBoxData = reinterpret_cast<uint8 * RESTRICT_ALIAS>(texBox.at(0, y, 0));
for (uint32 x = 0; x < this->fogOfWarTexture->getWidth(); x++)
{
float dx = x - position.x;
float dy = y - position.y;
float distance = sqrt(dx * dx + dy * dy);
if (distance < radius)
{
const size_t dstIdx = x * bytesPerPixel;
float rgba[4];
// Create blank texture without details
rgba[0] = 1.0f;
rgba[1] = 1.0f;
rgba[2] = 1.0f;
rgba[3] = 1.0f;
PixelFormatGpuUtils::packColour(rgba, this->fogOfWarTexture->getPixelFormat(), &pixBoxData[dstIdx]);
}
else
{
const size_t dstIdx = x * bytesPerPixel;
float rgba[4];
// Create blank texture without details
rgba[0] = 1.0f;
rgba[1] = 0.0f;
rgba[2] = 0.0f;
rgba[3] = 0.0f;
PixelFormatGpuUtils::packColour(rgba, this->fogOfWarTexture->getPixelFormat(), &pixBoxData[dstIdx]);
}
}
}
this->fogOfWarStagingTexture->stopMapRegion();
this->fogOfWarStagingTexture->upload(texBox, this->fogOfWarTexture, 0, 0, 0);
this->fogOfWarTexture->notifyDataIsReady();
this->workspace->_validateFinalTarget();
this->workspace->_beginUpdate(true);
this->workspace->_update();
this->workspace->_endUpdate(true);
}
// My Material Minimap/FogOfWar:
// GLSL shaders
fragment_program FogOfWarPostprocess_fp_GLSL glsl
{
source FogOfWarBlend_fp.glsl
default_params
{
param_named backgroundMap int 0
}
}
// HLSL shaders
fragment_program FogOfWarPostprocess_fp_HLSL hlsl
{
source FogOfWar_fp.hlsl
entry_point main
target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3
}
fragment_program FogOfWar_fp unified
{
delegate FogOfWarPostprocess_fp_HLSL
delegate FogOfWarPostprocess_fp_GLSL
}
material Minimap/FogOfWar
{
technique
{
pass
{
vertex_program_ref Ogre/Compositor/Quad_vs
{
}
// Use a custom shader for the fog of war blending
fragment_program_ref FogOfWar_fp
{
param_named MinimapRT int 0
param_named FogOfWarTexture int 1
}
// Set the minimap texture
texture_unit
{
texture MinimapRT
}
// Set the fog of war texture
texture_unit
{
texture FogOfWarTexture
}
}
}
}
// My Shader: FogOfWar_fp.hlsl
Texture2D MinimapRT : register(t0);
Texture2D FogOfWarTexture : register(t1);
SamplerState samLinear : register(s0);
struct PS_INPUT
{
float4 Position : SV_POSITION;
float2 UV : TEXCOORD0;
};
float4 main(PS_INPUT input) : SV_TARGET
{
float4 minimapColor = MinimapRT.Sample(samLinear, input.UV);
float4 fogColor = FogOfWarTexture.Sample(samLinear, input.UV);
return minimapColor * fogColor;
}
Mayby somebody sees what is going wrong here. I'm not sure how those textures can be handled in Ogre correctly.
Best Regards
Lax