Revision: 15469
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15469
Author:   blendix
Date:     2008-07-07 15:57:29 +0200 (Mon, 07 Jul 2008)

Log Message:
-----------
Apricot Branch
==============

Some optimizations:
* Only Apply mesh deformer if the mesh is actually modified, once
  per frame, this was done too often before.
* GLSL shader binding is now faster, only goes over dynamics inputs
  instead of all of them, and frees more memory after compiling too.

Modified Paths:
--------------
    branches/apricot/source/blender/gpu/intern/gpu_codegen.c
    branches/apricot/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    branches/apricot/source/gameengine/Converter/BL_MeshDeformer.cpp
    branches/apricot/source/gameengine/Converter/BL_MeshDeformer.h
    branches/apricot/source/gameengine/Converter/BL_ShapeDeformer.h
    branches/apricot/source/gameengine/Converter/BL_SkinDeformer.cpp
    branches/apricot/source/gameengine/Converter/BL_SkinDeformer.h
    branches/apricot/source/gameengine/Ketsji/KX_Scene.cpp

Modified: branches/apricot/source/blender/gpu/intern/gpu_codegen.c
===================================================================
--- branches/apricot/source/blender/gpu/intern/gpu_codegen.c    2008-07-07 
11:58:09 UTC (rev 15468)
+++ branches/apricot/source/blender/gpu/intern/gpu_codegen.c    2008-07-07 
13:57:29 UTC (rev 15469)
@@ -152,13 +152,14 @@
        char attribname[32];    /* attribute name */
        int attribfirst;                /* this is the first one that is bound 
*/
        GPUBuiltin builtin;             /* builtin uniform */
+
+       char shadername[32];    /* name in shader */
 } GPUInput;
 
 struct GPUPass {
        struct GPUPass *next, *prev;
 
-       ListBase nodes;
-       int firstbind;
+       ListBase inputs;
        struct GPUOutput *output;
        struct GPUShader *shader;
 };
@@ -730,92 +731,121 @@
        return pass->shader;
 }
 
-void GPU_pass_bind(GPUPass *pass)
+void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
 {
+       GPUShader *shader = pass->shader;
        GPUNode *node;
-       GPUInput *input;
-       GPUShader *shader = pass->shader;
-       ListBase *nodes = &pass->nodes;
-       DynStr *ds;
-       char *name;
+       GPUInput *next, *input;
+       ListBase *inputs = &pass->inputs;
+       int extract;
 
-       if (!shader)
+       memset(inputs, 0, sizeof(*inputs));
+
+       if(!shader)
                return;
 
-       /* create textures first, otherwise messes up multitexture state for
-        * following textures*/
-       for (node=nodes->first; node; node=node->next)
-               for (input=node->inputs.first; input; input=input->next)
-                       if (input->ima)
-                               input->tex = 
GPU_texture_from_blender(input->ima, input->iuser);
-
        GPU_shader_bind(shader);
 
        for (node=nodes->first; node; node=node->next) {
-               for (input=node->inputs.first; input; input=input->next) {
+               for (input=node->inputs.first; input; input=next) {
+                       next = input->next;
+
                        /* attributes don't need to be bound, they already have
                         * an id that the drawing functions will use */
                        if(input->source == GPU_SOURCE_ATTRIB ||
                           input->source == GPU_SOURCE_BUILTIN)
                                continue;
 
-                       /* pass samplers and uniforms to opengl */
-                       if (input->link)
-                               input->tex = NULL; /* input->link->tex; */
-
-                       ds = BLI_dynstr_new();
-                       if (input->tex)
-                               BLI_dynstr_printf(ds, "samp%d", input->texid);
+                       if (input->ima || input->tex)
+                               snprintf(input->shadername, 
sizeof(input->shadername), "samp%d", input->texid);
                        else
-                               BLI_dynstr_printf(ds, "unf%d", input->id);
-                       name = BLI_dynstr_get_cstring(ds);
-                       BLI_dynstr_free(ds);
+                               snprintf(input->shadername, 
sizeof(input->shadername), "unf%d", input->id);
 
-                       if (input->tex) {
-                               if (input->bindtex) {
-                                       if(pass->firstbind);
-                                       GPU_texture_bind(input->tex, 
input->texid);
-                                       GPU_shader_uniform_texture(shader, 
name, input->tex);
-                               }
+                       /* pass non-dynamic uniforms to opengl */
+                       extract = 0;
+
+                       if(input->ima || input->tex) {
+                               if (input->bindtex)
+                                       extract = 1;
                        }
                        else if (input->arraysize) {
-                               if(pass->firstbind || input->dynamicvec)
-                                       GPU_shader_uniform_vector(shader, name, 
input->type,
-                                               input->arraysize,
-                                               (input->dynamicvec)? 
input->dynamicvec: input->vec);
+                               if(input->dynamicvec)
+                                       extract = 1;
+                               else
+                                       GPU_shader_uniform_vector(shader, 
input->shadername, input->type,
+                                               input->arraysize, input->vec);
                        }
                        else {
-                               if(pass->firstbind || input->dynamicvec)
-                                       GPU_shader_uniform_vector(shader, name, 
input->type, 1,
-                                               (input->dynamicvec)? 
input->dynamicvec: input->vec);
+                               if(input->dynamicvec)
+                                       extract = 1;
+                               else
+                                       GPU_shader_uniform_vector(shader, 
input->shadername, input->type, 1,
+                                               input->vec);
                        }
 
-                       MEM_freeN(name);
+                       /* extract nodes */
+                       if(extract) {
+                               BLI_remlink(&node->inputs, input);
+                               BLI_addtail(inputs, input);
+                       }
                }
        }
 
-       pass->firstbind = 0;
+       GPU_shader_unbind(shader);
 }
 
-void GPU_pass_unbind(GPUPass *pass)
+void GPU_pass_bind(GPUPass *pass)
 {
-       GPUNode *node;
        GPUInput *input;
        GPUShader *shader = pass->shader;
-       ListBase *nodes = &pass->nodes;
+       ListBase *inputs = &pass->inputs;
 
        if (!shader)
                return;
 
-       for (node=nodes->first; node; node=node->next) {
-               for (input=node->inputs.first; input; input=input->next) {
-                       if (input->tex)
-                               if(input->bindtex)
-                                       GPU_texture_unbind(input->tex);
-                       if (input->link || input->ima)
-                               input->tex = 0;
+       /* create textures first, otherwise messes up multitexture state for
+        * following textures*/
+       for (input=inputs->first; input; input=input->next)
+               if (input->ima)
+                       input->tex = GPU_texture_from_blender(input->ima, 
input->iuser);
+
+       GPU_shader_bind(shader);
+
+       /* pass dynamic inputs to opengl, others were already done */
+       for (input=inputs->first; input; input=input->next) {
+               if(input->ima || input->tex) {
+                       if(input->tex) {
+                               GPU_texture_bind(input->tex, input->texid);
+                               GPU_shader_uniform_texture(shader, 
input->shadername, input->tex);
+                       }
                }
+               else if (input->arraysize) {
+                       GPU_shader_uniform_vector(shader, input->shadername, 
input->type,
+                               input->arraysize, input->dynamicvec);
+               }
+               else {
+                       GPU_shader_uniform_vector(shader, input->shadername, 
input->type, 1,
+                               input->dynamicvec);
+               }
        }
+}
+
+void GPU_pass_unbind(GPUPass *pass)
+{
+       GPUInput *input;
+       GPUShader *shader = pass->shader;
+       ListBase *inputs = &pass->inputs;
+
+       if (!shader)
+               return;
+
+       for (input=inputs->first; input; input=input->next) {
+               if (input->tex)
+                       if(input->bindtex)
+                               GPU_texture_unbind(input->tex);
+               if (input->ima)
+                       input->tex = 0;
+       }
        
        GPU_shader_unbind(shader);
 }
@@ -975,26 +1005,33 @@
        BLI_addtail(&node->outputs, output);
 }
 
-void GPU_node_free(GPUNode *node)
+void GPU_inputs_free(ListBase *inputs)
 {
        GPUInput *input;
-       GPUOutput *output;
 
-       for (input=node->inputs.first; input; input=input->next) {
-               if (input->link) {
+       for(input=inputs->first; input; input=input->next) {
+               if(input->link) {
                        GPU_node_link_free(input->link);
                }
                else if(input->tex && !input->dynamictex)
                        GPU_texture_free(input->tex);
        }
 
+       BLI_freelistN(inputs);
+}
+
+void GPU_node_free(GPUNode *node)
+{
+       GPUOutput *output;
+
+       GPU_inputs_free(&node->inputs);
+
        for (output=node->outputs.first; output; output=output->next)
                if (output->link) {
                        output->link->output = NULL;
                        GPU_node_link_free(output->link);
                }
 
-       BLI_freelistN(&node->inputs);
        BLI_freelistN(&node->outputs);
        MEM_freeN(node);
 }
@@ -1315,13 +1352,12 @@
        /* create pass */
        pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
 
-       pass->nodes = *nodes;
        pass->output = outlink->output;
        pass->shader = shader;
-       pass->firstbind = 1;
 
-       /* take ownership over nodes */
-       memset(nodes, 0, sizeof(*nodes));
+       /* extract dynamic inputs and throw away nodes */
+       GPU_nodes_extract_dynamic_inputs(pass, nodes);
+       GPU_nodes_free(nodes);
 
        return pass;
 }
@@ -1329,7 +1365,7 @@
 void GPU_pass_free(GPUPass *pass)
 {
        GPU_shader_free(pass->shader);
-       GPU_nodes_free(&pass->nodes);
+       GPU_inputs_free(&pass->inputs);
        MEM_freeN(pass);
 }
 

Modified: 
branches/apricot/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- branches/apricot/source/gameengine/Converter/BL_BlenderDataConversion.cpp   
2008-07-07 11:58:09 UTC (rev 15468)
+++ branches/apricot/source/gameengine/Converter/BL_BlenderDataConversion.cpp   
2008-07-07 13:57:29 UTC (rev 15469)
@@ -1681,13 +1681,15 @@
                        if (bHasArmature)
                                dcont->LoadShapeDrivers(ob->parent);
                } else if (bHasArmature) {
-                       BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, 
(BL_SkinMeshObject*)meshobj );                         
+                       BL_SkinDeformer *dcont = new 
BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
+                                                                               
                                        ob, (BL_SkinMeshObject*)meshobj);
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = 
dcont;
                } else if (bHasDvert) {
                        // this case correspond to a mesh that can potentially 
deform but not with the
                        // object to which it is attached for the moment. A 
skin mesh was created in
                        // BL_ConvertMesh() so must create a deformer too!
-                       BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, 
(BL_SkinMeshObject*)meshobj );
+                       BL_MeshDeformer *dcont = new 
BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
+                                                                               
                                  ob, (BL_SkinMeshObject*)meshobj);
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = 
dcont;
                }
                

Modified: branches/apricot/source/gameengine/Converter/BL_MeshDeformer.cpp
===================================================================
--- branches/apricot/source/gameengine/Converter/BL_MeshDeformer.cpp    
2008-07-07 11:58:09 UTC (rev 15468)
+++ branches/apricot/source/gameengine/Converter/BL_MeshDeformer.cpp    
2008-07-07 13:57:29 UTC (rev 15469)
@@ -39,6 +39,7 @@
 #endif
 
 #include "RAS_IPolygonMaterial.h"
+#include "BL_DeformableGameObject.h"
 #include "BL_MeshDeformer.h"
 #include "BL_SkinMeshObject.h"
 #include "DNA_mesh_types.h"
@@ -47,7 +48,7 @@
 #include "GEN_Map.h"
 #include "STR_HashedString.h"
 
-bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat)
+bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*)
 {
        size_t                  i, j, index;
        vecVertexArray  array;
@@ -57,23 +58,37 @@
        RAS_TexVert *tv;
        MVert   *mvert;
 
-       // For each material
-       array = m_pMeshObject->GetVertexCache(mat);
-       mvarray = m_pMeshObject->GetMVertCache(mat);
-       diarray = m_pMeshObject->GetDIndexCache(mat);
+       // only apply once per frame if the mesh is actually modified
+       if(m_pMeshObject->MeshModified() &&
+          m_lastDeformUpdate != m_gameobj->GetLastFrame()) {
+               // For each material
+               for(RAS_MaterialBucket::Set::iterator mit = 
m_pMeshObject->GetFirstMaterial();
+                       mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
+                       RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
 
-       // For each array
-       for (i=0; i<array.size(); i++){
-               //      For each vertex
-               for (j=0; j<array[i]->size(); j++){
-                       tv = &((*array[i])[j]);
-                       index = ((*diarray[i])[j]);
+                       array = m_pMeshObject->GetVertexCache(mat);
+                       mvarray = m_pMeshObject->GetMVertCache(mat);
+                       diarray = m_pMeshObject->GetDIndexCache(mat);
 
-                       mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]);
-                       tv->SetXYZ(MT_Point3(mvert->co));
+                       // For each array
+                       for (i=0; i<array.size(); i++){
+                               //      For each vertex
+                               for (j=0; j<array[i]->size(); j++){
+                                       tv = &((*array[i])[j]);
+                                       index = ((*diarray[i])[j]);
+
+                                       mvert = 
&(m_bmesh->mvert[((*mvarray[i])[index])]);
+                                       tv->SetXYZ(MT_Point3(mvert->co));
+                               }
+                       }
                }
+
+               m_lastDeformUpdate = m_gameobj->GetLastFrame();
+
+               return true;
        }
-       return true;
+
+       return false;
 }
 
 BL_MeshDeformer::~BL_MeshDeformer()

Modified: branches/apricot/source/gameengine/Converter/BL_MeshDeformer.h

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to