void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone ) { PROFILE_SCOPE( SceneGraph_renderScene ); // Get the lights for rendering the scene. PROFILE_START( SceneGraph_registerLights ); LIGHTMGR->registerGlobalLights( &renderState->getFrustum(), false ); PROFILE_END(); // If its a diffuse pass, update the current ambient light level. // To do that find the starting zone and determine whether it has a custom // ambient light color. If so, pass it on to the ambient light manager. // If not, use the ambient light color of the sunlight. // // Note that we retain the starting zone information here and pass it // on to renderSceneNoLights so that we don't need to look it up twice. if( renderState->isDiffusePass() ) { if( !baseObject && getZoneManager() ) { getZoneManager()->findZone( renderState->getCameraPosition(), baseObject, baseZone ); AssertFatal( baseObject != NULL, "SceneManager::renderScene - findZone() did not return an object" ); } ColorF zoneAmbient; if( baseObject && baseObject->getZoneAmbientLightColor( baseZone, zoneAmbient ) ) mAmbientLightColor.setTargetValue( zoneAmbient ); else { const LightInfo* sunlight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType ); if( sunlight ) mAmbientLightColor.setTargetValue( sunlight->getAmbient() ); } renderState->setAmbientLightColor( mAmbientLightColor.getCurrentValue() ); } // Trigger the pre-render signal. PROFILE_START( SceneGraph_preRenderSignal); mCurrentRenderState = renderState; getPreRenderSignal().trigger( this, renderState ); mCurrentRenderState = NULL; PROFILE_END(); // Render the scene. if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide) { // Store previous values RectI originalVP = GFX->getViewport(); MatrixF originalWorld = GFX->getWorldMatrix(); Point2F projOffset = GFX->getCurrentProjectionOffset(); Point3F eyeOffset = GFX->getStereoEyeOffset(); // Render left half of display RectI leftVP = originalVP; leftVP.extent.x *= 0.5; GFX->setViewport(leftVP); MatrixF leftWorldTrans(true); leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z)); MatrixF leftWorld(originalWorld); leftWorld.mulL(leftWorldTrans); GFX->setWorldMatrix(leftWorld); Frustum gfxFrustum = GFX->getFrustum(); gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y)); GFX->setFrustum(gfxFrustum); SceneCameraState cameraStateLeft = SceneCameraState::fromGFX(); SceneRenderState renderStateLeft( this, renderState->getScenePassType(), cameraStateLeft ); renderStateLeft.setSceneRenderStyle(SRS_SideBySide); renderStateLeft.setSceneRenderField(0); renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone ); // Render right half of display RectI rightVP = originalVP; rightVP.extent.x *= 0.5; rightVP.point.x += rightVP.extent.x; GFX->setViewport(rightVP); MatrixF rightWorldTrans(true); rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z)); MatrixF rightWorld(originalWorld); rightWorld.mulL(rightWorldTrans); GFX->setWorldMatrix(rightWorld); gfxFrustum = GFX->getFrustum(); gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y)); GFX->setFrustum(gfxFrustum); SceneCameraState cameraStateRight = SceneCameraState::fromGFX(); SceneRenderState renderStateRight( this, renderState->getScenePassType(), cameraStateRight ); renderStateRight.setSceneRenderStyle(SRS_SideBySide); renderStateRight.setSceneRenderField(1); renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone ); // Restore previous values GFX->setWorldMatrix(originalWorld); gfxFrustum.clearProjectionOffset(); GFX->setFrustum(gfxFrustum); GFX->setViewport(originalVP); } else { renderSceneNoLights( renderState, objectMask, baseObject, baseZone ); } // Trigger the post-render signal. PROFILE_START( SceneGraphRender_postRenderSignal ); mCurrentRenderState = renderState; getPostRenderSignal().trigger( this, renderState ); mCurrentRenderState = NULL; PROFILE_END(); // Remove the previously registered lights. PROFILE_START( SceneGraph_unregisterLights); LIGHTMGR->unregisterAllLights(); PROFILE_END(); }
void PlaneReflector::updateReflection( const ReflectParams ¶ms ) { PROFILE_SCOPE(PlaneReflector_updateReflection); GFXDEBUGEVENT_SCOPE( PlaneReflector_updateReflection, ColorI::WHITE ); mIsRendering = true; S32 texDim = mDesc->texSize; texDim = getMax( texDim, 32 ); // Protect against the reflection texture being bigger // than the current game back buffer. texDim = getMin( texDim, params.viewportExtent.x ); texDim = getMin( texDim, params.viewportExtent.y ); bool texResize = ( texDim != mLastTexSize ); mLastTexSize = texDim; const Point2I texSize( texDim, texDim ); if ( texResize || reflectTex.isNull() || reflectTex->getFormat() != REFLECTMGR->getReflectFormat() ) reflectTex = REFLECTMGR->allocRenderTarget( texSize ); GFXTexHandle depthBuff = LightShadowMap::_getDepthTarget( texSize.x, texSize.y ); // store current matrices GFXTransformSaver saver; Point2I viewport(params.viewportExtent); if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide) { viewport.x *= 0.5f; } F32 aspectRatio = F32( viewport.x ) / F32( viewport.y ); Frustum frustum; frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane); // Manipulate the frustum for tiled screenshots const bool screenShotMode = gScreenShot && gScreenShot->isPending(); if ( screenShotMode ) gScreenShot->tileFrustum( frustum ); GFX->setFrustum( frustum ); // Store the last view info for scoring. mLastDir = params.query->cameraMatrix.getForwardVector(); mLastPos = params.query->cameraMatrix.getPosition(); setGFXMatrices( params.query->cameraMatrix ); // Adjust the detail amount F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust; TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust; if(reflectTarget.isNull()) reflectTarget = GFX->allocRenderToTextureTarget(); reflectTarget->attachTexture( GFXTextureTarget::Color0, reflectTex ); reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff ); GFX->pushActiveRenderTarget(); GFX->setActiveRenderTarget( reflectTarget ); U32 objTypeFlag = -1; SceneCameraState reflectCameraState = SceneCameraState::fromGFX(); LIGHTMGR->registerGlobalLights( &reflectCameraState.getFrustum(), false ); // Since we can sometime be rendering a reflection for 1 or 2 frames before // it gets updated do to the lag associated with getting the results from // a HOQ we can sometimes see into parts of the reflection texture that // have nothing but clear color ( eg. under the water ). // To make this look less crappy use the ambient color of the sun. // // In the future we may want to fix this instead by having the scatterSky // render a skirt or something in its lower half. // ColorF clearColor = gClientSceneGraph->getAmbientLightColor(); GFX->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget, clearColor, 1.0f, 0 ); if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide) { // Store previous values RectI originalVP = GFX->getViewport(); Point2F projOffset = GFX->getCurrentProjectionOffset(); Point3F eyeOffset = GFX->getStereoEyeOffset(); // Render left half of display RectI leftVP = originalVP; leftVP.extent.x *= 0.5; GFX->setViewport(leftVP); MatrixF leftWorldTrans(true); leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z)); MatrixF leftWorld(params.query->cameraMatrix); leftWorld.mulL(leftWorldTrans); Frustum gfxFrustum = GFX->getFrustum(); gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y)); GFX->setFrustum(gfxFrustum); setGFXMatrices( leftWorld ); SceneCameraState cameraStateLeft = SceneCameraState::fromGFX(); SceneRenderState renderStateLeft( gClientSceneGraph, SPT_Reflect, cameraStateLeft ); renderStateLeft.setSceneRenderStyle(SRS_SideBySide); renderStateLeft.setSceneRenderField(0); renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial ); renderStateLeft.setDiffuseCameraTransform( params.query->cameraMatrix ); renderStateLeft.disableAdvancedLightingBins(true); gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag ); // Render right half of display RectI rightVP = originalVP; rightVP.extent.x *= 0.5; rightVP.point.x += rightVP.extent.x; GFX->setViewport(rightVP); MatrixF rightWorldTrans(true); rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z)); MatrixF rightWorld(params.query->cameraMatrix); rightWorld.mulL(rightWorldTrans); gfxFrustum = GFX->getFrustum(); gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y)); GFX->setFrustum(gfxFrustum); setGFXMatrices( rightWorld ); SceneCameraState cameraStateRight = SceneCameraState::fromGFX(); SceneRenderState renderStateRight( gClientSceneGraph, SPT_Reflect, cameraStateRight ); renderStateRight.setSceneRenderStyle(SRS_SideBySide); renderStateRight.setSceneRenderField(1); renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial ); renderStateRight.setDiffuseCameraTransform( params.query->cameraMatrix ); renderStateRight.disableAdvancedLightingBins(true); gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag ); // Restore previous values gfxFrustum.clearProjectionOffset(); GFX->setFrustum(gfxFrustum); GFX->setViewport(originalVP); } else { SceneRenderState reflectRenderState ( gClientSceneGraph, SPT_Reflect, SceneCameraState::fromGFX() ); reflectRenderState.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial ); reflectRenderState.setDiffuseCameraTransform( params.query->cameraMatrix ); reflectRenderState.disableAdvancedLightingBins(true); gClientSceneGraph->renderSceneNoLights( &reflectRenderState, objTypeFlag ); } LIGHTMGR->unregisterAllLights(); // Clean up. reflectTarget->resolve(); GFX->popActiveRenderTarget(); // Restore detail adjust amount. TSShapeInstance::smDetailAdjust = detailAdjustBackup; mIsRendering = false; }
void MovementController::OnUpdate(DWORD const deltaMilliseconds) { //if (m_bKey['Q']) //{ // // This code is a cheat to position the camera exactly in a given // // spot so I can take screen shots! // Mat4x4 camTranslate; // D3DXMatrixTranslation(&m_matPosition, 8.847f, 7.055f, 11.618f); // m_fTargetYaw = m_fYaw += -64.35f; // m_fTargetPitch = m_fPitch = 28.57f; // // Calculate the new rotation matrix from the camera // // yaw and pitch. // Mat4x4 matRot; // D3DXMatrixRotationYawPitchRoll(&matRot, DEGREES_TO_RADIANS(m_fYaw), DEGREES_TO_RADIANS(m_fPitch), 0); // // Create the new object-to-world matrix, and the // // new world-to-object matrix. // D3DXMatrixMultiply(&m_matToWorld, &matRot, &m_matPosition); // D3DXMatrixInverse(&m_matFromWorld, NULL, &m_matToWorld); // m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); // return; //} bool bTranslating = false; Vec4 atWorld(0,0,0,0); Vec4 rightWorld(0,0,0,0); Vec4 upWorld(0,0,0,0); if (m_bKey['W'] || m_bKey['S']) { // In D3D, the "look at" default is always // the positive Z axis. Vec4 at = g_Forward4; if (m_bKey['S']) at *= -1; // This will give us the "look at" vector // in world space - we'll use that to move // the camera. atWorld = m_matToWorld.Xform(at); bTranslating = true; } if (m_bKey['A'] || m_bKey['D']) { // In D3D, the "right" default is always // the positive X axis. Vec4 right = g_Right4; if (m_bKey['A']) right *= -1; // This will give us the "right" vector // in world space - we'll use that to move // the camera rightWorld = m_matToWorld.Xform(right); bTranslating = true; } if (m_bKey[' '] || m_bKey['C'] || m_bKey['X']) { // In D3D, the "up" default is always // the positive Y axis. Vec4 up = g_Right4; if (!m_bKey[' ']) up *= -1; //Unlike strafing, Up is always up no matter //which way you are looking upWorld = up; bTranslating = true; } //Handling rotation as a result of mouse position { // The secret formula!!! Don't give it away! //If you are seeing this now, then you must be some kind of elite hacker! m_fYaw += (m_fTargetYaw - m_fYaw) * ( .35f ); m_fTargetPitch = MAX(-90, MIN(90, m_fTargetPitch)); m_fPitch += (m_fTargetPitch - m_fPitch) * ( .35f ); // Calculate the new rotation matrix from the camera // yaw and pitch. Mat4x4 matRot; matRot.BuildYawPitchRoll(DEGREES_TO_RADIANS(-m_fYaw), DEGREES_TO_RADIANS(m_fPitch), 0); // Create the new object-to-world matrix, and the // new world-to-object matrix. m_matToWorld = matRot * m_matPosition; m_matFromWorld = m_matToWorld.Inverse(); m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); } if (bTranslating) { float elapsedTime = (float)deltaMilliseconds / 1000.0f; Vec3 direction = atWorld + rightWorld + upWorld; direction.Normalize(); // Ramp the acceleration by the elapsed time. float numberOfSeconds = 5.f; m_currentSpeed += m_maxSpeed * ( (elapsedTime*elapsedTime) / numberOfSeconds); if (m_currentSpeed > m_maxSpeed) m_currentSpeed = m_maxSpeed; direction *= m_currentSpeed; Vec3 pos = m_matPosition.GetPosition() + direction; m_matPosition.SetPosition(pos); m_matToWorld.SetPosition(pos); m_matFromWorld = m_matToWorld.Inverse(); m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); } else { m_currentSpeed = 0.0f; } }