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