diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2009-04-26 16:23:30 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2009-04-26 16:23:30 +0400 |
commit | ba563216e9ec4e7c3e55ca343948d925a2dc1651 (patch) | |
tree | c982d2100e4625559d53ab1e9c8e2be04c4a1033 /source/gameengine | |
parent | fc4ba5e13116835c3208ecfe21c9ccc3e93277f7 (diff) |
BGE: Fix Orthographic mode and viewport scaling
- the BGE now uses correct glOrtho projection whe camera is in orthographic mode
-
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Camera.cpp | 158 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Camera.h | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Dome.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 82 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.cpp | 3 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_CameraData.h | 4 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_FramingManager.cpp | 101 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_FramingManager.h | 22 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_IRasterizer.h | 26 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 33 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 15 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/ImageRender.cpp | 50 |
13 files changed, 354 insertions, 150 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b2f283220a0..962af7cc4c9 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1620,7 +1620,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { Camera* ca = static_cast<Camera*>(ob->data); - RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob)); + RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob)); KX_Camera *gamecamera; gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index e536d1f1e7e..8565346b30e 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -47,7 +47,7 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, m_camdata(camdata), m_dirty(true), m_normalized(false), - m_frustum_culling(frustum_culling && camdata.m_perspective), + m_frustum_culling(frustum_culling), m_set_projection_matrix(false), m_set_frustum_center(false) { @@ -184,6 +184,11 @@ float KX_Camera::GetLens() const return m_camdata.m_lens; } +float KX_Camera::GetScale() const +{ + return m_camdata.m_scale; +} + float KX_Camera::GetCameraNear() const @@ -264,80 +269,83 @@ void KX_Camera::ExtractFrustumSphere() MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix; clip_camcs_matrix.invert(); - // detect which of the corner of the far clipping plane is the farthest to the origin - MT_Vector4 nfar; // far point in device normalized coordinate - MT_Point3 farpoint; // most extreme far point in camera coordinate - MT_Point3 nearpoint;// most extreme near point in camera coordinate - MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate - MT_Scalar F=1.0, N; // square distance of far and near point to origin - MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 - MT_Scalar e, s; // far and near clipping distance (<0) - MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance - MT_Scalar z; // projection of sphere center on z axis (<0) - // tmp value - MT_Vector4 npoint(1., 1., 1., 1.); - MT_Vector4 hpoint; - MT_Point3 point; - MT_Scalar len; - for (int i=0; i<4; i++) - { - hpoint = clip_camcs_matrix*npoint; - point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); - len = point.dot(point); - if (len > F) - { - nfar = npoint; - farpoint = point; - F = len; - } - // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane - len = npoint[0]; - npoint[0] = -npoint[1]; - npoint[1] = len; - farcenter += point; - } - // the far center is the average of the far clipping points - farcenter *= 0.25; - // the extreme near point is the opposite point on the near clipping plane - nfar.setValue(-nfar[0], -nfar[1], -1., 1.); - nfar = clip_camcs_matrix*nfar; - nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); - N = nearpoint.dot(nearpoint); - e = farpoint[2]; - s = nearpoint[2]; - // projection on XY plane for distance to axis computation - MT_Point2 farxy(farpoint[0], farpoint[1]); - // f is forced positive by construction - f = farxy.length(); - // get corresponding point on the near plane - farxy *= s/e; - // this formula preserve the sign of n - n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); - c = MT_Point2(farcenter[0], farcenter[1]).length()/e; - // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case - z = (F-N)/(2.0*(e-s+c*(f-n))); - m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); - m_frustum_radius = m_frustum_center.distance(farpoint); - -#if 0 - // The most extreme points on the near and far plane. (normalized device coords) - MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.); - - // Transform to hom camera local space - hnear = clip_camcs_matrix*hnear; - hfar = clip_camcs_matrix*hfar; - - // Tranform to 3d camera local space. - MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]); - MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); - - // Compute center - // don't use camera data in case the user specifies the matrix directly - m_frustum_center = MT_Point3(0., 0., - (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/))); - m_frustum_radius = m_frustum_center.distance(farpoint); -#endif - + if (m_projection_matrix[3][3] == MT_Scalar(0.0)) + { + // frustrum projection + // detect which of the corner of the far clipping plane is the farthest to the origin + MT_Vector4 nfar; // far point in device normalized coordinate + MT_Point3 farpoint; // most extreme far point in camera coordinate + MT_Point3 nearpoint;// most extreme near point in camera coordinate + MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate + MT_Scalar F=-1.0, N; // square distance of far and near point to origin + MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 + MT_Scalar e, s; // far and near clipping distance (<0) + MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance + MT_Scalar z; // projection of sphere center on z axis (<0) + // tmp value + MT_Vector4 npoint(1., 1., 1., 1.); + MT_Vector4 hpoint; + MT_Point3 point; + MT_Scalar len; + for (int i=0; i<4; i++) + { + hpoint = clip_camcs_matrix*npoint; + point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); + len = point.dot(point); + if (len > F) + { + nfar = npoint; + farpoint = point; + F = len; + } + // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane + len = npoint[0]; + npoint[0] = -npoint[1]; + npoint[1] = len; + farcenter += point; + } + // the far center is the average of the far clipping points + farcenter *= 0.25; + // the extreme near point is the opposite point on the near clipping plane + nfar.setValue(-nfar[0], -nfar[1], -1., 1.); + nfar = clip_camcs_matrix*nfar; + nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); + // this is a frustrum projection + N = nearpoint.dot(nearpoint); + e = farpoint[2]; + s = nearpoint[2]; + // projection on XY plane for distance to axis computation + MT_Point2 farxy(farpoint[0], farpoint[1]); + // f is forced positive by construction + f = farxy.length(); + // get corresponding point on the near plane + farxy *= s/e; + // this formula preserve the sign of n + n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); + c = MT_Point2(farcenter[0], farcenter[1]).length()/e; + // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case + z = (F-N)/(2.0*(e-s+c*(f-n))); + m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); + m_frustum_radius = m_frustum_center.distance(farpoint); + } + else + { + // orthographic projection + // The most extreme points on the near and far plane. (normalized device coords) + MT_Vector4 hnear(1., 1., 1., 1.), hfar(-1., -1., -1., 1.); + + // Transform to hom camera local space + hnear = clip_camcs_matrix*hnear; + hfar = clip_camcs_matrix*hfar; + + // Tranform to 3d camera local space. + MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]); + MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); + + // just use mediant point + m_frustum_center = (farpoint + nearpoint)*0.5; + m_frustum_radius = m_frustum_center.distance(farpoint); + } // Transform to world space. m_frustum_center = GetCameraToWorld()(m_frustum_center); m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index d570fac213a..83316972ca0 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -184,6 +184,8 @@ public: /** Gets the aperture. */ float GetLens() const; + /** Gets the ortho scale. */ + float GetScale() const; /** Gets the near clip distance. */ float GetCameraNear() const; /** Gets the far clip distance. */ diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 077e2ce33b7..9565c53e0bf 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -1507,8 +1507,7 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i) MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); // restore the original orientation @@ -1914,8 +1913,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) MT_Transform camtrans(cam->GetWorldToCamera()); MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); scene->CalculateVisibleMeshes(m_rasterizer,cam); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 63db54a296e..9bac0f7d758 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1093,7 +1093,7 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect area = userviewport; } - else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) { + else if ( !m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) { RAS_FramingManager::ComputeViewport( scene->GetFramingType(), m_canvas->GetDisplayArea(), @@ -1163,13 +1163,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) { bool override_camera; RAS_Rect viewport, area; - float left, right, bottom, top, nearfrust, farfrust, focallength; - const float ortho = 100.0; + float nearfrust, farfrust, focallength; // KX_Camera* cam = scene->GetActiveCamera(); if (!cam) return; - GetSceneViewport(scene, cam, area, viewport); // store the computed viewport in the scene @@ -1187,19 +1185,24 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) override_camera = override_camera && (cam->GetName() == "__default__cam__"); if (override_camera && m_overrideCamUseOrtho) { - MT_CmMatrix4x4 projmat = m_overrideCamProjMat; - m_rasterizer->SetProjectionMatrix(projmat); + m_rasterizer->SetProjectionMatrix(m_overrideCamProjMat); + if (!cam->hasValidProjectionMatrix()) { + // needed to get frustrum planes for culling + MT_Matrix4x4 projmat; + projmat.setValue(m_overrideCamProjMat.getPointer()); + cam->SetProjectionMatrix(projmat); + } } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() ) { m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); } else { RAS_FrameFrustum frustum; - float lens = cam->GetLens(); bool orthographic = !cam->GetCameraData()->m_perspective; nearfrust = cam->GetCameraNear(); farfrust = cam->GetCameraFar(); focallength = cam->GetFocalLength(); + MT_Matrix4x4 projmat; if(override_camera) { nearfrust = m_overrideCamNear; @@ -1207,45 +1210,56 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) } if (orthographic) { - lens *= ortho; - nearfrust = (nearfrust + 1.0)*ortho; - farfrust *= ortho; - } - - RAS_FramingManager::ComputeFrustum( - scene->GetFramingType(), - area, - viewport, - lens, - nearfrust, - farfrust, - frustum - ); - left = frustum.x1 * m_cameraZoom; - right = frustum.x2 * m_cameraZoom; - bottom = frustum.y1 * m_cameraZoom; - top = frustum.y2 * m_cameraZoom; - nearfrust = frustum.camnear; - farfrust = frustum.camfar; + RAS_FramingManager::ComputeOrtho( + scene->GetFramingType(), + area, + viewport, + cam->GetScale(), + nearfrust, + farfrust, + frustum + ); + if (!cam->GetViewport()) { + frustum.x1 *= m_cameraZoom; + frustum.x2 *= m_cameraZoom; + frustum.y1 *= m_cameraZoom; + frustum.y2 *= m_cameraZoom; + } + projmat = m_rasterizer->GetOrthoMatrix( + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar); - MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( - left, right, bottom, top, nearfrust, farfrust, focallength); + } else { + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + cam->GetLens(), + nearfrust, + farfrust, + frustum + ); + if (!cam->GetViewport()) { + frustum.x1 *= m_cameraZoom; + frustum.x2 *= m_cameraZoom; + frustum.y1 *= m_cameraZoom; + frustum.y2 *= m_cameraZoom; + } + projmat = m_rasterizer->GetFrustumMatrix( + frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar, focallength); + } cam->SetProjectionMatrix(projmat); // Otherwise the projection matrix for each eye will be the same... - if (m_rasterizer->Stereo()) + if (!orthographic && m_rasterizer->Stereo()) cam->InvalidateProjectionMatrix(); } MT_Transform camtrans(cam->GetWorldToCamera()); - if (!cam->GetCameraData()->m_perspective) - camtrans.getOrigin()[2] *= ortho; MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); cam->SetModelviewMatrix(viewmat); //redundant, already done in Render() diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 7bc982111fe..498eb7262b5 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -160,8 +160,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T /* setup rasterizer transformations */ ras->SetProjectionMatrix(projectionmat); - ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(), - cam->GetCameraLocation(), cam->GetCameraOrientation()); + ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); } void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index e3af43fb839..c8f4d9a0a17 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -32,6 +32,7 @@ struct RAS_CameraData { float m_lens; + float m_scale; float m_clipstart; float m_clipend; bool m_perspective; @@ -42,10 +43,11 @@ struct RAS_CameraData int m_viewporttop; float m_focallength; - RAS_CameraData(float lens = 35.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, + RAS_CameraData(float lens = 35.0, float scale = 6.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : m_lens(lens), + m_scale(scale), m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp index e2bbca48bb5..ea18ffb2298 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.cpp +++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp @@ -72,6 +72,39 @@ ComputeDefaultFrustum( void RAS_FramingManager:: +ComputeDefaultOrtho( + const float camnear, + const float camfar, + const float scale, + const float design_aspect_ratio, + RAS_FrameFrustum & frustum +) +{ + float halfSize = scale*0.5f; + float sizeX; + float sizeY; + + if (design_aspect_ratio > 1.f) { + // halfsize defines the width + sizeX = halfSize; + sizeY = halfSize/design_aspect_ratio; + } else { + // halfsize defines the height + sizeX = halfSize * design_aspect_ratio; + sizeY = halfSize; + } + + frustum.x2 = sizeX; + frustum.x1 = -frustum.x2; + frustum.y2 = sizeY; + frustum.y1 = -frustum.y2; + frustum.camnear = -camfar; + frustum.camfar = camfar; +} + + + void +RAS_FramingManager:: ComputeBestFitViewRect( const RAS_Rect &availableViewport, const float design_aspect_ratio, @@ -227,5 +260,73 @@ ComputeFrustum( } } + void +RAS_FramingManager:: + ComputeOrtho( + const RAS_FrameSettings &settings, + const RAS_Rect &availableViewport, + const RAS_Rect &viewport, + const float scale, + const float camnear, + const float camfar, + RAS_FrameFrustum &frustum + ) +{ + RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); + + const float design_width = float(settings.DesignAspectWidth()); + const float design_height = float(settings.DesignAspectHeight()); + + float design_aspect_ratio = float(1); + + if (design_height == float(0)) { + // well this is ill defined + // lets just scale the thing + type = RAS_FrameSettings::e_frame_scale; + } else { + design_aspect_ratio = design_width/design_height; + } + + + ComputeDefaultOrtho( + camnear, + camfar, + scale, + design_aspect_ratio, + frustum + ); + + switch (type) { + + case RAS_FrameSettings::e_frame_extend: + { + RAS_Rect vt; + ComputeBestFitViewRect( + availableViewport, + design_aspect_ratio, + vt + ); + + // now scale the calculated frustum by the difference + // between vt and the viewport in each axis. + // These are always > 1 + + float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); + float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); + + frustum.x1 *= x_scale; + frustum.x2 *= x_scale; + frustum.y1 *= y_scale; + frustum.y2 *= y_scale; + + break; + } + case RAS_FrameSettings::e_frame_scale : + case RAS_FrameSettings::e_frame_bars: + default : + break; + } + +} diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 0a226ac30f9..4398e2d00c3 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -209,6 +209,18 @@ public : static void + ComputeOrtho( + const RAS_FrameSettings &settings, + const RAS_Rect &availableViewport, + const RAS_Rect &viewport, + const float scale, + const float camnear, + const float camfar, + RAS_FrameFrustum &frustum + ); + + static + void ComputeFrustum( const RAS_FrameSettings &settings, const RAS_Rect &availableViewport, @@ -229,6 +241,16 @@ public : RAS_FrameFrustum & frustum ); + static + void + ComputeDefaultOrtho( + const float camnear, + const float camfar, + const float scale, + const float design_aspect_ratio, + RAS_FrameFrustum & frustum + ); + private : static diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 96472b112d6..dc8c3c1ebf8 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -250,9 +250,9 @@ public: * Sets the modelview matrix. */ virtual void SetViewMatrix(const MT_Matrix4x4 & mat, - const MT_Vector3& campos, - const MT_Point3 &camLoc, - const MT_Quaternion &camOrientQuat)=0; + const MT_Matrix3x3 & ori, + const MT_Point3 & pos, + bool perspective)=0; /** */ virtual const MT_Point3& GetCameraPosition()=0; @@ -326,6 +326,26 @@ public: float focallength = 0.0f, bool perspective = true )=0; + + /** + * Generates a orthographic projection matrix from the specified frustum. + * @param left the left clipping plane + * @param right the right clipping plane + * @param bottom the bottom clipping plane + * @param top the top clipping plane + * @param frustnear the near clipping plane + * @param frustfar the far clipping plane + * @return a 4x4 matrix representing the projection transform. + */ + virtual MT_Matrix4x4 GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar + )=0; + /** * Sets the specular color component of the lighting equation. */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index bf50cde2280..3fe5e26abc3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -921,17 +921,40 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( return result; } +MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar +){ + MT_Matrix4x4 result; + double mat[16]; + + // stereo is meaning less for orthographic, disable it + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(left, right, bottom, top, frustnear, frustfar); + + glGetDoublev(GL_PROJECTION_MATRIX, mat); + result.setValue(mat); + + return result; +} + // next arguments probably contain redundant info, for later... -void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos, - const MT_Point3 &, const MT_Quaternion &camOrientQuat) +void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, + const MT_Matrix3x3 & camOrientMat3x3, + const MT_Point3 & pos, + bool perspective) { m_viewmatrix = mat; // correction for stereo - if(Stereo()) + if(Stereo() && perspective) { - MT_Matrix3x3 camOrientMat3x3(camOrientQuat); MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention MT_Vector3 unitViewupVec(0.0, 0.0, 1.0); MT_Vector3 viewDir, viewupVec; @@ -977,7 +1000,7 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vecto glMatrixMode(GL_MODELVIEW); glLoadMatrixd(glviewmat); - m_campos = campos; + m_campos = pos; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 6013946fadf..4d51a477d48 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -163,9 +163,9 @@ public: virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat); virtual void SetViewMatrix( const MT_Matrix4x4 & mat, - const MT_Vector3& campos, - const MT_Point3 &camLoc, - const MT_Quaternion &camOrientQuat + const MT_Matrix3x3 & ori, + const MT_Point3 & pos, + bool perspective ); virtual const MT_Point3& GetCameraPosition(); @@ -216,6 +216,15 @@ public: bool perspective ); + virtual MT_Matrix4x4 GetOrthoMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar + ); + virtual void SetSpecularity( float specX, float specY, diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 9a3c4fea70e..f1df47af373 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -181,7 +181,6 @@ void ImageRender::Render() frustrum.camnear = -mirrorOffset[2]; frustrum.camfar = -mirrorOffset[2]+m_clip; } - const float ortho = 100.0; const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); // The screen area that ImageViewport will copy is also the rendering zone @@ -214,37 +213,44 @@ void ImageRender::Render() float farfrust = m_camera->GetCameraFar(); float aspect_ratio = 1.0f; Scene *blenderScene = m_scene->GetBlenderScene(); + MT_Matrix4x4 projmat; - if (orthographic) { - lens *= ortho; - nearfrust = (nearfrust + 1.0)*ortho; - farfrust *= ortho; - } // compute the aspect ratio from frame blender scene settings so that render to texture // works the same in Blender and in Blender player if (blenderScene->r.ysch != 0) - aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); - - RAS_FramingManager::ComputeDefaultFrustum( - nearfrust, - farfrust, - lens, - aspect_ratio, - frustrum); - - MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( - frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); - + aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp); + + if (orthographic) { + + RAS_FramingManager::ComputeDefaultOrtho( + nearfrust, + farfrust, + m_camera->GetScale(), + aspect_ratio, + frustrum + ); + + projmat = m_rasterizer->GetOrthoMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + } else + { + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + } m_camera->SetProjectionMatrix(projmat); } MT_Transform camtrans(m_camera->GetWorldToCamera()); - if (!m_camera->GetCameraData()->m_perspective) - camtrans.getOrigin()[2] *= ortho; MT_Matrix4x4 viewmat(camtrans); - m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), - m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->GetCameraData()->m_perspective); m_camera->SetModelviewMatrix(viewmat); // restore the stereo mode now that the matrix is computed m_rasterizer->SetStereoMode(stereomode); |