//[-------------------------------------------------------] //[ 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); } } }