BGE performance, 3rd round: culling and rasterizer.
authorBenoit Bolsee <benoit.bolsee@online.be>
Thu, 7 May 2009 09:13:01 +0000 (09:13 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Thu, 7 May 2009 09:13:01 +0000 (09:13 +0000)
This commit extend the technique of dynamic linked list to the mesh
slots so as to eliminate dumb scan or map lookup. It provides massive
performance improvement in the culling and in the rasterizer when
the majority of objects are static.

Other improvements:
- Compute the opengl matrix only for objects that are visible.
- Simplify hash function for GEN_HasedPtr
- Scan light list instead of general object list to render shadows
- Remove redundant opengl calls to set specularity, shinyness and diffuse
  between each mesh slots.
- Cache GPU material to avoid frequent call to GPU_material_from_blender
- Only set once the fixed elements of mesh slot
- Use more inline function

The following table shows the performance increase between 2.48, 1st round
and this round of improvement. The test was done with a scene containing
40000 objects, of which 1000 are in the view frustrum approximately. The
object are simple textured cube to make sure the GPU is not the bottleneck.
As some of the rasterizer processing time has moved under culling, I present
the sum of scenegraph(includes culling)+rasterizer time

Scenegraph+rasterizer(ms)       2.48      1st round       3rd round

All objects static,            323.0           86.0             7.2
all visible, 1000 in
the view frustrum

All objects static,            219.0           49.7             N/A(*)
all invisible.

All objects moving,            323.0          105.6            34.7
all visible, 1000 in
the view frustrum

Scene destruction              40min          40min              4s

(*) : this time is not representative because the frame rate was at 60fps.
      In that case, the GPU holds down the GE by frame sync. By design, the
      overhead of the rasterizer is 0 when the the objects are invisible.

This table shows a global speed up between 9x and 45x compared to 2.48a
for scenegraph, culling and rasterizer overhead. The speed up goes much
higher when objects are invisible.

An additional 2-4x speed up is possible in the scenegraph by upgrading
the Moto library to use Eigen2 BLAS library instead of C++ classes but
the scenegraph is already so fast that it is not a priority right now.

Next speed up in logic: many things to do there...

34 files changed:
projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj
projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
source/gameengine/Ketsji/BL_BlenderShader.cpp
source/gameengine/Ketsji/BL_BlenderShader.h
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_Light.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Rasterizer/CMakeLists.txt
source/gameengine/Rasterizer/Makefile
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_BucketManager.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript
source/gameengine/Rasterizer/SConscript
source/gameengine/SceneGraph/SG_DList.h
source/gameengine/SceneGraph/SG_QList.h
source/gameengine/SceneGraph/SG_Spatial.cpp
source/gameengine/SceneGraph/SG_Spatial.h
source/gameengine/VideoTexture/ImageRender.cpp
source/kernel/gen_system/GEN_HashedPtr.cpp

index d3d35ff4826cb11d67a56c3c5de7adab8f405b45..dde8714507a63cf25e0a483ae17933994a1d4aad 100644 (file)
@@ -43,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index 77142079b802916647e045d7e0b5209e94ba21cb..09b87f41ddf7c4c3d189a86c110deabe3ba68672 100644 (file)
@@ -43,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index 3df483b05987cba9105b2f3cc46e2c999f8a1f9a..a0a61d01bb29a158ac5f06fd4c2dbcf854d45639 100644 (file)
@@ -20,41 +20,33 @@ BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lig
 :
        mScene(scene),
        mMat(ma),
-       mLightLayer(lightlayer)
+       mLightLayer(lightlayer),
+       mGPUMat(NULL)
 {
        mBlenderScene = scene->GetBlenderScene();
        mBlendMode = GPU_BLEND_SOLID;
 
-       if(mMat)
-               GPU_material_from_blender(mBlenderScene, mMat);
+       ReloadMaterial();
 }
 
 BL_BlenderShader::~BL_BlenderShader()
 {
-       if(mMat && GPU_material_from_blender(mBlenderScene, mMat))
-               GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat));
+       if(mGPUMat)
+               GPU_material_unbind(mGPUMat);
 }
 
-bool BL_BlenderShader::Ok()
+void BL_BlenderShader::ReloadMaterial()
 {
-       return VerifyShader();
-}
-
-bool BL_BlenderShader::VerifyShader()
-{
-       if(mMat)
-               return (GPU_material_from_blender(mBlenderScene, mMat) != 0);
-       else
-               return false;
+       mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
 }
 
 void BL_BlenderShader::SetProg(bool enable, double time)
 {
        if(VerifyShader()) {
                if(enable)
-                       GPU_material_bind(GPU_material_from_blender(mBlenderScene, mMat), mLightLayer, mBlenderScene->lay, time);
+                       GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time);
                else
-                       GPU_material_unbind(GPU_material_from_blender(mBlenderScene, mMat));
+                       GPU_material_unbind(mGPUMat);
        }
 }
 
@@ -66,7 +58,7 @@ int BL_BlenderShader::GetAttribNum()
        if(!VerifyShader())
                return enabled;
 
-       GPU_material_vertex_attributes(GPU_material_from_blender(mBlenderScene, mMat), &attribs);
+       GPU_material_vertex_attributes(mGPUMat, &attribs);
 
     for(i = 0; i < attribs.totlayer; i++)
                if(attribs.layer[i].glindex+1 > enabled)
@@ -89,7 +81,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
        if(!VerifyShader())
                return;
        
-       gpumat = GPU_material_from_blender(mBlenderScene, mMat);
+       gpumat = mGPUMat;
 
        if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
                GPU_material_vertex_attributes(gpumat, &attribs);
@@ -131,7 +123,7 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
        float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
        GPUMaterial *gpumat;
 
-       gpumat = GPU_material_from_blender(mBlenderScene, mMat);
+       gpumat = mGPUMat;
 
        if(!gpumat || !GPU_material_bound(gpumat))
                return;
index 5c1f59f94ade694e319e8bc791db6ede04299721..9af53bfc86323f3996ca8898ac00b6aa1608ea97 100644 (file)
@@ -32,19 +32,28 @@ private:
        struct Material *mMat;
        int                             mLightLayer;
        int                             mBlendMode;
+       GPUMaterial     *mGPUMat;
 
-       bool                    VerifyShader();
+       bool                    VerifyShader() 
+       {
+               return (NULL != mGPUMat);
+       }
 
 public:
        BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer);
        virtual ~BL_BlenderShader();
 
-       bool                            Ok();
+       bool                            Ok()
+       {
+               // same as VerifyShared
+               return (NULL != mGPUMat);
+       }
        void                            SetProg(bool enable, double time=0.0);
 
        int GetAttribNum();
        void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
        void Update(const class RAS_MeshSlot & ms, class RAS_IRasterizer* rasty);
+       void ReloadMaterial();
        int GetBlendMode();
 
        bool Equals(BL_BlenderShader *blshader);
index 5f08739ea14ae09d173f6e6a182dae050741a331..c3c738a818364d203ebf92c0ad4674b04b77a457 100644 (file)
@@ -152,6 +152,12 @@ Scene* KX_BlenderMaterial::GetBlenderScene() const
        return mScene->GetBlenderScene();
 }
 
+void KX_BlenderMaterial::ReleaseMaterial()
+{
+       if (mBlenderShader)
+               mBlenderShader->ReloadMaterial();
+}
+
 void KX_BlenderMaterial::OnConstruction()
 {
        if (mConstructed)
@@ -409,10 +415,12 @@ KX_BlenderMaterial::ActivatShaders(
                }
                else
                        rasty->SetLines(false);
+               ActivatGLMaterials(rasty);
+               ActivateTexGen(rasty);
        }
 
-       ActivatGLMaterials(rasty);
-       ActivateTexGen(rasty);
+       //ActivatGLMaterials(rasty);
+       //ActivateTexGen(rasty);
 }
 
 void
@@ -501,10 +509,12 @@ KX_BlenderMaterial::ActivateMat(
                }
                else
                        rasty->SetLines(false);
+               ActivatGLMaterials(rasty);
+               ActivateTexGen(rasty);
        }
 
-       ActivatGLMaterials(rasty);
-       ActivateTexGen(rasty);
+       //ActivatGLMaterials(rasty);
+       //ActivateTexGen(rasty);
 }
 
 bool 
index d763ba3ef032805b74aa32b22dcaca7764e26819..52019ed2248739616df162a776393731f93f8c5b 100644 (file)
@@ -121,6 +121,7 @@ private:
        void GetMaterialRGBAColor(unsigned char *rgba) const;
        Material* GetBlenderMaterial() const;
        Scene* GetBlenderScene() const;
+       void ReleaseMaterial();
 
        // message centers
        void    setTexData( bool enable,RAS_IRasterizer *ras);
index 22b9c94017832d6632f090e45ffefb9de4864ad1..b20c0dae97b1da653231ace0e1b50de35f9517a4 100644 (file)
@@ -436,6 +436,7 @@ double*     KX_GameObject::GetOpenGLMatrix()
                m_bIsNegativeScaling = ((scaling[0] < 0.0) ^ (scaling[1] < 0.0) ^ (scaling[2] < 0.0)) ? true : false;
                trans.scale(scaling[0], scaling[1], scaling[2]);
                trans.getValue(fl);
+               GetSGNode()->ClearDirty();
        }
        return fl;
 }
@@ -443,8 +444,27 @@ double*    KX_GameObject::GetOpenGLMatrix()
 void KX_GameObject::AddMeshUser()
 {
        for (size_t i=0;i<m_meshes.size();i++)
-               m_meshes[i]->AddMeshUser(this);
-       
+       {
+               m_meshes[i]->AddMeshUser(this, &m_meshSlots);
+       }
+       // set the part of the mesh slot that never change
+       double* fl = GetOpenGLMatrixPtr()->getPointer();
+       RAS_Deformer *deformer = GetDeformer();
+
+       //RAS_MeshSlot *ms;
+       //for(ms =static_cast<RAS_MeshSlot*>(m_meshSlots.QPeek());
+       //      ms!=static_cast<RAS_MeshSlot*>(m_meshSlots.Self());
+       //      ms =static_cast<RAS_MeshSlot*>(ms->QPeek()))
+       //{
+       //      ms->m_OpenGLMatrix = fl;
+       //      ms->SetDeformer(deformer);
+       //}
+       SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
+       for(mit.begin(); !mit.end(); ++mit)
+       {
+               (*mit)->m_OpenGLMatrix = fl;
+               (*mit)->SetDeformer(deformer);
+       }
        UpdateBuckets(false);
 }
 
@@ -468,10 +488,29 @@ static void UpdateBuckets_recursive(SG_Node* node)
 void KX_GameObject::UpdateBuckets( bool recursive )
 {
        if (GetSGNode()) {
-               double* fl = GetOpenGLMatrixPtr()->getPointer();
-
-               for (size_t i=0;i<m_meshes.size();i++)
-                       m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
+               RAS_MeshSlot *ms;
+
+               if (GetSGNode()->IsDirty())
+                       GetOpenGLMatrix();
+               //for(ms =static_cast<RAS_MeshSlot*>(m_meshSlots.QPeek());
+               //    ms!=static_cast<RAS_MeshSlot*>(m_meshSlots.Self());
+               //    ms =static_cast<RAS_MeshSlot*>(ms->QPeek()))
+               SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
+               for(mit.begin(); !mit.end(); ++mit)
+               {
+                       ms = *mit;
+                       ms->m_bObjectColor = m_bUseObjectColor;
+                       ms->m_RGBAcolor = m_objectColor;
+                       ms->m_bVisible = m_bVisible;
+                       ms->m_bCulled = m_bCulled || !m_bVisible;
+                       if (!ms->m_bCulled) 
+                               ms->m_bucket->ActivateMesh(ms);
+                       
+                       /* split if necessary */
+#ifdef USE_SPLIT
+                       ms->Split();
+#endif
+               }
        
                if (recursive) {
                        UpdateBuckets_recursive(GetSGNode());
index bbb1b8bb3603661380cc321ce9fbe94954904325..2869404ee9ba1718e0e99f8ec824783b7862a262 100644 (file)
@@ -77,6 +77,7 @@ protected:
        STR_String                                                      m_text;
        int                                                                     m_layer;
        std::vector<RAS_MeshObject*>            m_meshes;
+       SG_QList                                                        m_meshSlots;    // head of mesh slots of this 
        struct Object*                                          m_pBlenderObject;
        struct Object*                                          m_pBlenderGroupObject;
        
index d6747bd1ba4e706a3b1249b2bb0189a206948ec4..e773a9571f111f313fe794bcad622fb20656d927 100644 (file)
@@ -296,11 +296,13 @@ void KX_KetsjiEngine::RenderDome()
                return;
 
        KX_SceneList::iterator sceneit;
-       for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
-       {
-               // do this only once per scene
-               (*sceneit)->UpdateMeshTransformations();
-       }
+
+       // This is now done incrementally in KX_Scene::CalculateVisibleMeshes()
+       //for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
+       //{
+       //      // do this only once per scene
+       //      (*sceneit)->UpdateMeshTransformations();
+       //}
 
        int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
        for (int i=0;i<n_renders;i++){
@@ -826,8 +828,8 @@ void KX_KetsjiEngine::Render()
                // pass the scene's worldsettings to the rasterizer
                SetWorldSettings(scene->GetWorldInfo());
 
-               // do this only once per scene
-               scene->UpdateMeshTransformations();
+               // this is now done incrementatlly in KX_Scene::CalculateVisibleMeshes
+               //scene->UpdateMeshTransformations();
 
                // shadow buffers
                RenderShadowBuffers(scene);
@@ -1119,16 +1121,13 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
 
 void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
 {
-       CListValue *objectlist = scene->GetObjectList();
+       CListValue *lightlist = scene->GetLightList();
        int i, drawmode;
 
        m_rendertools->SetAuxilaryClientInfo(scene);
 
-       for(i=0; i<objectlist->GetCount(); i++) {
-               KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i);
-
-               if(!gameobj->IsLight())
-                       continue;
+       for(i=0; i<lightlist->GetCount(); i++) {
+               KX_GameObject *gameobj = (KX_GameObject*)lightlist->GetValue(i);
 
                KX_LightObject *light = (KX_LightObject*)gameobj;
 
@@ -1268,9 +1267,6 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
        m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
        cam->SetModelviewMatrix(viewmat);
 
-       //redundant, already done in Render()
-       //scene->UpdateMeshTransformations();
-
        // The following actually reschedules all vertices to be
        // redrawn. There is a cache between the actual rescheduling
        // and this call though. Visibility is imparted when this call
index 0f90bfd8a02a34ddd3f3acd68754259f81879e58..777a7f326298e8a375aa38fa5d845bc65fcc8475 100644 (file)
@@ -102,8 +102,11 @@ void KX_LightObject::Update()
 {
        GPULamp *lamp;
 
-       if((lamp = GetGPULamp())) {
+       if((lamp = GetGPULamp()) != NULL && GetSGNode()) {
                float obmat[4][4];
+               // lights don't get their openGL matrix updated, do it now
+               if (GetSGNode()->IsDirty())
+                       GetOpenGLMatrix();
                double *dobmat = GetOpenGLMatrixPtr()->getPointer();
 
                for(int i=0; i<4; i++)
index 918c251599eddf860eaed9d9f734e2af47018866..2aa0ef921e97b7c33170cbc4d95c4cdbb26b44aa 100644 (file)
@@ -172,13 +172,18 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
                        rasty->SetLines(true);
                else
                        rasty->SetLines(false);
+               rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+               rasty->SetShinyness(m_shininess);
+               rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+               if (m_material)
+                       rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
        }
 
-       rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
-       rasty->SetShinyness(m_shininess);
-       rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
-       if (m_material)
-               rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
+       //rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
+       //rasty->SetShinyness(m_shininess);
+       //rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
+       //if (m_material)
+       //      rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
 }
 
 void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
index 1a571633b15cd1ac6cfeafd60153f2489d04fee5..57f736a6c09910e0a591c28390807225160ea406 100644 (file)
@@ -936,16 +936,17 @@ static PyObject* gPySetGLSLMaterialSetting(PyObject*,
 
        /* display lists and GLSL materials need to be remade */
        if(G.fileflags != fileflags) {
+               GPU_materials_free();
                if(gp_KetsjiEngine) {
                        KX_SceneList *scenes = gp_KetsjiEngine->CurrentScenes();
                        KX_SceneList::iterator it;
 
                        for(it=scenes->begin(); it!=scenes->end(); it++)
-                               if((*it)->GetBucketManager())
+                               if((*it)->GetBucketManager()) {
                                        (*it)->GetBucketManager()->ReleaseDisplayLists();
+                                       (*it)->GetBucketManager()->ReleaseMaterials();
+                               }
                }
-
-               GPU_materials_free();
        }
 
        Py_RETURN_NONE;
index d31d451f02e3f1012a53db4f816fca4fd9e36027..7280071cd1dee173ddaf50daa99b04a2b9c4b9bc 100644 (file)
@@ -488,6 +488,8 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
 
        // this is the list of object that are send to the graphics pipeline
        m_objectlist->Add(newobj->AddRef());
+       if (newobj->IsLight())
+               m_lightlist->Add(newobj->AddRef());
        newobj->AddMeshUser();
 
        // logic cannot be replicated, until the whole hierarchy is replicated.
index 69a167e54a946c7d4ec2ede00fd7332fe50077d2..143209f5a54abd6dd2081e9fbbe17f5216bcb792 100644 (file)
@@ -30,6 +30,7 @@ SET(INC
   .
   ../../../source/kernel/gen_system
   ../../../source/blender/makesdna
+  ../../../source/gameengine/SceneGraph
   ../../../intern/string
   ../../../intern/moto/include
   ../../../extern/glew/include
index fa6cf94c4b65a0a54466b968cc90449f803e4683..eafa2ded2f20506c397f440ae8d7f20fa7567a25 100644 (file)
@@ -41,6 +41,7 @@ CPPFLAGS += -I$(NAN_STRING)/include
 CPPFLAGS += -I$(NAN_MOTO)/include
 CPPFLAGS += -I../../kernel/gen_system
 CPPFLAGS += -I../../blender/makesdna
+CPPFLAGS += -I../SceneGraph
 CPPFLAGS += -I../BlenderRoutines
 CPPFLAGS += -I../Expressions
 
index ec290f89d9ec8a5f67f687bb27ab150bb96de74b..a111ac2786f3bc4c86316c477cb858ba65331495 100644 (file)
@@ -113,16 +113,38 @@ void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList
        const MT_Vector3 pnorm(cameratrans.getBasis()[2]);
 
        for (bit = buckets.begin(); bit != buckets.end(); ++bit)
+       {
+#if 1
+               SG_DList::iterator<RAS_MeshSlot> mit((*bit)->GetActiveMeshSlots());
+               for(mit.begin(); !mit.end(); ++mit)
+                       size++;
+#else
                for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
                        if (!mit->IsCulled())
                                size++;
+#endif
+       }
 
        slots.resize(size);
 
        for (bit = buckets.begin(); bit != buckets.end(); ++bit)
+       {
+#if 1
+               RAS_MaterialBucket* bucket = *bit;
+               RAS_MeshSlot* ms;
+               // remove the mesh slot form the list, it culls them automatically for next frame
+               for(ms = bucket->GetNextActiveMeshSlot();
+                       ms!= NULL;
+                       ms = bucket->GetNextActiveMeshSlot())
+               {
+                       slots[i++].set(ms, bucket, pnorm);
+               }
+#else
                for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
                        if (!mit->IsCulled())
                                slots[i++].set(&*mit, *bit, pnorm);
+#endif
+       }
                
        if(alpha)
                sort(slots.begin(), slots.end(), backtofront());
@@ -161,11 +183,28 @@ void RAS_BucketManager::RenderSolidBuckets(
        const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
 {
        BucketList::iterator bit;
-       list<RAS_MeshSlot>::iterator mit;
 
        rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
 
        for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
+#if 1
+               RAS_MaterialBucket* bucket = *bit;
+               RAS_MeshSlot* ms;
+               // remove the mesh slot form the list, it culls them automatically for next frame
+               for(ms = bucket->GetNextActiveMeshSlot();
+                       ms!= NULL;
+                       ms = bucket->GetNextActiveMeshSlot())
+               {
+                       rendertools->SetClientObject(rasty, ms->m_clientObj);
+                       while (bucket->ActivateMaterial(cameratrans, rasty, rendertools))
+                               bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *ms);
+
+                       // make this mesh slot culled automatically for next frame
+                       // it will be culled out by frustrum culling
+                       ms->SetCulled(true);
+               }
+#else
+               list<RAS_MeshSlot>::iterator mit;
                for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
                        if (mit->IsCulled())
                                continue;
@@ -179,6 +218,7 @@ void RAS_BucketManager::RenderSolidBuckets(
                        // it will be culled out by frustrum culling
                        mit->SetCulled(true);
                }
+#endif
        }
        
        /* this code draws meshes order front-to-back instead to reduce overdraw.
@@ -276,3 +316,21 @@ void RAS_BucketManager::ReleaseDisplayLists(RAS_IPolyMaterial *mat)
        }
 }
 
+void RAS_BucketManager::ReleaseMaterials(RAS_IPolyMaterial * mat)
+{
+       BucketList::iterator bit;
+       list<RAS_MeshSlot>::iterator mit;
+
+       for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
+               if (mat == NULL || (mat == (*bit)->GetPolyMaterial())) {
+                       (*bit)->GetPolyMaterial()->ReleaseMaterial();
+               }
+       }
+       
+       for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+               if (mat == NULL || (mat == (*bit)->GetPolyMaterial())) {
+                       (*bit)->GetPolyMaterial()->ReleaseMaterial();
+               }
+       }
+}
+
index 74526f365a000b0d66ada697043ff3060954221b..2b81ddd3c826b7965e020ccc6d7585479c0985db 100644 (file)
@@ -58,6 +58,7 @@ public:
        void OptimizeBuckets(MT_Scalar distance);
        
        void ReleaseDisplayLists(RAS_IPolyMaterial * material = NULL);
+       void ReleaseMaterials(RAS_IPolyMaterial * material = NULL);
 
 private:
        void OrderBuckets(const MT_Transform& cameratrans, BucketList& buckets, vector<sortedmeshslot>& slots, bool alpha);
index c10e4040a92c335cfd3db1ca801adbc2c1fc5e7e..f2fd96d63e95685807008ab225b59814c06e3764 100644 (file)
@@ -227,6 +227,9 @@ Scene* RAS_IPolyMaterial::GetBlenderScene() const
        return NULL;
 }
 
+void RAS_IPolyMaterial::ReleaseMaterial()
+{
+}
 
 unsigned int   RAS_IPolyMaterial::GetFlag() const
 {
index 1bc03a1db05ba027695957c6b989351697b42c17..decd93c3d13e8835a0ca226c4f6d8952fe1cf885 100644 (file)
@@ -160,6 +160,7 @@ public:
 
        virtual Material*   GetBlenderMaterial() const;
        virtual Scene*          GetBlenderScene() const;
+       virtual void            ReleaseMaterial();
        virtual void            GetMaterialRGBAColor(unsigned char *rgba) const;
        virtual bool            UsesLighting(RAS_IRasterizer *rasty) const;
        virtual bool            UsesObjectColor() const;
index d63e9c984156806810377a5e2b89885824b8c8ea..db6394c1ec01d68fc38201f065cf25ce1d869604 100644 (file)
@@ -42,7 +42,7 @@
 
 /* mesh slot */
 
-RAS_MeshSlot::RAS_MeshSlot()
+RAS_MeshSlot::RAS_MeshSlot() : SG_QList()
 {
        m_clientObj = NULL;
        m_pDeformer = NULL;
@@ -82,7 +82,7 @@ RAS_MeshSlot::~RAS_MeshSlot()
        }
 }
 
-RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot)
+RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot) : SG_QList()
 {
        RAS_DisplayArrayList::iterator it;
 
@@ -461,21 +461,21 @@ bool RAS_MeshSlot::Split(bool force)
        return false;
 }
 
+
+#ifdef USE_SPLIT       
 bool RAS_MeshSlot::IsCulled()
 {
-       list<RAS_MeshSlot*>::iterator it;
-
        if(m_joinSlot)
                return true;
        if(!m_bCulled)
                return false;
-#ifdef USE_SPLIT       
+       list<RAS_MeshSlot*>::iterator it;
        for(it=m_joinedSlots.begin(); it!=m_joinedSlots.end(); it++)
                if(!(*it)->m_bCulled)
                        return false;
-#endif 
        return true;
 }
+#endif 
 
 /* material bucket sorting */
 
index b07f86b079e26e61e15b3990fd877b25f0dcea60..8db75b8b735d8d552fd357c5e30f018eef0d8664 100644 (file)
@@ -32,6 +32,7 @@
 #include "RAS_TexVert.h"
 #include "GEN_Map.h"
 #include "STR_HashedString.h"
+#include "SG_QList.h"
 
 #include "MT_Transform.h"
 #include "RAS_IPolygonMaterial.h"
@@ -89,7 +90,9 @@ public:
 /* Entry of a RAS_MeshObject into RAS_MaterialBucket */
 typedef std::vector<RAS_DisplayArray*> RAS_DisplayArrayList;
 
-class RAS_MeshSlot
+// The QList is used to link the mesh slots to the object
+// The DList is used to link the visible mesh slots to the material bucket
+class RAS_MeshSlot : public SG_QList
 {
        friend class RAS_ListRasterizer;
 private:
@@ -160,7 +163,11 @@ public:
        bool Split(bool force=false);
        bool Join(RAS_MeshSlot *target, MT_Scalar distance);
        bool Equals(RAS_MeshSlot *target);
+#ifdef USE_SPLIT
        bool IsCulled();
+#else
+       bool IsCulled() { return m_bCulled; }
+#endif
        void SetCulled(bool culled) { m_bCulled = culled; }
 };
 
@@ -171,7 +178,6 @@ class RAS_MeshMaterial
 public:
        RAS_MeshSlot *m_baseslot;
        class RAS_MaterialBucket *m_bucket;
-
        GEN_Map<GEN_HashedPtr,RAS_MeshSlot*> m_slots;
 };
 
@@ -208,10 +214,23 @@ public:
        class RAS_MeshSlot* CopyMesh(class RAS_MeshSlot *ms);
        void                            RemoveMesh(class RAS_MeshSlot* ms);
        void                            Optimize(MT_Scalar distance);
+       void                            ActivateMesh(RAS_MeshSlot* slot)
+       {
+               m_activeMeshSlotsHead.AddBack(slot);
+       }
+       SG_DList&                       GetActiveMeshSlots()
+       {
+               return m_activeMeshSlotsHead;
+       }
+       RAS_MeshSlot*           GetNextActiveMeshSlot()
+       {
+               return (RAS_MeshSlot*)m_activeMeshSlotsHead.Remove();
+       }
 
 private:
-       list<RAS_MeshSlot>                      m_meshSlots;
+       list<RAS_MeshSlot>                      m_meshSlots;                    // all the mesh slots
        RAS_IPolyMaterial*                      m_material;
+       SG_DList                                        m_activeMeshSlotsHead;  // only those which must be rendered
        
 };
 
index 278aa9c75e2fa30903118f68e563a0f25fb4cd07..c3223cb944890b458f2d9b2d4ebcbe7fd03c2aa2 100644 (file)
@@ -242,6 +242,7 @@ RAS_Polygon* RAS_MeshObject::AddPolygon(RAS_MaterialBucket *bucket, int numverts
                RAS_MeshMaterial meshmat;
                meshmat.m_bucket = bucket;
                meshmat.m_baseslot = meshmat.m_bucket->AddMesh(numverts);
+               meshmat.m_baseslot->m_mesh = this;
                m_materials.push_back(meshmat);
                mmat = &m_materials.back();
        }
@@ -381,7 +382,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid,
        return NULL;
 }
 
-void RAS_MeshObject::AddMeshUser(void *clientobj)
+void RAS_MeshObject::AddMeshUser(void *clientobj, SG_QList *head)
 {
        list<RAS_MeshMaterial>::iterator it;
 
@@ -391,6 +392,7 @@ void RAS_MeshObject::AddMeshUser(void *clientobj)
                RAS_MeshSlot *ms = it->m_bucket->CopyMesh(it->m_baseslot);
                ms->m_clientObj = clientobj;
                it->m_slots.insert(clientobj, ms);
+               head->QAddBack(ms);
        }
 }
 
@@ -402,7 +404,7 @@ void RAS_MeshObject::UpdateBuckets(void* clientobj,
                                                           bool culled)
 {
        list<RAS_MeshMaterial>::iterator it;
-
+       
        for(it = m_materials.begin();it!=m_materials.end();++it) {
                RAS_MeshSlot **msp = it->m_slots[clientobj];
 
@@ -417,6 +419,8 @@ void RAS_MeshObject::UpdateBuckets(void* clientobj,
                ms->m_RGBAcolor = rgbavec;
                ms->m_bVisible = visible;
                ms->m_bCulled = culled || !visible;
+               if (!ms->m_bCulled)
+                       ms->m_bucket->ActivateMesh(ms);
 
                /* split if necessary */
 #ifdef USE_SPLIT
index cc50f9c783d1d6f9c1b188bb0c087017873d7fc5..a2283b9bc5d7333922ecc45c062ecbbe34d7e4c3 100644 (file)
@@ -130,7 +130,7 @@ public:
        RAS_Polygon*            GetPolygon(int num) const;
        
        /* buckets */
-       virtual void            AddMeshUser(void *clientobj);
+       virtual void            AddMeshUser(void *clientobj, SG_QList *head);
        virtual void            UpdateBuckets(
                                                        void* clientobj,
                                                        double* oglmatrix,
index d061a449b7e0c15ba12af550ffe1bc60c6f9d3b0..fe3d0f6aeea33fc899285983c5df6f68cf1f6f6d 100644 (file)
@@ -32,6 +32,7 @@ SET(INC
   ../../../../intern/moto/include
   ../../../../source/gameengine/Rasterizer
   ../../../../source/gameengine/Ketsji
+  ../../../../source/gameengine/SceneGraph
   ../../../../extern/glew/include
   ../../../../source/blender/gpu
   ../../../../source/blender/makesdna
index b55f64928059a9c7cb44588f7d0128b363273027..0327714dc5fdf8e7098e4060bf733bca637ba95b 100644 (file)
@@ -47,6 +47,7 @@ CPPFLAGS += -I../../../blender/blenlib
 CPPFLAGS += -I../../../blender/blenkernel
 CPPFLAGS += -I../../BlenderRoutines
 CPPFLAGS += -I../../Ketsji
+CPPFLAGS += -I../../SceneGraph
 CPPFLAGS += -I..
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 
index 06c61fb4b097d2b025660a76d561e90735f932b6..3ae4522f8e1d375dcf471dcd4e5658a163d87cf6 100644 (file)
@@ -214,7 +214,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
        // workaround: note how we do not use vertex arrays for making display
        // lists, since glVertexAttribPointerARB doesn't seem to work correct
        // in display lists on ATI? either a bug in the driver or in Blender ..
-       if (mUseVertexArrays && !localSlot && !ms.m_pDerivedMesh)
+       if (mUseVertexArrays && /*!localSlot &&*/ !ms.m_pDerivedMesh)
                RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
        else
                RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
index 314630297e09937432fda930121f63536c3bac30..d4b029ea34d37dc3fe84bb1c2f17bd8e2634bbe5 100644 (file)
@@ -5,7 +5,7 @@ sources = env.Glob('*.cpp')
 
 incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines '
 incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC']
-incs += ' #source/blender/gameengine/Ketsji #source/blender/makesdna #source/blender/blenkernel'
+incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel'
 incs += ' #intern/guardedalloc #source/blender/blenlib'
 
 cxxflags = []
index a16a04b85145f2d7e2a9bfc044d1d672c6ab9266..771d3399485091a5098713b71d5a0bf66bb467b8 100644 (file)
@@ -4,7 +4,7 @@ Import ('env')
 sources = env.Glob('*.cpp')
 
 
-incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/blender/blenkernel #source/blender/makesdna'
+incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna'
 incs += ' ' + env['BF_PYTHON_INC']
 
 cxxflags = []
index d682be679e69b7b21e3a0f6be8b4a1837fca357a..dc5afa2ee99f867be76a938a109a26f26f9c3b1f 100644 (file)
@@ -83,6 +83,10 @@ public:
     { 
         m_flink = m_blink = this; 
     }
+       SG_DList(const SG_DList& other)
+       {
+        m_flink = m_blink = this; 
+       }
     virtual ~SG_DList() 
     {
                Delink();
index efaa613bbb9d5ae452f2d4c8905a06c61f2624c8..4a254ac36a4747ba3f5aff00b0467652cc5205ae 100644 (file)
@@ -84,6 +84,10 @@ public:
     { 
         m_fqlink = m_bqlink = this; 
     }
+       SG_QList(const SG_QList& other) : SG_DList()
+       {
+        m_fqlink = m_bqlink = this; 
+       }
     virtual ~SG_QList() 
     {
                QDelink();
index b79d4bac91a79effa3f5149bfe027fb4162b4f38..5a47f07f5737c3468014ab6edd499b64d454aa18 100644 (file)
@@ -56,7 +56,8 @@ SG_Spatial(
        
        m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)),
        m_radius(1.0),
-       m_modified(false)
+       m_modified(false),
+       m_ogldirty(false)
 {
 }
 
@@ -76,7 +77,9 @@ SG_Spatial(
        m_parent_relation(NULL),
        
        m_bbox(other.m_bbox),
-       m_radius(other.m_radius)
+       m_radius(other.m_radius),
+       m_modified(false),
+       m_ogldirty(false)
 {
        // duplicate the parent relation for this object
        m_parent_relation = other.m_parent_relation->NewCopy();
index eb1e87fbf19d5f2d4146eb9ad805485f6cbe5101..d1fc95cceac61519476a34794649eb38694ffe1b 100644 (file)
@@ -63,19 +63,24 @@ protected:
        SG_BBox                 m_bbox;
        MT_Scalar               m_radius;
        bool                    m_modified;
+       bool                    m_ogldirty;             // true if the openGL matrix for this object must be recomputed
 
 public:
 
        inline void ClearModified() 
        { 
                m_modified = false; 
+               m_ogldirty = true;
        }
        inline void SetModified()
        {
                m_modified = true;
                ActivateScheduleUpdateCallback();
        }
-
+       inline void ClearDirty()
+       {
+               m_ogldirty = false;
+       }
        /** 
         * Define the realtionship this node has with it's parent
         * node. You should pass an unshared instance of an SG_ParentRelation
@@ -233,6 +238,7 @@ public:
        MT_Scalar Radius() const { return m_radius; }
        void SetRadius(MT_Scalar radius) { m_radius = radius; }
        bool IsModified() { return m_modified; }
+       bool IsDirty() { return m_ogldirty; }
        
 protected:
        friend class SG_Controller;
index 1e3a84c1efbce20181834e5f5970eedf3cdc4b70..db4461325d83c5d9bcd7520707d834d0e6e0e3ca 100644 (file)
@@ -255,9 +255,6 @@ void ImageRender::Render()
     // restore the stereo mode now that the matrix is computed
     m_rasterizer->SetStereoMode(stereomode);
 
-    // do not update the mesh transform, we don't want to do it more than once per frame
-    //m_scene->UpdateMeshTransformations();
-
        m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
 
        m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
index 6dbed1fb7a8d6159451ba2ec0213cf7cfcc5a6c2..ff9de465a347605b07181b54db51cd3208e9b9c8 100644 (file)
 // is a 32-bit integer, use all the bits of the pointer as long
 // as possible.
 //
-
+#if 1
 unsigned int GEN_Hash(void * inDWord)
 {
        uintptr_t key = (uintptr_t)inDWord;
-
+#if 0
+       // this is way too complicated
        key += ~(key << 16);
        key ^=  (key >>  5);
        key +=  (key <<  3);
@@ -53,4 +54,8 @@ unsigned int GEN_Hash(void * inDWord)
        key ^=  (key >> 17);
 
        return (unsigned int)(key & 0xffffffff);
+#else
+       return (unsigned int)(key ^ (key>>4));
+#endif
 }
+#endif
\ No newline at end of file