[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15469] branches/apricot/source: Apricot Branch
Brecht Van Lommel
brechtvanlommel at pandora.be
Mon Jul 7 15:58:01 CEST 2008
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. @@
More information about the Bf-blender-cvs
mailing list