From b5ddf4782936b276c655bfa03ee1491d7aa8fc9d Mon Sep 17 00:00:00 2001 From: Porteries Tristan Date: Thu, 19 Jan 2017 06:28:40 +0000 Subject: [PATCH] UPBGE: Move camera projection computation in KX_KetsjiEngine::GetCameraProjection. This function returns the current projection matrix of a camera, if the projection is invalid then a new one is recomputed. The function doesn't alterate the OpenGL state by calling perspective_m4 and orthographic_m4 in RAS_OpenGLRasterizer. --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 108 +++++++++--------- source/gameengine/Ketsji/KX_KetsjiEngine.h | 3 + .../RAS_OpenGLRasterizer.cpp | 27 +---- 3 files changed, 66 insertions(+), 72 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 37ff05ef86c0..14574903122e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -848,68 +848,30 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) } } -// update graphics -void KX_KetsjiEngine::RenderFrame(KX_Scene *scene, KX_Camera *cam, unsigned short pass) +const MT_Matrix4x4& KX_KetsjiEngine::GetCameraProjection(KX_Scene *scene, KX_Camera *cam, const RAS_Rect& viewport, const RAS_Rect& area) { - bool override_camera; - RAS_Rect viewport, area; - float nearfrust, farfrust, focallength; - - if (!cam) - return; - - bool isfirstscene = (scene == m_scenes->GetFront()); - - KX_SetActiveScene(scene); - -#ifdef WITH_PYTHON - scene->RunDrawingCallbacks(KX_Scene::PRE_DRAW_SETUP, cam); -#endif - - GetSceneViewport(scene, cam, area, viewport); - - // set the viewport for this frame and scene - const int left = viewport.GetLeft(); - const int bottom = viewport.GetBottom(); - const int width = viewport.GetWidth(); - const int height = viewport.GetHeight(); - m_rasterizer->SetViewport(left, bottom, width + 1, height + 1); - m_rasterizer->SetScissor(left, bottom, width + 1, height + 1); - - /* Clear the depth after setting the scene viewport/scissor - * if it's not the first render pass. */ - if (pass > 0) { - m_rasterizer->Clear(RAS_IRasterizer::RAS_DEPTH_BUFFER_BIT); + if (cam->hasValidProjectionMatrix()) { + return cam->GetProjectionMatrix(); } - // see KX_BlenderMaterial::Activate - //m_rasterizer->SetAmbient(); - m_rasterizer->DisplayFog(); - - override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName) && + const bool override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName) && (cam->GetName() == "__default__cam__"); if (override_camera && !m_overrideCamData.m_perspective) { - m_rasterizer->SetProjectionMatrix(m_overrideCamProjMat); - if (!cam->hasValidProjectionMatrix()) { - // needed to get frustum planes for culling - MT_Matrix4x4 projmat; - projmat.setValue(m_overrideCamProjMat.getPointer()); - cam->SetProjectionMatrix(projmat); - } - } - else if (cam->hasValidProjectionMatrix()) { - m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); + // needed to get frustum planes for culling + MT_Matrix4x4 projmat; + projmat.setValue(m_overrideCamProjMat.getPointer()); + cam->SetProjectionMatrix(projmat); } else { RAS_FrameFrustum frustum; - bool orthographic = !cam->GetCameraData()->m_perspective; - nearfrust = cam->GetCameraNear(); - farfrust = cam->GetCameraFar(); - focallength = cam->GetFocalLength(); + const bool orthographic = !cam->GetCameraData()->m_perspective; + const float nearfrust = cam->GetCameraNear(); + const float farfrust = cam->GetCameraFar(); + const float focallength = cam->GetFocalLength(); MT_Matrix4x4 projmat; - float camzoom = override_camera ? m_overrideCamZoom : m_cameraZoom; + const float camzoom = override_camera ? m_overrideCamZoom : m_cameraZoom; if (orthographic) { RAS_FramingManager::ComputeOrtho( @@ -965,9 +927,53 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene *scene, KX_Camera *cam, unsigned shor cam->InvalidateProjectionMatrix(); } + return cam->GetProjectionMatrix(); +} + +// update graphics +void KX_KetsjiEngine::RenderFrame(KX_Scene *scene, KX_Camera *cam, unsigned short pass) +{ + bool override_camera; + RAS_Rect viewport, area; + float nearfrust, farfrust, focallength; + + if (!cam) + return; + + bool isfirstscene = (scene == m_scenes->GetFront()); + + KX_SetActiveScene(scene); + +#ifdef WITH_PYTHON + scene->RunDrawingCallbacks(KX_Scene::PRE_DRAW_SETUP, cam); +#endif + + GetSceneViewport(scene, cam, area, viewport); + + // set the viewport for this frame and scene + const int left = viewport.GetLeft(); + const int bottom = viewport.GetBottom(); + const int width = viewport.GetWidth(); + const int height = viewport.GetHeight(); + m_rasterizer->SetViewport(left, bottom, width + 1, height + 1); + m_rasterizer->SetScissor(left, bottom, width + 1, height + 1); + + /* Clear the depth after setting the scene viewport/scissor + * if it's not the first render pass. */ + if (pass > 0) { + m_rasterizer->Clear(RAS_IRasterizer::RAS_DEPTH_BUFFER_BIT); + } + + // see KX_BlenderMaterial::Activate + //m_rasterizer->SetAmbient(); + m_rasterizer->DisplayFog(); + + + MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); + m_rasterizer->SetProjectionMatrix(GetCameraProjection(scene, cam, viewport, area)); m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->NodeGetLocalScaling(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 25ec87ce2f11..dcbfa4f54fc7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -224,6 +224,9 @@ class KX_KetsjiEngine */ void UpdateSuspendedScenes(); + /// Update and return the projection matrix of a camera depending on the viewport. + const MT_Matrix4x4& GetCameraProjection(KX_Scene *scene, KX_Camera *cam, const RAS_Rect& viewport, const RAS_Rect& area); + void RenderFrame(KX_Scene *scene, KX_Camera *cam, unsigned short pass); void PostRenderScene(KX_Scene *scene, unsigned short target); void RenderDebugProperties(); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 1c86fc8b0da9..bc6d6e6480e0 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -1426,9 +1426,6 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( float focallength, bool perspective) { - MT_Matrix4x4 result; - float mat[16]; - // correction for stereo if (Stereo()) { float near_div_focallength; @@ -1466,14 +1463,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( } } - SetMatrixMode(RAS_PROJECTION); - LoadIdentity(); - glFrustum(left, right, bottom, top, frustnear, frustfar); - - glGetFloatv(GL_PROJECTION_MATRIX, mat); - result.setValue(mat); + float mat[4][4]; + perspective_m4(mat, left, right, bottom, top, frustnear, frustfar); - return result; + return MT_Matrix4x4(&mat[0][0]); } MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( @@ -1484,18 +1477,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( float frustnear, float frustfar) { - MT_Matrix4x4 result; - float mat[16]; - - // stereo is meaningless for orthographic, disable it - SetMatrixMode(RAS_PROJECTION); - LoadIdentity(); - glOrtho(left, right, bottom, top, frustnear, frustfar); - - glGetFloatv(GL_PROJECTION_MATRIX, mat); - result.setValue(mat); + float mat[4][4]; + orthographic_m4(mat, left, right, bottom, top, frustnear, frustfar); - return result; + return MT_Matrix4x4(&mat[0][0]); } // next arguments probably contain redundant info, for later...