BGE: Fix Orthographic mode and viewport scaling
authorBenoit Bolsee <benoit.bolsee@online.be>
Sun, 26 Apr 2009 12:23:30 +0000 (12:23 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sun, 26 Apr 2009 12:23:30 +0000 (12:23 +0000)
- the BGE now uses correct glOrtho projection whe camera is in orthographic mode
-

14 files changed:
projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_Camera.h
source/gameengine/Ketsji/KX_Dome.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/Rasterizer/RAS_CameraData.h
source/gameengine/Rasterizer/RAS_FramingManager.cpp
source/gameengine/Rasterizer/RAS_FramingManager.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/VideoTexture/ImageRender.cpp

index 01ccd916edbfa97d2e99e7a9e2559e75582d9af4..5cd8a9c469b5b54a3484479177e9c5dd7b26ec07 100644 (file)
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalOptions="/MACHINE:I386"\r
-                               AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"\r
+                               AdditionalDependencies="odelib.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"\r
                                OutputFile="..\..\..\..\bin\blenderplayer.exe"\r
                                LinkIncremental="1"\r
                                SuppressStartupBanner="true"\r
                                AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"\r
                                IgnoreDefaultLibraryNames="libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib"\r
+                               GenerateDebugInformation="true"\r
                                ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\blenderplayer.pdb"\r
                                SubSystem="1"\r
                                RandomizedBaseAddress="1"\r
index b2f283220a0c395b116652e1397e0a7d59753eb9..962af7cc4c90ecf6e878f62b1a808113c185d3a6 100644 (file)
@@ -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);
index e536d1f1e7ec28b1b54642a96a844c41755ec4fa..8565346b30e6fb38b7a9c069afdbf0c73f8cadb3 100644 (file)
@@ -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()]);
index d570fac213a3c2f16e2c635d178fd385b6d22378..83316972ca01c5a342e58b2fb95fc09234efc701 100644 (file)
@@ -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. */
index 077e2ce33b765f91965966d4fe037439a42c2900..9565c53e0bfa3e06cf88f0d8372ed9dcc451d11f 100644 (file)
@@ -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);
index 63db54a296e98ab7e1e382ec6f0807e514b27680..9bac0f7d75879b57b3f2831d46468d92913101cd 100644 (file)
@@ -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()
index 7bc982111fe1af7745e6d65d548428166c2d746f..498eb7262b597c6049f95ecfe9b0bda39026d4c2 100644 (file)
@@ -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)
index e3af43fb839d391bdd517f2a6fb2b53cd022534b..c8f4d9a0a17c5a1713d7f56bf99f352bc54c5e09 100644 (file)
@@ -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),
index e2bbca48bb57ddd1c4c10b6ca6d8cc4075be9aaf..ea18ffb229896fd7ecbc8897d596473299d4df8d 100644 (file)
@@ -70,6 +70,39 @@ ComputeDefaultFrustum(
        frustum.camfar = camfar;
 }
 
+       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(
@@ -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;
+       }
+       
+}
 
 
index 0a226ac30f9e1d4d0c66ada6c9f5c5b8d646aa52..4398e2d00c34973f5656c248a3c7c8d95466531e 100644 (file)
@@ -207,6 +207,18 @@ public :
         * and camera description
         */
 
+       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(
@@ -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
index 96472b112d62626ea8f565828e1746b0f4212c03..dc8c3c1ebf8186a4959ae6d3277157157c07ad6a 100644 (file)
@@ -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.
         */
index bf50cde22802daad110567f566d0df9c2f4df134..3fe5e26abc367e0149fdefba0932eae655c2f3d7 100644 (file)
@@ -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;
 }
 
 
index 6013946fadf9b42f5f13bf5e070c86df390ae617..4d51a477d48c630c47660aebacaee9b84c568d19 100644 (file)
@@ -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,
index 9a3c4fea70ed4a955fe2fa6cc488911886de58fb..f1df47af373e8ea6e61f9b52968695293f48a00f 100644 (file)
@@ -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);