void SCRenderToTexture::SetPainter(const String &sValue) { if (m_sPainter != sValue) { m_sPainter = sValue; // Setup the surface painter if (m_pSurfaceTextureBuffer) { SurfacePainter *pSurfacePainter = GetSceneContext()->GetRendererContext().GetRenderer().CreateSurfacePainter(m_sPainter); m_pSurfaceTextureBuffer->SetPainter(pSurfacePainter); if (pSurfacePainter && pSurfacePainter->IsInstanceOf("PLScene::SPScene")) { // Do NOT let the renderer update this surface by default, WE update it inside DrawPre() m_pSurfaceTextureBuffer->SetActive(false); // THIS is the scene root :) SPScene *pPainter = static_cast<SPScene*>(pSurfacePainter); pPainter->SetRootContainer(this); // Tell the surface scene painter about the 'conrete scene' SceneNode *pSceneNode = GetByName(m_sSceneName); if (pSceneNode && pSceneNode->IsContainer()) pPainter->SetSceneContainer(static_cast<SceneContainer*>(pSceneNode)); else pPainter->SetSceneContainer(nullptr); // Set default scene renderer pPainter->SetDefaultSceneRenderer(m_sSceneRenderer); } } } }
/** * @brief * Sets the used scene renderer */ bool SceneRendererTool::SetSceneRenderer(SceneContainer *pSceneContainer, const String &sFilename, const String &sFallbackFilename) { // Is there a surface painter and is it an "SPScene"-instance? if (pSceneContainer && m_pSurfacePainter && m_pSurfacePainter->IsInstanceOf("PLScene::SPScene")) { // Get and setup the "SPScene"-instance of the surface painter SPScene *pSPScene = static_cast<SPScene*>(m_pSurfacePainter); pSPScene->SetRootContainer(pSceneContainer->GetContainer()); pSPScene->SetSceneContainer(pSceneContainer); // Check renderer API and version number, if legacy hardware is used we can only // use a quite primitive scene renderer! String sSceneRendererFilename = sFilename; { // [TODO] Detect required capabilities of a scene renderer? (important) // OpenGL uint32 nVersion = 0; if (m_pSurfacePainter->GetRenderer().GetAPI(&nVersion) == "OpenGL") { if (nVersion < 14) { sSceneRendererFilename = sFallbackFilename; PL_LOG(Warning, "Your graphics card is too old to support proper shader rendering. " "At least a OpenGL 1.4 compatible graphics card is recommended. A fallback fill be used.") } // OpenGL ES 2.0 } else if (m_pSurfacePainter->GetRenderer().GetAPI(&nVersion) == "OpenGL ES 2.0") {
void SCRenderToTexture::SetSceneName(const String &sValue) { if (m_sSceneName != sValue) { m_sSceneName = sValue; // Setup the surface painter if (m_pSurfaceTextureBuffer) { SurfacePainter *pSurfacePainter = m_pSurfaceTextureBuffer->GetPainter(); if (pSurfacePainter && pSurfacePainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pPainter = static_cast<SPScene*>(pSurfacePainter); SceneNode *pSceneNode = GetByName(m_sSceneName); if (pSceneNode && pSceneNode->IsContainer()) pPainter->SetSceneContainer(static_cast<SceneContainer*>(pSceneNode)); else pPainter->SetSceneContainer(nullptr); } } } }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application65::OnCreateScene(SceneContainer &cContainer) { // Create a scene node with the soldier mesh cContainer.Create("PLScene::SNMesh", "Soldier", "Position=\"0.0 -0.7 -4.0\" Scale=\"0.008 0.008 0.008\" Mesh=\"Data/Meshes/Soldier.mesh\""); // Create a nice particle effect behind the soldier cContainer.Create("PLParticleGroups::PGMagic2", "Magic2", "Position=\"0.0 0.0 -25.0\""); // Create a moving light source to illuminate the scene cContainer.Create("PLScene::SNPointLight", "Light", "Position=\"1.0 2.0 -2.0\" Flags=\"Flares|Corona|Blend\" Range=\"15.0\""); // Create a camera - this time we increase the camera FOV to get a better space feeling :) SceneNode *pCamera = cContainer.Create("PLScene::SNCamera", "FixedCamera", "Position=\"0.0 0.0 -2.5\" Rotation=\"0.0 180.0 0.0\" FOV=\"60\""); if (pCamera && pCamera->IsInstanceOf("PLScene::SNCamera")) { // Make this to our main scene camera SetCamera(reinterpret_cast<SNCamera*>(pCamera)); // Get class list of all available post process scene node modifiers m_lstModifierClasses.Clear(); ClassManager::GetInstance()->GetClasses(m_lstModifierClasses, "PLCompositing::SNMPostProcess", Recursive, NoBase, NoAbstract); // 'Activate' the first effect if (m_lstModifierClasses.GetNumOfElements()) pCamera->AddModifier(m_lstModifierClasses[m_nCurrentSelectedModifier]->GetClassName()); } // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(&cContainer); } // Within the parent container... SceneContainer *pContainer = cContainer.GetContainer(); if (pContainer) { // Add our information text scene nodes SceneNode *pInfoText = pContainer->Create("PLScene::SceneContainer", "InfoText", "Flags=\"NoCulling\""); if (pInfoText && pInfoText->IsInstanceOf("PLScene::SceneContainer")) { SceneContainer *pInfoTextContainer = static_cast<SceneContainer*>(pInfoText); pInfoTextContainer->Create("PLScene::SNText2D", '0', "Position=\"0.01 0.01\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("'F1' = Show/hide this help text") + '\"'); pInfoTextContainer->Create("PLScene::SNText2D", '1', "Position=\"0.01 0.03\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("'Space' = Enable/disable post processing") + '\"'); pInfoTextContainer->Create("PLScene::SNText2D", '2', "Position=\"0.01 0.05\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("'1-7' = Custom post process effects") + '\"'); pInfoTextContainer->Create("PLScene::SNText2D", '3', "Position=\"0.01 0.07\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("'Page up' = Next post process effect") + '\"'); pInfoTextContainer->Create("PLScene::SNText2D", '4', "Position=\"0.01 0.09\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("'Page down' = Previous post process effect") + '\"'); } } // Set scene container SetScene(&cContainer); }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application67::OnCreateScene(SceneContainer &cContainer) { // Create a scene container with our 'concrete sound scene' using the default sound API SceneNode *pSceneContainerNode = cContainer.Create("PLSound::SCSound", "SoundScene"); if (pSceneContainerNode && pSceneContainerNode->IsInstanceOf("PLScene::SceneContainer")) { SceneContainer *pSceneContainer = static_cast<SceneContainer*>(pSceneContainerNode); // Protect this important container! pSceneContainer->SetProtected(true); // Populate the scene container // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(pSceneContainer); // Get the scene context SceneContext *pSceneContext = GetSceneContext(); if (pSceneContext) { // Create us a scene renderer SceneRenderer *pSceneRenderer = pSceneContext->GetSceneRendererManager().Create("2DGame"); if (pSceneRenderer) { // Add begin scene renderer pass pSceneRenderer->Create("PLCompositing::SRPBegin", "Begin", "TextureFormat=\"R8G8B8A8\" Flags=\"Inactive\""); // Add our own scene renderer pass pSceneRenderer->Create("SRP2DGame", "2DGame"); // Add post processing scene renderer pass pSceneRenderer->Create("PLCompositing::SRPPostProcessing", "PostProcessing"); // Add end scene renderer pass pSceneRenderer->Create("PLCompositing::SRPEnd", "End"); // Make this scene renderer to the default scene renderer of our scene surface painter pSPScene->SetDefaultSceneRenderer(pSceneRenderer->GetName()); } } } // Set scene container SetScene(pSceneContainer); // Start the game Restart(); } }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application66::OnCreateScene(SceneContainer &cContainer) { // Set scene container flags cContainer.SetFlags(SceneNode::NoCulling); // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(&cContainer); } // Within the parent container... SceneContainer *pContainer = cContainer.GetContainer(); if (pContainer) { // Create a 'ingame'-GUI scene node const SNGui *pGuiSceneNode = static_cast<SNGui*>(pContainer->Create("PLFrontendPLGui::SNGui", "GUI")); if (pGuiSceneNode) { // Setup the GUI Gui *pGui = pGuiSceneNode->GetGui(); if (pGui) { // Create the GUI font if (!GuiFont) { GuiFont = new Font(*pGui); GuiFont->LoadFromFile("Data/Fonts/LinLibertine_Re-2.7.9.9.otf", 18); } // Set GUI options pGui->SetMouseVisible(false); // Create ingame GUI container m_pIngameGui = new IngameGui(*this, pGui->GetRootWidget()); m_pIngameGui->SetSize(Vector2i(1024, 768)); m_pIngameGui->SetBackgroundColor(PLGraphics::Color4::Transparent); m_pIngameGui->SetFocus(); m_pIngameGui->SetVisible(true); } } } // Set scene container SetScene(&cContainer); }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application70::OnCreateScene(SceneContainer &cContainer) { // Create a camera SceneNode *pCamera = cContainer.Create("PLScene::SNCamera", "FreeCamera", "Position=\"1 2 -3\" Rotation=\"25 210 0\""); if (pCamera && pCamera->IsInstanceOf("PLScene::SNCamera")) { // Make this to our main scene camera SetCamera(reinterpret_cast<SNCamera*>(pCamera)); // Add a controller modifier so we can look around the camera by using a default control pCamera->AddModifier("PLEngine::SNMEgoLookController"); // Add a controller modifier so we can move around the camera by using a default control pCamera->AddModifier("PLEngine::SNMMoveController"); } // Create the floor cContainer.Create("PLScene::SNMesh", "Floor", "Position=\"0 0 -5\" Scale=\"4 0.1 4\" Mesh=\"Default\""); // Create an instance of the fire particle effect scene node cContainer.Create("SNFireSample", "Fire", "Position=\"0.5 0.3 -5\" Scale=\"0.1 0.1 0.1\""); // Create an instance of the basic particle effect scene node cContainer.Create("SNBasicSample", "Basic", "Position=\"-0.5 0.1 -8\" Scale=\"0.5 0.5 0.5\""); // Create an instance of the gravitation particle effect scene node cContainer.Create("SNGravitationSample", "Gravitation", "Position=\"-1 1 -5\" Scale=\"0.5 0.5 0.5\""); // Create an instance of the galaxy particle effect scene node cContainer.Create("SNGalaxySample", "Galaxy", "Position=\"-3 0.5 -8\" Scale=\"0.5 0.5 0.5\""); // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(&cContainer); } // Set scene container SetScene(&cContainer); }
/** * @brief * Function that is called to create the application's scene container */ void EngineApplication::OnCreateScene(SceneContainer &cContainer) { // [TODO] Load 'm_sSceneFilename' if provided // Set scene container flags cContainer.SetFlags(SceneNode::NoCulling); // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(&cContainer); } // Configure scene and set the currently used application camera SetCamera(SceneCreator::ConfigureScene(cContainer, "PLEngine::SceneCreatorDefault")); // Set scene container SetScene(&cContainer); }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application64::OnCreateScene(SceneContainer &cContainer) { // Create a camera SceneNode *pCamera = cContainer.Create("PLScene::SNCamera", "FreeCamera", "Position=\"1 2 -3\" Rotation=\"25 210 0\""); if (pCamera && pCamera->IsInstanceOf("PLScene::SNCamera")) { // Make this to our main scene camera SetCamera(reinterpret_cast<SNCamera*>(pCamera)); } // Create a scene node with the soldier mesh - in debug mode, show some fancy technical visualizations SceneNode *pSceneNode = cContainer.Create("PLScene::SNMesh", "Soldier", "Position=\"0.0 0.1 -5.0\" Scale=\"0.008 0.008 0.008\" Mesh=\"Data/Meshes/Soldier.mesh\" DebugFlags=\"DebugShowWireframe|DebugShowJoints|DebugShowJointNames|DebugShowSkeleton\""); if (pSceneNode) { // Rotate the soldier pSceneNode->AddModifier("PLScene::SNMRotationLinearAnimation", "Velocity=\"0 10 0\""); // Playback the animation named "walk_0" letting the soldier walk pSceneNode->AddModifier("PLScene::SNMMeshAnimation", "Name=\"walk_0\""); // Animate the morph target named "blink" letting the soldier blink from time to time pSceneNode->AddModifier("PLScene::SNMMeshMorphBlink", "Name=\"blink\""); } // Create the floor cContainer.Create("PLScene::SNMesh", "Floor", "Position=\"0.0 0.0 -5.0\" Rotation=\"0.0 180.0 0.0\" Scale=\"4.0 0.1 4.0\" Mesh=\"Default\""); // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(&cContainer); } // Set scene container SetScene(&cContainer); // Create the picking component m_pMyPicking = new MyPicking(*this); }
//[-------------------------------------------------------] //[ Private virtual PLEngine::EngineApplication functions ] //[-------------------------------------------------------] void Application61::OnCreateScene(SceneContainer &cContainer) { // Set no scene container as default SetScene(nullptr); // Sound API given? if (m_sSoundAPI.GetLength()) { // Create a scene container with our 'concrete sound scene' using the chosen sound API SceneNode *pSceneContainerNode = cContainer.Create("PLSound::SCSound", "SoundScene", "SoundAPI=\"" + m_sSoundAPI + "\" Pitch=\"" + Timing::GetInstance()->GetTimeScaleFactor() + '\"'); if (pSceneContainerNode && pSceneContainerNode->IsInstanceOf("PLScene::SceneContainer")) { SceneContainer *pSceneContainer = static_cast<SceneContainer*>(pSceneContainerNode); // Protect this important container! pSceneContainer->SetProtected(true); // Set scene container SetScene(pSceneContainer); // Populate the scene container // Create a camera SceneNode *pCamera = pSceneContainer->Create("PLScene::SNCamera", "FreeCamera", "Position=\"0.0 -1.5 1.4\" Rotation=\"-14.0 180.0 0.0\""); if (pCamera && pCamera->IsInstanceOf("PLScene::SNCamera")) { // Make this to our main scene camera SetCamera(reinterpret_cast<SNCamera*>(pCamera)); // Add a controller modifier so we can look around the camera by using a default control pCamera->AddModifier("PLEngine::SNMEgoLookController"); // Add a controller modifier so we can move around the camera by using a default control pCamera->AddModifier("PLEngine::SNMMoveController", "Speed=\"2\""); // Make this camera to the 'sound listener' pSceneContainer->SetAttribute("Listener", pCamera->GetName()); } // Create the floor pSceneContainer->Create("PLScene::SNMesh", "Floor", "Position=\"0.0 -2.1 -5.0\" Rotation=\"0.0 180.0 0.0\" Scale=\"4.0 0.1 4.0\" Mesh=\"Default\""); // Create a box on the floor pSceneContainer->Create("PLScene::SNMesh", "Box", "Position=\"0.0 -1.5 -5.0\" Scale=\"0.5 0.5 0.5\" Mesh=\"Default\""); // Create rain particles and rain sound pSceneContainer->Create("PLParticleGroups::PGRain", "Rain", "Position=\"0.0 15.0 -5.0\" Flags=\"ForceUpdate\" MediumSize=\"3\""); pSceneContainer->Create("PLSound::SNSound", "RainSound", "Sound=\"Data/Sounds/Rain.ogg\" Volume=\"0.2\""); // Create the soldier walking in the rain :) SceneNode *pSoldier = pSceneContainer->Create("PLScene::SNMesh", "Soldier", "Position=\"0.0 -1.5 -5.0\" Scale=\"0.007 0.007 0.007\" Mesh=\"Data/Meshes/Soldier.mesh\""); if (pSoldier) { // Add animation modifier pSoldier->AddModifier("PLScene::SNMMeshAnimation", "Name=\"walk_0\" Speed=\"2\""); // Let the soldier walk on a path... pSoldier->AddModifier("PLScene::SNMPositionPath", "Filename=\"Data/Misc/61Sound_Soldier.path\" Speed=\"0.5\" Flags=\"NodeIndexProgress\" Interpolation=\"CatmullRomCurve\""); // ... and we should look into the direction he's moving pSoldier->AddModifier("PLScene::SNMRotationMoveDirection"); // Link a footsteps sound to the soldier pSoldier->AddModifier("PLSound::SNMSound","Sound=\"Data/Sounds/Walking.ogg\""); } // Setup scene surface painter SurfacePainter *pPainter = GetPainter(); if (pPainter && pPainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pSPScene = static_cast<SPScene*>(pPainter); pSPScene->SetRootContainer(cContainer.GetContainer()); pSPScene->SetSceneContainer(pSceneContainer); } // Within the parent container... SceneContainer *pContainer = pSceneContainer->GetContainer(); if (pContainer) { // Get/add our information text scene nodes SceneNode *pInfoText = pContainer->Create("PLScene::SceneContainer", "InfoText", "Flags=\"NoCulling\""); if (pInfoText && pInfoText->IsInstanceOf("PLScene::SceneContainer")) { SceneContainer *pInfoTextContainer = static_cast<SceneContainer*>(pInfoText); // The name of the used sound API pInfoTextContainer->Create("PLScene::SNText2D", "SoundAPI", "Position=\"0.01 0.01\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("Sound API: ") + GetSoundAPI() + '\"'); // Draw keys information pInfoTextContainer->Create("PLScene::SNText2D", "Keys", "Position=\"0.01 0.04\" Flags=\"No3DPosition|NoCenter\" Text=\"" + PLT("Keys:") + '\"'); pInfoTextContainer->Create("PLScene::SNText2D", "TimeScale", "Position=\"0.06 0.08\" Flags=\"No3DPosition|NoCenter\""); UpdateTimeScaleTextNode(); } } } } }
//[-------------------------------------------------------] //[ Public virtual SceneNode functions ] //[-------------------------------------------------------] void SCRenderToTexture::DrawPre(Renderer &cRenderer, const VisNode *pVisNode) { if (IsActive() && m_pSurfaceTextureBuffer) { // Call base implementation SceneContainer::DrawPre(cRenderer, pVisNode); // Check FPS limitation if (FPSLimit) { const uint64 nCurrentTime = System::GetInstance()->GetMilliseconds(); if (m_nFPSLimitLastTime && nCurrentTime-m_nFPSLimitLastTime < static_cast<uint64>(1000.0f/FPSLimit)) return; // Do not update m_nFPSLimitLastTime = nCurrentTime; } // Get the surface scene painter SurfacePainter *pSurfacePainter = m_pSurfaceTextureBuffer->GetPainter(); if (pSurfacePainter && pSurfacePainter->IsInstanceOf("PLScene::SPScene")) { SPScene *pPainter = static_cast<SPScene*>(pSurfacePainter); // Deactivate THIS node to avoid recursion SetActive(false); // Get current camera SNCamera *pCameraBackup = SNCamera::GetCamera(); // Set camera SceneNode *pSceneNode = GetByName(CameraName.Get()); if (pSceneNode && pSceneNode->IsCamera()) { // If the camera is not active, we do not need to do anything in here... if (!pSceneNode->IsActive()) return; pPainter->SetCamera(static_cast<SNCamera*>(pSceneNode)); static_cast<SNCamera*>(pSceneNode)->SetCamera(cRenderer); } else pPainter->SetCamera(nullptr); // Get current render target Surface *pSurfaceBackup = cRenderer.GetRenderTarget(); // [HACK] If the painter has no scene container, check if the scene container exists now... if (!pPainter->GetSceneContainer()) { pSceneNode = GetByName(m_sSceneName); if (pSceneNode && pSceneNode->IsContainer()) pPainter->SetSceneContainer(static_cast<SceneContainer*>(pSceneNode)); } // Check the render target type if (m_bCube) { // Render to cube texture // Setup the camera SNCamera *pCamera = pPainter->GetCamera(); if (pCamera) { // Set field of view and aspect pCamera->SetFOV(90.0f); pCamera->SetAspect(1.0f); // For each of the 6 cube faces... for (uint8 nFace=0; nFace<6; nFace++) { // Set rotation switch (nFace) { // x-positive case 0: pCamera->SetRotation(Vector3( 0.0f, -90.0f, 180.0f)); break; // x-negative case 1: pCamera->SetRotation(Vector3( 0.0f, 90.0f, 180.0f)); break; // y-positive case 2: pCamera->SetRotation(Vector3( 90.0f, 0.0f, 180.0f)); break; // y-negative case 3: pCamera->SetRotation(Vector3(-90.0f, 0.0f, 180.0f)); break; // z-positive case 4: pCamera->SetRotation(Vector3( 0.0f, 0.0f, 180.0f)); break; // z-negative case 5: pCamera->SetRotation(Vector3( 0.0f, 180.0f, 180.0f)); break; } // Set the new render target if (cRenderer.SetRenderTarget(m_pSurfaceTextureBuffer, nFace)) { // Draw a nice and colorful picture :) pPainter->OnPaint(*m_pSurfaceTextureBuffer); } } } else { // For each of the 6 cube faces... for (uint8 nFace=0; nFace<6; nFace++) { // Set the new render target if (cRenderer.SetRenderTarget(m_pSurfaceTextureBuffer, nFace)) { // Draw a nice and colorful picture :) pPainter->OnPaint(*m_pSurfaceTextureBuffer); } } } } else { // Render to 2D/rectangle texture // Set the new render target if (cRenderer.SetRenderTarget(m_pSurfaceTextureBuffer)) { // Draw a nice and colorful picture :) pPainter->OnPaint(*m_pSurfaceTextureBuffer); } } // Reset renderer target cRenderer.SetRenderTarget(pSurfaceBackup); if (pCameraBackup) { pPainter->SetCamera(pCameraBackup); pCameraBackup->SetCamera(cRenderer); } // Reactivate THIS node to avoid recursion SetActive(true); } } }
/** * @brief * Creates/recreates the texture surface */ void SCRenderToTexture::CreateSurfaceTexture() { // Get the renderer Renderer &cRenderer = GetSceneContext()->GetRendererContext().GetRenderer(); // Delete the old render to texture buffer surface if (m_pSurfaceTextureBuffer) { delete m_pSurfaceTextureBuffer; m_pSurfaceTextureBuffer = nullptr; } // Delete the old resulting texture Texture *pTexture = m_pTextureHandler->GetResource(); if (pTexture) { pTexture->Delete(); m_pTextureHandler->SetResource(nullptr); } // Get the desired texture buffer format TextureBuffer::EPixelFormat nFormat; switch (m_nFormat) { case 0: nFormat = TextureBuffer::R8G8B8; break; case 1: nFormat = TextureBuffer::R8G8B8A8; break; default: nFormat = TextureBuffer::R8G8B8A8; break; } // Create 'render to texture buffer' surface if (m_bCube) { m_pSurfaceTextureBuffer = cRenderer.CreateSurfaceTextureBufferCube(m_nWidth, nFormat, m_nSurfaceFlags); } else { // If possible, we use a standard 2D texture buffer if (cRenderer.GetCapabilities().bTextureBufferNonPowerOfTwo || (Math::IsPowerOfTwo(m_nWidth) && Math::IsPowerOfTwo(m_nHeight))) m_pSurfaceTextureBuffer = cRenderer.CreateSurfaceTextureBuffer2D(Vector2i(m_nWidth, m_nHeight), nFormat, m_nSurfaceFlags); else m_pSurfaceTextureBuffer = cRenderer.CreateSurfaceTextureBufferRectangle(Vector2i(m_nWidth, m_nHeight), nFormat, m_nSurfaceFlags); } if (m_pSurfaceTextureBuffer) { // Setup the surface painter SurfacePainter *pSurfacePainter = cRenderer.CreateSurfacePainter(m_sPainter); m_pSurfaceTextureBuffer->SetPainter(pSurfacePainter); if (pSurfacePainter && pSurfacePainter->IsInstanceOf("PLScene::SPScene")) { // Do NOT let the renderer update this surface by default, WE update it inside DrawPre() m_pSurfaceTextureBuffer->SetActive(false); // THIS is the scene root :) SPScene *pPainter = static_cast<SPScene*>(pSurfacePainter); pPainter->SetRootContainer(this); // Tell the surface scene painter about the 'conrete scene' SceneNode *pSceneNode = GetByName(m_sSceneName); pPainter->SetSceneContainer((pSceneNode && pSceneNode->IsContainer()) ? static_cast<SceneContainer*>(pSceneNode) : nullptr); // Set default scene renderer pPainter->SetDefaultSceneRenderer(m_sSceneRenderer); } } // Add the texture TextureManager &cTextureManager = cRenderer.GetRendererContext().GetTextureManager(); // If there's already a texture with this name we have to get another, still free resource name if (cTextureManager.GetByName(m_sTextureName)) { // Find an unused resource name String sName = m_sTextureName + "_0"; for (uint32 i=1; cTextureManager.GetByName(sName); i++) sName = m_sTextureName + '_' + static_cast<int>(i); // We have found an unused name m_sTextureName = sName; } if (m_pSurfaceTextureBuffer && m_pSurfaceTextureBuffer->GetTextureBuffer()) { pTexture = cTextureManager.CreateTexture(m_sTextureName, *m_pSurfaceTextureBuffer->GetTextureBuffer()); if (pTexture) m_sTextureName = pTexture->GetName(); m_pTextureHandler->SetResource(pTexture); } }