diff --git a/Samples/Media/materials/programs/GLSL/SampleLib_InstancedViewports.glsl b/Samples/Media/materials/programs/GLSL/SampleLib_InstancedViewports.glsl index a4b0bba84df..8d36ce34b48 100644 --- a/Samples/Media/materials/programs/GLSL/SampleLib_InstancedViewports.glsl +++ b/Samples/Media/materials/programs/GLSL/SampleLib_InstancedViewports.glsl @@ -29,36 +29,22 @@ furnished to do so, subject to the following conditions: // Transform the output position to the current "monitor" //----------------------------------------------------------------------------- +#ifdef OGRE_VERTEX_SHADER void SGX_InstancedViewportsTransform( in vec4 i_position, - in mat4 i_worldViewMatrix, - in mat4 i_projectionMatrix, - in vec4 i_viewportOffsetMatrixR0, - in vec4 i_viewportOffsetMatrixR1, - in vec4 i_viewportOffsetMatrixR2, - in vec4 i_viewportOffsetMatrixR3, - in vec2 i_monitorsCount, + in mat4 viewportOffsetArray[NUM_MONITORS], in vec4 i_monitorIndex, out vec4 o_position) { - o_position = mul(i_worldViewMatrix, i_position); - mat4 viewportOffset = mtxFromRows(i_viewportOffsetMatrixR0, - i_viewportOffsetMatrixR1, - i_viewportOffsetMatrixR2, - i_viewportOffsetMatrixR3); - - o_position = mul(viewportOffset, o_position); - o_position = mul(i_projectionMatrix, o_position); - - vec2 monitorIndexNorm = i_monitorIndex.xy - ((i_monitorsCount - 1.0)/2.0); - o_position.xy = - (o_position.xy + (o_position.w * monitorIndexNorm)*2.0) / i_monitorsCount; + mat4 viewportOffset = viewportOffsetArray[int(i_monitorIndex.z)]; + o_position = mul(viewportOffset, i_position); } +#endif //----------------------------------------------------------------------------- // Discard any pixel that is outside the bounds of the current "monitor" //----------------------------------------------------------------------------- - +#ifdef OGRE_FRAGMENT_SHADER void SGX_InstancedViewportsDiscardOutOfBounds( in vec2 i_monitorsCount, in vec4 i_monitorIndex, @@ -72,8 +58,8 @@ void SGX_InstancedViewportsDiscardOutOfBounds( float maxM = max(boxedXY.x,boxedXY.y); if (maxM >= 0.5) { -#ifdef OGRE_FRAGMENT_SHADER + discard; -#endif } } +#endif \ No newline at end of file diff --git a/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h b/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h index d14bf653a0b..41d77927452 100644 --- a/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h +++ b/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h @@ -82,66 +82,22 @@ class ShaderExInstancedViewports : public SubRenderState /** Set the monitors count. */ void setMonitorsCount (const Vector2 monitorsCount); - - /** Return the monitors count. */ - Vector2 getMonitorsCount () const { return mMonitorsCount; } + + void setParameter(const String& name, const Any& value) override; static String Type; // Protected methods. protected: - + bool createCpuSubPrograms(ProgramSet* programSet) override; - /** - @see SubRenderState::resolveParameters. - */ - bool resolveParameters (ProgramSet* programSet) override; + UniformParameterPtr mPSInMonitorsCount; + UniformParameterPtr mVSInMatrixArray; - /** - @see SubRenderState::resolveDependencies. - */ - bool resolveDependencies (ProgramSet* programSet) override; - - /** - @see SubRenderState::addFunctionInvocations. - */ - bool addFunctionInvocations (ProgramSet* programSet) override; - - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocations (Function* vsMain, const int groupOrder); - - - /** - Internal method that adds related pixel shader functions invocations. - */ - bool addPSInvocations (Function* psMain, const int groupOrder); - - -// Attributes. -protected: - ParameterPtr mVSInPosition; // Vertex shader original input position in projective space. - ParameterPtr mVSOriginalOutPositionProjectiveSpace; // Vertex shader original output position in projective space. - ParameterPtr mVSOutPositionProjectiveSpace; // Vertex shader output texcord position in projective space. - ParameterPtr mPSInPositionProjectiveSpace; // Pixel shader input position in projective space. - UniformParameterPtr mVSInMonitorsCount; // Vertex shader uniform monitors count. - UniformParameterPtr mPSInMonitorsCount; // Pixel shader uniform monitors count. - ParameterPtr mVSInMonitorIndex; // Vertex shader uniform monitor index. - ParameterPtr mVSOutMonitorIndex; // Vertex shader output monitor index. - ParameterPtr mPSInMonitorIndex; // Pixel shader input monitor index. - - ParameterPtr mVSInViewportOffsetMatrixR0; - ParameterPtr mVSInViewportOffsetMatrixR1; - ParameterPtr mVSInViewportOffsetMatrixR2; - ParameterPtr mVSInViewportOffsetMatrixR3; - - UniformParameterPtr mWorldViewMatrix; // world & view parameter. - UniformParameterPtr mProjectionMatrix; // projection parameter. - - Vector2 mMonitorsCount; + Vector2 mViewportGrid; bool mMonitorsCountChanged; + std::vector mCameras; }; diff --git a/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp b/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp index c6715648f2f..722e43956a6 100644 --- a/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp +++ b/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp @@ -44,16 +44,10 @@ namespace RTShader { /************************************************************************/ String ShaderExInstancedViewports::Type = "SGX_InstancedViewports"; -//----------------------------------------------------------------------- -#define SGX_LIB_INSTANCED_VIEWPORTS "SampleLib_InstancedViewports" -#define SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM "SGX_InstancedViewportsTransform" -#define SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS "SGX_InstancedViewportsDiscardOutOfBounds" - - //----------------------------------------------------------------------- ShaderExInstancedViewports::ShaderExInstancedViewports() { - mMonitorsCount = Vector2(1.0, 1.0); + mViewportGrid = Vector2(1.0, 1.0); mMonitorsCountChanged = true; mOwnsGlobalData = false; } @@ -78,188 +72,132 @@ void ShaderExInstancedViewports::copyFrom(const SubRenderState& rhs) const ShaderExInstancedViewports& rhsInstancedViewports = static_cast(rhs); // Copy all settings that affect this sub render state output code. - mMonitorsCount = rhsInstancedViewports.mMonitorsCount; + mViewportGrid = rhsInstancedViewports.mViewportGrid; mMonitorsCountChanged = rhsInstancedViewports.mMonitorsCountChanged; + mCameras = rhsInstancedViewports.mCameras; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::preAddToRenderState( const RenderState* renderState, Pass* srcPass, Pass* dstPass ) { auto matname = srcPass->getParent()->getParent()->getName(); - return matname.find("SdkTrays") == String::npos && matname.find("Instancing") == String::npos; + return matname.find("SdkTrays") == String::npos && matname.find("Instancing") == String::npos && matname.find("ImGui") == String::npos; } //----------------------------------------------------------------------- -bool ShaderExInstancedViewports::resolveParameters(ProgramSet* programSet) + +bool ShaderExInstancedViewports::createCpuSubPrograms(ProgramSet* programSet) { + OgreAssert(mCameras.size() == mViewportGrid.x * mViewportGrid.y, + "Number of cameras must match the number of viewports"); + Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Resolve vertex shader output position in projective space. - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPC_POSITION_OBJECT_SPACE); + bool isHLSL = ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl"; - mVSOriginalOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPC_POSITION_PROJECTIVE_SPACE); + if (isHLSL) + { + // set hlsl shader to use row-major matrices instead of column-major. + vsProgram->setUseColumnMajorMatrices(false); + } -#define SPC_POSITION_PROJECTIVE_SPACE_AS_TEXCORD (Parameter::SPC_CUSTOM_CONTENT_BEGIN + 1) + int numMonitors = mViewportGrid.x * mViewportGrid.y; + vsProgram->addPreprocessorDefines(StringUtil::format("NUM_MONITORS=%d", numMonitors)); - mVSOutPositionProjectiveSpace = vsMain->resolveOutputParameter(SPC_POSITION_PROJECTIVE_SPACE_AS_TEXCORD, GCT_FLOAT4); + vsProgram->addDependency("SampleLib_InstancedViewports"); + psProgram->addDependency("SampleLib_InstancedViewports"); - // Resolve ps input position in projective space. - mPSInPositionProjectiveSpace = psMain->resolveInputParameter(mVSOutPositionProjectiveSpace); - // Resolve vertex shader uniform monitors count - mVSInMonitorsCount = vsProgram->resolveParameter(GCT_FLOAT2, "monitorsCount"); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); - // Resolve pixel shader uniform monitors count mPSInMonitorsCount = psProgram->resolveParameter(GCT_FLOAT2, "monitorsCount"); + mVSInMatrixArray = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, GPV_GLOBAL, "matrixArray", numMonitors); + // Resolve vertex shader output position in projective space. + auto positionIn = vsMain->resolveInputParameter(Parameter::SPC_POSITION_OBJECT_SPACE); + auto vsInMonitorIndex = vsMain->resolveInputParameter(Parameter::SPC_TEXTURE_COORDINATE1, GCT_FLOAT4); - // Resolve the current world & view matrices concatenated - mWorldViewMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_WORLDVIEW_MATRIX); - - // Resolve the current projection matrix - mProjectionMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_PROJECTION_MATRIX); - - -#define SPC_MONITOR_INDEX Parameter::SPC_TEXTURE_COORDINATE1 - // Resolve vertex shader monitor index - mVSInMonitorIndex = vsMain->resolveInputParameter(SPC_MONITOR_INDEX, GCT_FLOAT4); - -#define SPC_MATRIX_R0 Parameter::SPC_TEXTURE_COORDINATE2 -#define SPC_MATRIX_R1 Parameter::SPC_TEXTURE_COORDINATE3 -#define SPC_MATRIX_R2 Parameter::SPC_TEXTURE_COORDINATE4 -#define SPC_MATRIX_R3 Parameter::SPC_TEXTURE_COORDINATE5 - - // Resolve vertex shader viewport offset matrix - mVSInViewportOffsetMatrixR0 = vsMain->resolveInputParameter(SPC_MATRIX_R0, GCT_FLOAT4); - mVSInViewportOffsetMatrixR1 = vsMain->resolveInputParameter(SPC_MATRIX_R1, GCT_FLOAT4); - mVSInViewportOffsetMatrixR2 = vsMain->resolveInputParameter(SPC_MATRIX_R2, GCT_FLOAT4); - mVSInViewportOffsetMatrixR3 = vsMain->resolveInputParameter(SPC_MATRIX_R3, GCT_FLOAT4); + auto originalOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPC_POSITION_PROJECTIVE_SPACE); + auto vsOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPC_CUSTOM_CONTENT_BEGIN + 1, GCT_FLOAT4); + auto vsOutMonitorIndex = vsMain->resolveOutputParameter(Parameter::SPC_TEXTURE_COORDINATE1, GCT_FLOAT4); - - // Resolve vertex shader output monitor index. - mVSOutMonitorIndex = vsMain->resolveOutputParameter(SPC_MONITOR_INDEX, GCT_FLOAT4); + // Add vertex shader invocations. + auto vstage = vsMain->getStage(FFP_VS_TRANSFORM + 1); + vstage.callFunction("SGX_InstancedViewportsTransform", {In(positionIn), In(mVSInMatrixArray), In(vsInMonitorIndex), + Out(originalOutPositionProjectiveSpace)}); + // Output position in projective space. + vstage.assign(originalOutPositionProjectiveSpace, vsOutPositionProjectiveSpace); + // Output monitor index. + vstage.assign(vsInMonitorIndex, vsOutMonitorIndex); - // Resolve ps input monitor index. - mPSInMonitorIndex = psMain->resolveInputParameter(mVSOutMonitorIndex); + // Add pixel shader invocations. + auto psInMonitorIndex = psMain->resolveInputParameter(vsOutMonitorIndex); + auto psInPositionProjectiveSpace = psMain->resolveInputParameter(vsOutPositionProjectiveSpace); + auto fstage = psMain->getStage(FFP_PS_PRE_PROCESS + 1); + fstage.callFunction("SGX_InstancedViewportsDiscardOutOfBounds", + {In(mPSInMonitorsCount), In(psInMonitorIndex), In(psInPositionProjectiveSpace)}); return true; } //----------------------------------------------------------------------- -bool ShaderExInstancedViewports::resolveDependencies(ProgramSet* programSet) +void ShaderExInstancedViewports::updateGpuProgramsParams(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { - Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); - Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM); + if (mMonitorsCountChanged) + { + mPSInMonitorsCount->setGpuParameter(mViewportGrid); - vsProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); + mMonitorsCountChanged = false; + } - psProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); - - return true; -} + Matrix4 shift = Matrix4::IDENTITY; + shift.setScale(Vector3(1./mViewportGrid[0], 1./mViewportGrid[1], 1)); + std::vector matrixArray; + Vector2 monitorCount = mViewportGrid; -//----------------------------------------------------------------------- -bool ShaderExInstancedViewports::addFunctionInvocations(ProgramSet* programSet) -{ - Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Add vertex shader invocations. - if (false == addVSInvocations(vsMain, FFP_VS_TRANSFORM + 1)) - return false; + int camIdx = 0; + for (int x = 0 ; x < monitorCount.x ; x++) + for (int y = 0 ; y < monitorCount.y ; y++) + { + auto cam = mCameras[camIdx++]; + auto worldViewMatrix = source->getViewMatrix(cam) * source->getWorldMatrix(); + auto projectionMatrix = source->getProjectionMatrix(cam); + shift.setTrans(Vector3((2*x - 1)/monitorCount[0], (2*y - 1)/monitorCount[1], 0)); + matrixArray.push_back(shift * projectionMatrix * worldViewMatrix); + } - // Add pixel shader invocations. - if (false == addPSInvocations(psMain, FFP_PS_PRE_PROCESS + 1)) - return false; - - return true; + // Update the matrix array + mVSInMatrixArray->setGpuParameter((Real*)matrixArray.data(), matrixArray.size(), 16); } - //----------------------------------------------------------------------- -bool ShaderExInstancedViewports::addVSInvocations( Function* vsMain, const int groupOrder ) -{ - FunctionAtom* funcInvocation = NULL; - - funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM, groupOrder); - funcInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - funcInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mProjectionMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInViewportOffsetMatrixR0, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInViewportOffsetMatrixR1, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInViewportOffsetMatrixR2, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInViewportOffsetMatrixR3, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInMonitorsCount, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - - // Output position in projective space. - funcInvocation = OGRE_NEW AssignmentAtom( groupOrder); - funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOutPositionProjectiveSpace, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - // Output monitor index. - funcInvocation = OGRE_NEW AssignmentAtom( groupOrder); - funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOutMonitorIndex, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - - return true; -} - -//----------------------------------------------------------------------- -bool ShaderExInstancedViewports::addPSInvocations( Function* psMain, const int groupOrder ) +void ShaderExInstancedViewports::setParameter(const String& name, const Any& value) { - FunctionInvocation* funcInvocation = NULL; - - funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS, groupOrder); - funcInvocation->pushOperand(mPSInMonitorsCount, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInMonitorIndex, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInPositionProjectiveSpace, Operand::OPS_IN); - - psMain->addAtomInstance(funcInvocation); + if (name == "viewportGrid") + { + setMonitorsCount(any_cast(value)); + return; + } - return true; -} -//----------------------------------------------------------------------- -void ShaderExInstancedViewports::updateGpuProgramsParams(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) -{ - if (mMonitorsCountChanged) + if (name == "cameras") { - mVSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); - mPSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); + mCameras = any_cast>(value); + return; + } - mMonitorsCountChanged = false; - } + SubRenderState::setParameter(name, value); } -//----------------------------------------------------------------------- + void ShaderExInstancedViewports::setMonitorsCount( const Vector2 monitorCount ) { - mMonitorsCount = monitorCount; + mViewportGrid = monitorCount; mMonitorsCountChanged = true; Ogre::VertexDeclaration* vertexDeclaration = Ogre::HardwareBufferManager::getSingleton().createVertexDeclaration(); - size_t offset = 0; - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 1); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 2); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 3); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 4); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 5); + vertexDeclaration->addElement(0, 0, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 1); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( @@ -267,41 +205,12 @@ void ShaderExInstancedViewports::setMonitorsCount( const Vector2 monitorCount ) vbuf->setInstanceDataStepRate(1); vbuf->setIsInstanceData(true); - float * buf = (float *)vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD); + Vector4f* buf = (Vector4f *)vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD); + int i = 0; for (int x = 0 ; x < monitorCount.x ; x++) for (int y = 0 ; y < monitorCount.y ; y++) { - *buf = x; buf++; - *buf = y; buf++; - *buf = 0; buf++; - *buf = 0; buf++; - - Ogre::Quaternion q; - Ogre::Radian angle = Ogre::Degree(90 / ( monitorCount.x * monitorCount.y) * (x + y * monitorCount.x) ); - q.FromAngleAxis(angle,Ogre::Vector3::UNIT_Y); - q.normalise(); - Ogre::Matrix3 rotMat; - q.ToRotationMatrix(rotMat); - - *buf = rotMat.GetColumn(0).x; buf++; - *buf = rotMat.GetColumn(0).y; buf++; - *buf = rotMat.GetColumn(0).z; buf++; - *buf = x * -20; buf++; - - *buf = rotMat.GetColumn(1).x; buf++; - *buf = rotMat.GetColumn(1).y; buf++; - *buf = rotMat.GetColumn(1).z; buf++; - *buf = 0; buf++; - - *buf = rotMat.GetColumn(2).x; buf++; - *buf = rotMat.GetColumn(2).y; buf++; - *buf = rotMat.GetColumn(2).z; buf++; - *buf = y * 20; buf++; - - *buf = 0; buf++; - *buf = 0; buf++; - *buf = 0; buf++; - *buf = 1; buf++; + *buf++ = Vector4f(x, y, i++, 0); } vbuf->unlock(); diff --git a/Samples/ShaderSystem/src/ShaderSystem.cpp b/Samples/ShaderSystem/src/ShaderSystem.cpp index e7a0fd29b5a..2a183e52ab4 100644 --- a/Samples/ShaderSystem/src/ShaderSystem.cpp +++ b/Samples/ShaderSystem/src/ShaderSystem.cpp @@ -1072,6 +1072,10 @@ void Sample_ShaderSystem::destroyInstancedViewports() destroyInstancedViewportsFactory(); + for (int i = 0; i < 3; i++) + { + mSceneMgr->destroyCamera(StringUtil::format("InstancedCamera%d", i)); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::destroyInstancedViewportsFactory() @@ -1094,17 +1098,30 @@ void Sample_ShaderSystem::createInstancedViewports() mShaderGenerator->addSubRenderStateFactory(mInstancedViewportsFactory); } - Ogre::Vector2 monitorCount(2.0, 2.0); - mInstancedViewportsSubRenderState = mShaderGenerator->createSubRenderState(); - Ogre::RTShader::ShaderExInstancedViewports* shaderExInstancedViewports - = static_cast(mInstancedViewportsSubRenderState); - shaderExInstancedViewports->setMonitorsCount(monitorCount); + if (Root::getSingletonPtr()->getRenderSystem()->getName().find("Direct3D9") != String::npos) + { + mSceneMgr->getManualObject("TextureAtlasObject")->getParentSceneNode()->setVisible(false); + mSceneMgr->setSkyBox(false, ""); + } + + std::vector cameras = {mCamera}; + for (int i = 0; i < 3; i++) + { + auto cam = mSceneMgr->createCamera(StringUtil::format("InstancedCamera%d", i)); + auto node = mCamera->getParentSceneNode()->createChildSceneNode(); + node->yaw(Degree(i * 90 - 45)); + node->attachObject(cam); + cameras.push_back(cam); + } + + mInstancedViewportsSubRenderState = mShaderGenerator->createSubRenderState("SGX_InstancedViewports"); + mInstancedViewportsSubRenderState->setParameter("viewportGrid", Vector2(2, 2)); + mInstancedViewportsSubRenderState->setParameter("cameras", cameras); Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::MSN_SHADERGEN); renderState->addTemplateSubRenderState(mInstancedViewportsSubRenderState); // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. mShaderGenerator->invalidateScheme(Ogre::MSN_SHADERGEN); - mShaderGenerator->validateScheme(Ogre::MSN_SHADERGEN); } void Sample_ShaderSystem::createMaterialForTexture( const String & texName, bool isTextureAtlasTexture )