Various game engine fixes:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 14 Sep 2008 00:32:18 +0000 (00:32 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 14 Sep 2008 00:32:18 +0000 (00:32 +0000)
* Fix issue with add transparency mode with blender materials.
* Possible fix at frontface flip in the game engine.
* Fix color buffering clearing for multiple viewports, it used
  to clear as if there was one.
* Fix for zoom level in user defined viewports, it was based on
  the full window before, now it is based on the viewport itself.
* For user defined viewports, always use Expose instead of
  Letterbox with bars, the latter doesn't make sense then.

source/blender/blenloader/intern/readfile.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Rasterizer/RAS_BucketManager.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

index 6b720851b0d49d5290403848541c0c2c4c31e831..da85a264a0cdce80ccb366a039692c4b9c4a9be5 100644 (file)
@@ -7762,7 +7762,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
-       if(main->versionfile <= 246 && main->subversionfile < 1){
+       if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
                Mesh *me;
 
                for(me=main->mesh.first; me; me= me->id.next)
index 05d4f45b63427e41d548299b3195f37ab4adc308..7a04a42e90dc885323d5c241d7c86df72b2e0ece 100644 (file)
@@ -627,7 +627,7 @@ BL_Material* ConvertMaterial(
                material->transp = TF_ALPHA;
 
        // always zsort alpha + add
-       if((material->transp == TF_ALPHA || texalpha) && (material->transp != TF_CLIP)) {
+       if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) {
                material->ras_mode |= ALPHA;
                material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
        }
index 0b4fde61e1c441d0af840e107b6a622021eca5b2..4d24ba195ccaacd672898d97712035d47d3e364d 100644 (file)
@@ -629,7 +629,8 @@ int main(int argc, char** argv)
                                char pathname[160];
 
                                get_filename(argc, argv, filename);
-                               make_absolute_filename(filename);
+                               if(filename[0])
+                                       make_absolute_filename(filename);
                                
                                do
                                {
index cf98bb72601252fc7d1cd4b25dac07ba7d44cce8..4d83853537e2f75048e3f55dc344e14ff4fce55a 100644 (file)
@@ -276,30 +276,73 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo)
 
 }
 
-bool KX_KetsjiEngine::BeginFrame()
+void KX_KetsjiEngine::ClearFrame()
 {
-       bool result = false;
+       // clear unless we're drawing overlapping stereo
+       if(m_rasterizer->InterlacedStereo() &&
+               m_rasterizer->GetEye() == RAS_IRasterizer::RAS_STEREO_RIGHTEYE)
+               return;
 
-       RAS_Rect vp;
-       KX_Scene* firstscene = *m_scenes.begin();
-       const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
+       // clear the viewports with the background color of the first scene
+       bool doclear = false;
+       KX_SceneList::iterator sceneit;
+       RAS_Rect clearvp, area, viewport;
 
-       // set the area used for rendering
-       m_rasterizer->SetRenderArea();
+       for (sceneit = m_scenes.begin(); sceneit != m_scenes.end(); sceneit++)
+       {
+               KX_Scene* scene = *sceneit;
+               //const RAS_FrameSettings &framesettings = scene->GetFramingType();
+               list<class KX_Camera*>* cameras = scene->GetCameras();
+
+               list<KX_Camera*>::iterator it;
+               for(it = cameras->begin(); it != cameras->end(); it++)
+               {
+                       SetupViewport(scene, (*it), area, viewport);
+
+                       if(!doclear) {
+                               clearvp = viewport;
+                               doclear = true;
+                       }
+                       else {
+                               if(viewport.GetLeft() < clearvp.GetLeft())
+                                       clearvp.SetLeft(viewport.GetLeft());
+                               if(viewport.GetBottom() < clearvp.GetBottom())
+                                       clearvp.SetBottom(viewport.GetBottom());
+                               if(viewport.GetRight() > clearvp.GetRight())
+                                       clearvp.SetRight(viewport.GetRight());
+                               if(viewport.GetTop() > clearvp.GetTop())
+                                       clearvp.SetTop(viewport.GetTop());
+
+                       }
+               }
+       }
+
+       if(doclear) {
+               KX_Scene* firstscene = *m_scenes.begin();
+               SetBackGround(firstscene->GetWorldInfo());
+
+               m_canvas->SetViewPort(clearvp.GetLeft(), clearvp.GetBottom(),
+                       clearvp.GetRight(), clearvp.GetTop());  
+               m_rasterizer->ClearColorBuffer();
+       }
+}
 
-       RAS_FramingManager::ComputeViewport(framesettings, m_canvas->GetDisplayArea(), vp);
+bool KX_KetsjiEngine::BeginFrame()
+{
+       // set the area used for rendering (stereo can assign only a subset)
+       m_rasterizer->SetRenderArea();
 
        if (m_canvas->BeginDraw())
        {
-               result = true;
+               ClearFrame();
+
+               m_rasterizer->BeginFrame(m_drawingmode , m_kxsystem->GetTimeInSeconds());
+               m_rendertools->BeginFrame(m_rasterizer);
 
-               m_canvas->SetViewPort(vp.GetLeft(), vp.GetBottom(), vp.GetRight(), vp.GetTop());
-               SetBackGround( firstscene->GetWorldInfo() );
-               m_rasterizer->BeginFrame( m_drawingmode , m_kxsystem->GetTimeInSeconds());
-               m_rendertools->BeginFrame( m_rasterizer);
+               return true;
        }
        
-       return result;
+       return false;
 }              
 
 
@@ -606,7 +649,7 @@ void KX_KetsjiEngine::Render()
                                );
                }
                // clear the -whole- viewport
-               m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
+               m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
        }
 
        m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE);
@@ -635,9 +678,6 @@ void KX_KetsjiEngine::Render()
        
                        m_rendertools->SetAuxilaryClientInfo(scene);
        
-                       //Initialize scene viewport.
-                       SetupRenderFrame(scene, cam);
-       
                        // do the rendering
                        RenderFrame(scene, cam);
                }
@@ -655,9 +695,6 @@ void KX_KetsjiEngine::Render()
                
                                m_rendertools->SetAuxilaryClientInfo(scene);
                
-                               //Initialize scene viewport.
-                               SetupRenderFrame(scene, (*it));
-               
                                // do the rendering
                                RenderFrame(scene, (*it));
                        }
@@ -690,10 +727,6 @@ void KX_KetsjiEngine::Render()
                        //pass the scene, for picking and raycasting (shadows)
                        m_rendertools->SetAuxilaryClientInfo(scene);
 
-                       //Initialize scene viewport.
-                       //SetupRenderFrame(scene);
-                       SetupRenderFrame(scene, cam);
-
                        // do the rendering
                        //RenderFrame(scene);
                        RenderFrame(scene, cam);
@@ -854,7 +887,7 @@ void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat)
 }
 
        
-void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
+void KX_KetsjiEngine::SetupViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport)
 {
        // In this function we make sure the rasterizer settings are upto
        // date. We compute the viewport so that logic
@@ -862,17 +895,26 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
 
        // Note we postpone computation of the projection matrix
        // so that we are using the latest camera position.
+       if (cam->GetViewport()) {
+               RAS_Rect userviewport;
 
-       RAS_Rect viewport;
+               userviewport.SetLeft(cam->GetViewportLeft()); 
+               userviewport.SetBottom(cam->GetViewportBottom());
+               userviewport.SetRight(cam->GetViewportRight());
+               userviewport.SetTop(cam->GetViewportTop());
 
-       if (!cam)
-               return;
+               // Don't do bars on user specified viewport
+               RAS_FrameSettings settings = scene->GetFramingType();
+               if(settings.FrameType() == RAS_FrameSettings::e_frame_bars)
+                       settings.SetFrameType(RAS_FrameSettings::e_frame_extend);
 
-       if (cam->GetViewport()) {
-               viewport.SetLeft(cam->GetViewportLeft()); 
-               viewport.SetBottom(cam->GetViewportBottom());
-               viewport.SetRight(cam->GetViewportRight());
-               viewport.SetTop(cam->GetViewportTop());
+               RAS_FramingManager::ComputeViewport(
+                       scene->GetFramingType(),
+                       userviewport,
+                       viewport
+               );
+
+               area = userviewport;
        }
        else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) ||  m_overrideCamUseOrtho ) {
                RAS_FramingManager::ComputeViewport(
@@ -880,24 +922,16 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
                        m_canvas->GetDisplayArea(),
                        viewport
                );
+
+               area = m_canvas->GetDisplayArea();
        } else {
                viewport.SetLeft(0); 
                viewport.SetBottom(0);
                viewport.SetRight(int(m_canvas->GetWidth()));
                viewport.SetTop(int(m_canvas->GetHeight()));
-       }
-       // store the computed viewport in the scene
-
-       scene->SetSceneViewport(viewport);      
-
-       // set the viewport for this frame and scene
-       m_canvas->SetViewPort(
-               viewport.GetLeft(),
-               viewport.GetBottom(),
-               viewport.GetRight(),
-               viewport.GetTop()
-       );      
 
+               area = m_canvas->GetDisplayArea();
+       }
 }
 
 void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
@@ -951,12 +985,22 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
 // update graphics
 void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
 {
+       RAS_Rect viewport, area;
        float left, right, bottom, top, nearfrust, farfrust, focallength;
        const float ortho = 100.0;
 //     KX_Camera* cam = scene->GetActiveCamera();
        
        if (!cam)
                return;
+
+       SetupViewport(scene, cam, area, viewport);
+
+       // store the computed viewport in the scene
+       scene->SetSceneViewport(viewport);      
+
+       // set the viewport for this frame and scene
+       m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(),
+               viewport.GetRight(), viewport.GetTop());        
        
        // see KX_BlenderMaterial::Activate
        //m_rasterizer->SetAmbient();
@@ -985,8 +1029,8 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
                
                RAS_FramingManager::ComputeFrustum(
                        scene->GetFramingType(),
-                       m_canvas->GetDisplayArea(),
-                       scene->GetSceneViewport(),
+                       area,
+                       viewport,
                        lens,
                        nearfrust,
                        farfrust,
@@ -1002,7 +1046,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
 
                MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
                        left, right, bottom, top, nearfrust, farfrust, focallength);
-       
+
                cam->SetProjectionMatrix(projmat);
                
                // Otherwise the projection matrix for each eye will be the same...
index 97458362f0f0cbd619113573b8f28efaf2e50903..89f6fe550450a9c0f949b56e02daf3bb82111a86 100644 (file)
@@ -177,7 +177,7 @@ private:
        /** Blue component of framing bar color. */
        float                                   m_overrideFrameColorB;
 
-       void                                    SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
+       void                                    SetupViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport);
        void                                    RenderFrame(KX_Scene* scene, KX_Camera* cam);
        void                                    PostRenderFrame();
        void                                    RenderDebugProperties();
@@ -355,6 +355,7 @@ protected:
        KX_Scene*               CreateScene(const STR_String& scenename);
        
        bool                    BeginFrame();
+       void                    ClearFrame();
        void                    EndFrame();
 };
 
index 9fb21a3c17b6b52c939ed53cd8e5ef73f8e22415..f7938bb62e67e28b1ad5800f13487e67730b25dc 100644 (file)
@@ -130,9 +130,6 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList
                sort(slots.begin(), slots.end(), fronttoback());
 }
 
-//static int TOTASLOT = 0;
-//static int TOTSLOT = 0;
-
 void RAS_BucketManager::RenderAlphaBuckets(
        const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
 {
@@ -149,10 +146,8 @@ void RAS_BucketManager::RenderAlphaBuckets(
        for(sit=slots.begin(); sit!=slots.end(); ++sit) {
                rendertools->SetClientObject(rasty, sit->m_ms->m_clientObj);
 
-               while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)) {
+               while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools))
                        sit->m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(sit->m_ms));
-                       //TOTASLOT++;
-               }
        }
 
        rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
@@ -173,13 +168,14 @@ void RAS_BucketManager::RenderSolidBuckets(
 
                        rendertools->SetClientObject(rasty, mit->m_clientObj);
 
-                       while ((*bit)->ActivateMaterial(cameratrans, rasty, rendertools)) {
+                       while ((*bit)->ActivateMaterial(cameratrans, rasty, rendertools))
                                (*bit)->RenderMeshSlot(cameratrans, rasty, rendertools, *mit);
-                               //TOTSLOT++;
-                       }
                }
        }
        
+       /* this code draws meshes order front-to-back instead to reduce overdraw.
+        * it turned out slower due to much material state switching, a more clever
+        * algorithm might do better. */
 #if 0
        vector<sortedmeshslot> slots;
        vector<sortedmeshslot>::iterator sit;
@@ -198,17 +194,12 @@ void RAS_BucketManager::RenderSolidBuckets(
 void RAS_BucketManager::Renderbuckets(
        const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
 {
-       // beginning each frame, clear (texture/material) caching information
+       /* beginning each frame, clear (texture/material) caching information */
        rasty->ClearCachingInfo();
 
-       //TOTASLOT = 0;
-       //TOTSLOT = 0;
-
        RenderSolidBuckets(cameratrans, rasty, rendertools);    
        RenderAlphaBuckets(cameratrans, rasty, rendertools);    
 
-       //printf("total slots = %d = %d + %d\n", TOTSLOT + TOTASLOT, TOTSLOT, TOTASLOT);
-
        rendertools->SetClientObject(rasty, NULL);
 }
 
index dcb48c1c2a0b9d6ff3f1ea17770ca81174668f7b..9cb59f300f7487e8f1bf7256001b5aeb94ae0e23 100644 (file)
@@ -108,6 +108,13 @@ public :
        ) const {
                return m_frame_type;
        };
+
+               void
+       SetFrameType(
+               RAS_FrameType type
+       ) {
+               m_frame_type = type;
+       };
        
                float
        BarRed(
@@ -140,14 +147,6 @@ public :
        };
 
 private :
-       
-       /**
-        * private to force use of public constructor
-        */
-
-       RAS_FrameSettings(
-               const RAS_FrameSettings &
-       );
 
        RAS_FrameType m_frame_type;
        float m_bar_r;
index 1d18d02a5833cec6405bac4eff0e0c391249b802..411b28fa3b7c21ae691f5c8bcee73986657025b7 100644 (file)
@@ -168,6 +168,10 @@ public:
         * BeginFrame is called at the start of each frame.
         */
        virtual bool    BeginFrame(int drawingmode, double time)=0;
+       /**
+        * ClearColorBuffer clears the color buffer.
+        */
+       virtual void    ClearColorBuffer()=0;
        /**
         * ClearDepthBuffer clears the depth buffer.
         */
@@ -181,7 +185,8 @@ public:
         */
        virtual void    EndFrame()=0;
        /**
-        * SetRenderArea sets the render area from the 2d canvas
+        * SetRenderArea sets the render area from the 2d canvas.
+        * Returns true if only of subset of the canvas is used.
         */
        virtual void    SetRenderArea()=0;
 
@@ -195,6 +200,7 @@ public:
         * @return true if stereo mode is enabled.
         */
        virtual bool    Stereo()=0;
+       virtual bool    InterlacedStereo()=0;
        /**
         * Sets which eye buffer subsequent primitives will be rendered to.
         */
index 62ee2edb7312e54ff316bf7d9f5c7f8d1e6000cf..4f31ae7fcbc3ace6a834dfb8970853c87f75f496 100644 (file)
@@ -105,8 +105,12 @@ bool RAS_OpenGLRasterizer::Init()
        m_ambg = 0.0f;
        m_ambb = 0.0f;
 
-       SetBlendingMode(GPU_BLEND_SOLID);
-       SetFrontFace(true);
+       glDisable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       m_last_blendmode = GPU_BLEND_SOLID;
+
+       glFrontFace(GL_CCW);
+       m_last_frontface = true;
 
        glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -250,21 +254,10 @@ void RAS_OpenGLRasterizer::Exit()
        EndFrame();
 }
 
-bool RAS_OpenGLRasterizer::InterlacedStereo() const
-{
-       return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
-}
-
 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
 {
        m_time = time;
        m_drawingmode = drawingmode;
-       
-       if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
-       {
-               m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
-               m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
-       }
 
        // Blender camera routine destroys the settings
        if (m_drawingmode < KX_SOLID)
@@ -278,8 +271,12 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
                glEnable (GL_CULL_FACE);
        }
 
-       SetBlendingMode(GPU_BLEND_SOLID);
-       SetFrontFace(true);
+       glDisable(GL_BLEND);
+       glDisable(GL_ALPHA_TEST);
+       m_last_blendmode = GPU_BLEND_SOLID;
+
+       glFrontFace(GL_CCW);
+       m_last_frontface = true;
 
        glShadeModel(GL_SMOOTH);
 
@@ -310,6 +307,12 @@ void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
 }
 
 
+void RAS_OpenGLRasterizer::ClearColorBuffer()
+{
+       m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
+       m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
+}
+
 
 void RAS_OpenGLRasterizer::ClearDepthBuffer()
 {
@@ -420,6 +423,10 @@ bool RAS_OpenGLRasterizer::Stereo()
                return true;
 }
 
+bool RAS_OpenGLRasterizer::InterlacedStereo()
+{
+       return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
+}
 
 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
 {
index 368bd4312aca0486a3681e51bdc554692363659d..0717cce0ce846861f1df5f4bdf57e081f6ce52ec 100644 (file)
@@ -88,7 +88,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
        float                   m_focallength;
        bool                    m_setfocallength;
        int                             m_noOfScanlines;
-       bool                    InterlacedStereo() const;
 
        //motion blur
        int     m_motionblur;
@@ -131,6 +130,7 @@ public:
        virtual bool    Init();
        virtual void    Exit();
        virtual bool    BeginFrame(int drawingmode, double time);
+       virtual void    ClearColorBuffer();
        virtual void    ClearDepthBuffer();
        virtual void    ClearCachingInfo(void);
        virtual void    EndFrame();
@@ -138,6 +138,7 @@ public:
 
        virtual void    SetStereoMode(const StereoMode stereomode);
        virtual bool    Stereo();
+       virtual bool    InterlacedStereo();
        virtual void    SetEye(const StereoEye eye);
        virtual StereoEye       GetEye();
        virtual void    SetEyeSeparation(const float eyeseparation);