diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-07-10 16:47:20 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-07-10 16:47:20 +0400 |
commit | 99fdf27af92b9bd9d05c108f2c2c8a240c5536bc (patch) | |
tree | 0e7d2c4b425a5d3906a7841e5919e384e0bc27a4 /source | |
parent | 3d7358539df4526ffc2c2bbd40cf2001c5acf374 (diff) |
Sync with Apricot Game Engine
=============================
* Clean up and optimizations in skinned/deformed mesh code.
* Compatibility fixes and clean up in the rasterizer.
* Changes related to GLSL shadow buffers which should have no
effect, to keep the code in sync with apricot.
Diffstat (limited to 'source')
41 files changed, 751 insertions, 758 deletions
diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 2a4672e3052..4aea0df74b9 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -34,6 +34,8 @@ #include <stdio.h> #include <string.h> +#include "GL/glew.h" + #ifdef WIN32 #include <windows.h> /* need to include windows.h so _WIN32_IE is defined */ #ifndef _WIN32_IE diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 230d6b262c6..ed6ea7c5f6a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -26,6 +26,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "GL/glew.h" #include "KX_BlenderGL.h" #ifdef HAVE_CONFIG_H @@ -44,7 +45,6 @@ #include "BMF_Api.h" -#include "GL/glew.h" #include "BIF_gl.h" #include "BL_Material.h" // MAXTEX diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d8b157cb5b4..f3e22cd297a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -312,11 +312,13 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, MTFace* tface, + const char *tfaceName, MFace* mface, MCol* mmcol, int lightlayer, Object* blenderobj, - MTF_localLayer *layers) + MTF_localLayer *layers, + bool glslmat) { //this needs some type of manager BL_Material *material = new BL_Material(); @@ -335,7 +337,7 @@ BL_Material* ConvertMaterial( if(validmat) { // use vertex colors by explicitly setting - if(mat->mode &MA_VERTEXCOLP) + if(mat->mode &MA_VERTEXCOLP || glslmat) type = 0; // use lighting? @@ -558,6 +560,7 @@ BL_Material* ConvertMaterial( } else { int valid = 0; + // check for tface tex to fallback on if( validface ){ @@ -590,6 +593,7 @@ BL_Material* ConvertMaterial( } MT_Point2 uv[4]; MT_Point2 uv2[4]; + const char *uvName = "", *uv2Name = ""; uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); @@ -616,6 +620,8 @@ BL_Material* ConvertMaterial( if (mface->v4) uv[3] = MT_Point2(tface->uv[3]); + + uvName = tfaceName; } else { // nothing at all @@ -641,39 +647,38 @@ BL_Material* ConvertMaterial( isFirstSet = false; else { - MT_Point2 uvSet[4]; for (int lay=0; lay<MAX_MTFACE; lay++) { MTF_localLayer& layer = layers[lay]; if (layer.face == 0) break; - - bool processed = false; if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) { + MT_Point2 uvSet[4]; + uvSet[0] = MT_Point2(layer.face->uv[0]); uvSet[1] = MT_Point2(layer.face->uv[1]); uvSet[2] = MT_Point2(layer.face->uv[2]); if (mface->v4) uvSet[3] = MT_Point2(layer.face->uv[3]); + else + uvSet[3] = MT_Point2(0.0f, 0.0f); - processed = true; - } - - if (!processed) continue; - - if (isFirstSet) - { - uv[0] = uvSet[0]; uv[1] = uvSet[1]; - uv[2] = uvSet[2]; uv[3] = uvSet[3]; - isFirstSet = false; - } - else - { - uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; - uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; - map.mapping |= USECUSTOMUV; + if (isFirstSet) + { + uv[0] = uvSet[0]; uv[1] = uvSet[1]; + uv[2] = uvSet[2]; uv[3] = uvSet[3]; + isFirstSet = false; + uvName = layer.name; + } + else + { + uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; + uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; + map.mapping |= USECUSTOMUV; + uv2Name = layer.name; + } } } } @@ -693,9 +698,8 @@ BL_Material* ConvertMaterial( } material->SetConversionRGB(rgb); - material->SetConversionUV(uv); - material->SetConversionUV2(uv2); - + material->SetConversionUV(uvName, uv); + material->SetConversionUV2(uv2Name, uv2); material->ras_mode |= (mface->v4==0)?TRIANGLE:0; if(validmat) @@ -797,6 +801,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MFace* mface = static_cast<MFace*>(mesh->mface); MTFace* tface = static_cast<MTFace*>(mesh->mtface); + const char *tfaceName = ""; MCol* mmcol = mesh->mcol; MT_assert(mface || mesh->totface == 0); @@ -832,14 +837,14 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;; layers[validLayers].name = mesh->fdata.layers[i].name; + if(tface == layers[validLayers].face) + tfaceName = layers[validLayers].name; validLayers++; } } meshobj->SetName(mesh->id.name); meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert); - if(skinMesh) - ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.resize(mesh->totvert); for (int f=0;f<mesh->totface;f++,mface++) { @@ -898,8 +903,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* else ma = give_current_material(blenderobj, 1); - bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj, layers); - bl_mat->glslmat = converter->GetGLSLMaterials(); + bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); // set the index were dealing with bl_mat->material_index = (int)mface->mat_nr; @@ -1059,35 +1063,25 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* int nverts = mface->v4?4:3; int vtxarray = meshobj->FindVertexArray(nverts,polymat); RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray); - if (skinMesh) { - int d1, d2, d3, d4=0; - bool flat; + bool flat; + + if (skinMesh) { /* If the face is set to solid, all fnors are the same */ if (mface->flag & ME_SMOOTH) flat = false; else flat = true; - - d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat); - d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat); - d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat); - if (nverts==4) - d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat); - poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,d1,flat,polymat,mface->v1)); - poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat,polymat,mface->v2)); - poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat,polymat,mface->v3)); - if (nverts==4) - poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,d4,flat,polymat,mface->v4)); } else - { - poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,false,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,false,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,false,polymat,mface->v3)); - if (nverts==4) - poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,false,polymat,mface->v4)); - } + flat = false; + + poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1)); + poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2)); + poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3)); + if (nverts==4) + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4)); + meshobj->AddPolygon(poly); if (poly->IsCollider()) { @@ -1125,8 +1119,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } } meshobj->m_xyz_index_to_vertex_index_mapping.clear(); - if(skinMesh) - ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.clear(); meshobj->UpdateMaterialList(); // pre calculate texture generation @@ -1545,7 +1537,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, -static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { +static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { RAS_LightObject lightobj; KX_LightObject *gamelight; @@ -1577,8 +1569,15 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX } else { lightobj.m_type = RAS_LightObject::LIGHT_NORMAL; } + +#ifdef BLENDER_GLSL + if(converter->GetGLSLMaterials()) + GPU_lamp_from_blender(ob, la); - gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj); + gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, ob->gpulamp); +#else + gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, NULL); +#endif BL_ConvertLampIpos(la, gamelight, converter); return gamelight; @@ -1610,7 +1609,7 @@ static KX_GameObject *gameobject_from_blenderobject( { case OB_LAMP: { - KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); + KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); gameobj = gamelight; gamelight->AddRef(); @@ -1660,7 +1659,7 @@ static KX_GameObject *gameobject_from_blenderobject( // two options exists for deform: shape keys and armature // only support relative shape key bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; - bool bHasDvert = mesh->dvert != NULL; + bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert); if (bHasShapeKey) { @@ -1671,13 +1670,15 @@ static KX_GameObject *gameobject_from_blenderobject( 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; } @@ -2075,7 +2076,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (blenderscene->camera) { KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera); - kxscene->SetActiveCamera(gamecamera); + if(gamecamera) + kxscene->SetActiveCamera(gamecamera); } // Set up armatures diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index 212827a660f..39d66a90e92 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -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,33 +48,40 @@ #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; - vecIndexArrays mvarray; - vecIndexArrays diarray; - - RAS_TexVert *tv; - MVert *mvert; - - // For each material - array = m_pMeshObject->GetVertexCache(mat); - mvarray = m_pMeshObject->GetMVertCache(mat); - diarray = m_pMeshObject->GetDIndexCache(mat); - - // 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)); + size_t i, j; + float *co; + + // 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(); + + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + + // For each array + for (i=0; i<vertexarrays.size(); i++){ + KX_VertexArray& vertexarray = (*vertexarrays[i]); + + // For each vertex + for (j=0; j<vertexarray.size(); j++){ + RAS_TexVert& v = vertexarray[j]; + co = m_bmesh->mvert[v.getOrigIndex()].co; + v.SetXYZ(MT_Point3(co)); + } + } } + + m_lastDeformUpdate = m_gameobj->GetLastFrame(); + + return true; } - return true; + + return false; } BL_MeshDeformer::~BL_MeshDeformer() @@ -92,83 +100,86 @@ void BL_MeshDeformer::RecalcNormals() /* We don't normalize for performance, not doing it for faces normals * gives area-weight normals which often look better anyway, and use * GL_NORMALIZE so we don't have to do per vertex normalization either - * since the GPU can do it faster - * - * There's a lot of indirection here to get to the data, can this work - * with less arrays/indirection? */ - - vecIndexArrays indexarrays; - vecIndexArrays mvarrays; - vecIndexArrays diarrays; - vecVertexArray vertexarrays; + * since the GPU can do it faster */ size_t i, j; /* set vertex normals to zero */ - for (i=0; i<(size_t)m_bmesh->totvert; i++) - m_transnors[i] = MT_Vector3(0.0f, 0.0f, 0.0f); + memset(m_transnors, 0, sizeof(float)*3*m_bmesh->totvert); /* add face normals to vertices. */ for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); mit != m_pMeshObject->GetLastMaterial(); ++ mit) { RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); - indexarrays = m_pMeshObject->GetIndexCache(mat); - vertexarrays = m_pMeshObject->GetVertexCache(mat); - diarrays = m_pMeshObject->GetDIndexCache(mat); - mvarrays = m_pMeshObject->GetMVertCache(mat); + const vecIndexArrays& indexarrays = m_pMeshObject->GetIndexCache(mat); + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); for (i=0; i<indexarrays.size(); i++) { KX_VertexArray& vertexarray = (*vertexarrays[i]); - const KX_IndexArray& mvarray = (*mvarrays[i]); - const KX_IndexArray& diarray = (*diarrays[i]); const KX_IndexArray& indexarray = (*indexarrays[i]); int nvert = mat->UsesTriangles()? 3: 4; for(j=0; j<indexarray.size(); j+=nvert) { - MT_Point3 mv1, mv2, mv3, mv4, fnor; - int i1 = indexarray[j]; - int i2 = indexarray[j+1]; - int i3 = indexarray[j+2]; - RAS_TexVert& v1 = vertexarray[i1]; - RAS_TexVert& v2 = vertexarray[i2]; - RAS_TexVert& v3 = vertexarray[i3]; - + RAS_TexVert& v1 = vertexarray[indexarray[j]]; + RAS_TexVert& v2 = vertexarray[indexarray[j+1]]; + RAS_TexVert& v3 = vertexarray[indexarray[j+2]]; + RAS_TexVert *v4 = NULL; + + const float *co1 = v1.getLocalXYZ(); + const float *co2 = v2.getLocalXYZ(); + const float *co3 = v3.getLocalXYZ(); + const float *co4 = NULL; + /* compute face normal */ - mv1 = MT_Point3(v1.getLocalXYZ()); - mv2 = MT_Point3(v2.getLocalXYZ()); - mv3 = MT_Point3(v3.getLocalXYZ()); + float fnor[3], n1[3], n2[3]; if(nvert == 4) { - int i4 = indexarray[j+3]; - RAS_TexVert& v4 = vertexarray[i4]; - mv4 = MT_Point3(v4.getLocalXYZ()); + v4 = &vertexarray[indexarray[j+3]]; + co4 = v4->getLocalXYZ(); + + n1[0]= co1[0]-co3[0]; + n1[1]= co1[1]-co3[1]; + n1[2]= co1[2]-co3[2]; - fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))); //.safe_normalized(); + n2[0]= co2[0]-co4[0]; + n2[1]= co2[1]-co4[1]; + n2[2]= co2[2]-co4[2]; } - else - fnor = ((mv2-mv1).cross(mv3-mv2)); //.safe_normalized(); + else { + n1[0]= co1[0]-co2[0]; + n2[0]= co2[0]-co3[0]; + n1[1]= co1[1]-co2[1]; + + n2[1]= co2[1]-co3[1]; + n1[2]= co1[2]-co2[2]; + n2[2]= co2[2]-co3[2]; + } + + fnor[0]= n1[1]*n2[2] - n1[2]*n2[1]; + fnor[1]= n1[2]*n2[0] - n1[0]*n2[2]; + fnor[2]= n1[0]*n2[1] - n1[1]*n2[0]; /* add to vertices for smooth normals */ - m_transnors[mvarray[diarray[i1]]] += fnor; - m_transnors[mvarray[diarray[i2]]] += fnor; - m_transnors[mvarray[diarray[i3]]] += fnor; + float *vn1 = m_transnors[v1.getOrigIndex()]; + float *vn2 = m_transnors[v2.getOrigIndex()]; + float *vn3 = m_transnors[v3.getOrigIndex()]; + + vn1[0] += fnor[0]; vn1[1] += fnor[1]; vn1[2] += fnor[2]; + vn2[0] += fnor[0]; vn2[1] += fnor[1]; vn2[2] += fnor[2]; + vn3[0] += fnor[0]; vn3[1] += fnor[1]; vn3[2] += fnor[2]; + + if(v4) { + float *vn4 = m_transnors[v4->getOrigIndex()]; + vn4[0] += fnor[0]; vn4[1] += fnor[1]; vn4[2] += fnor[2]; + } /* in case of flat - just assign, the vertices are split */ if(v1.getFlag() & TV_CALCFACENORMAL) { v1.SetNormal(fnor); v2.SetNormal(fnor); v3.SetNormal(fnor); - } - - if(nvert == 4) { - int i4 = indexarray[j+3]; - RAS_TexVert& v4 = vertexarray[i4]; - - /* same as above */ - m_transnors[mvarray[diarray[i4]]] += fnor; - - if(v4.getFlag() & TV_CALCFACENORMAL) - v4.SetNormal(fnor); + if(v4) + v4->SetNormal(fnor); } } } @@ -179,18 +190,17 @@ void BL_MeshDeformer::RecalcNormals() mit != m_pMeshObject->GetLastMaterial(); ++ mit) { RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); - vertexarrays = m_pMeshObject->GetVertexCache(mat); - diarrays = m_pMeshObject->GetDIndexCache(mat); - mvarrays = m_pMeshObject->GetMVertCache(mat); + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); for (i=0; i<vertexarrays.size(); i++) { KX_VertexArray& vertexarray = (*vertexarrays[i]); - const KX_IndexArray& mvarray = (*mvarrays[i]); - const KX_IndexArray& diarray = (*diarrays[i]); - for(j=0; j<vertexarray.size(); j++) - if(!(vertexarray[j].getFlag() & TV_CALCFACENORMAL)) - vertexarray[j].SetNormal(m_transnors[mvarray[diarray[j]]]); //.safe_normalized() + for(j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + + if(!(v.getFlag() & TV_CALCFACENORMAL)) + v.SetNormal(m_transnors[v.getOrigIndex()]); //.safe_normalized() + } } } } @@ -204,8 +214,8 @@ void BL_MeshDeformer::VerifyStorage() if (m_transnors) delete [] m_transnors; - m_transverts=new float[(sizeof(*m_transverts)*m_bmesh->totvert)][3]; - m_transnors=new MT_Vector3[m_bmesh->totvert]; + m_transverts=new float[m_bmesh->totvert][3]; + m_transnors=new float[m_bmesh->totvert][3]; m_tvtot = m_bmesh->totvert; } } diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 8d8b56b1eed..e9f7f0b192f 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -40,19 +40,25 @@ #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #endif //WIN32 +class BL_DeformableGameObject; + class BL_MeshDeformer : public RAS_Deformer { public: void VerifyStorage(); void RecalcNormals(); virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){}; - BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ): + BL_MeshDeformer(BL_DeformableGameObject *gameobj, + struct Object* obj, + class BL_SkinMeshObject *meshobj ): m_pMeshObject(meshobj), m_bmesh((struct Mesh*)(obj->data)), m_transverts(0), m_transnors(0), m_objMesh(obj), - m_tvtot(0) + m_tvtot(0), + m_gameobj(gameobj), + m_lastDeformUpdate(-1) {}; virtual ~BL_MeshDeformer(); virtual void SetSimulatedTime(double time){}; @@ -68,10 +74,12 @@ protected: // this is so m_transverts doesn't need to be converted // before deformation float (*m_transverts)[3]; - MT_Vector3* m_transnors; + float (*m_transnors)[3]; struct Object* m_objMesh; // -- int m_tvtot; + BL_DeformableGameObject* m_gameobj; + double m_lastDeformUpdate; }; #endif diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 9f8361dbaca..5f0188e3a42 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -58,9 +58,8 @@ public: Object *bmeshobj, BL_SkinMeshObject *mesh) : - BL_SkinDeformer(bmeshobj, mesh), - m_lastShapeUpdate(-1), - m_gameobj(gameobj) + BL_SkinDeformer(gameobj,bmeshobj, mesh), + m_lastShapeUpdate(-1) { }; @@ -72,9 +71,8 @@ public: bool release_object, BL_ArmatureObject* arma = NULL) : - BL_SkinDeformer(bmeshobj_old, bmeshobj_new, mesh, release_object, arma), - m_lastShapeUpdate(-1), - m_gameobj(gameobj) + BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, arma), + m_lastShapeUpdate(-1) { }; @@ -94,7 +92,6 @@ public: protected: vector<IpoCurve*> m_shapeDrivers; double m_lastShapeUpdate; - BL_DeformableGameObject* m_gameobj; }; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index dd7119b1031..d3442fe5298 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -57,11 +57,12 @@ extern "C"{ #define __NLA_DEFNORMALS //#undef __NLA_DEFNORMALS -BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, +BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj, class BL_SkinMeshObject *mesh, BL_ArmatureObject* arma) : // - BL_MeshDeformer(bmeshobj, mesh), + BL_MeshDeformer(gameobj, bmeshobj, mesh), m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj->defbase), @@ -71,12 +72,13 @@ BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, }; BL_SkinDeformer::BL_SkinDeformer( + BL_DeformableGameObject *gameobj, struct Object *bmeshobj_old, // Blender object that owns the new mesh struct Object *bmeshobj_new, // Blender object that owns the original mesh class BL_SkinMeshObject *mesh, bool release_object, BL_ArmatureObject* arma) : - BL_MeshDeformer(bmeshobj_old, mesh), + BL_MeshDeformer(gameobj, bmeshobj_old, mesh), m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj_old->defbase), @@ -96,35 +98,32 @@ BL_SkinDeformer::~BL_SkinDeformer() m_armobj->Release(); } -bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) +bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *) { - size_t i, j, index; - vecVertexArray array; - vecIndexArrays mvarray; - vecMDVertArray dvarray; - vecIndexArrays diarray; - - RAS_TexVert *tv; - MT_Point3 pt; -// float co[3]; - - Update(); - - array = m_pMeshObject->GetVertexCache(mat); - mvarray = m_pMeshObject->GetMVertCache(mat); - diarray = m_pMeshObject->GetDIndexCache(mat); - // 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]); - - // Copy the untransformed data from the original mvert - // Set the data - tv->SetXYZ(m_transverts[((*mvarray[i])[index])]); + size_t i, j; + + if (!Update()) + // no need to update the cache + return false; + + // Update all materials at once, so we can do the above update test + // without ending up with some materials not updated + for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); + mit != m_pMeshObject->GetLastMaterial(); ++ mit) { + RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + + // For each array + for (i=0; i<vertexarrays.size(); i++) { + KX_VertexArray& vertexarray = (*vertexarrays[i]); + + // For each vertex + // copy the untransformed data from the original mvert + for (j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + v.SetXYZ(m_transverts[v.getOrigIndex()]); + } } } diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index c5568c049cb..f35db8273c4 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -63,12 +63,14 @@ public: } void SetArmature (class BL_ArmatureObject *armobj); - BL_SkinDeformer(struct Object *bmeshobj, + BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj, class BL_SkinMeshObject *mesh, BL_ArmatureObject* arma = NULL); /* this second constructor is needed for making a mesh deformable on the fly. */ - BL_SkinDeformer(struct Object *bmeshobj_old, + BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj_old, struct Object *bmeshobj_new, class BL_SkinMeshObject *mesh, bool release_object, diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 49492923c7c..fa215df1e1c 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -43,90 +43,6 @@ #include "KX_GameObject.h" #include "RAS_BucketManager.h" -void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly) -{ - /* We're overriding this so that we can eventually associate faces with verts somehow */ - - // For vertIndex in poly: - // find the appropriate normal - - RAS_MeshObject::AddPolygon(poly); -} - -int BL_SkinMeshObject::FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat) -{ - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - int numvert = ao->m_MvertArrayCache1[vtxarray]->size(); - - /* Check to see if this has already been pushed */ - for (vector<BL_MDVertMap>::iterator it = m_mvert_to_dvert_mapping[mv].begin(); - it != m_mvert_to_dvert_mapping[mv].end(); - it++) - { - if(it->mat == mat) - return it->index; - } - - ao->m_MvertArrayCache1[vtxarray]->push_back(mv); - ao->m_DvertArrayCache1[vtxarray]->push_back(dv); - - BL_MDVertMap mdmap; - mdmap.mat = mat; - mdmap.index = numvert; - m_mvert_to_dvert_mapping[mv].push_back(mdmap); - - return numvert; -}; - -int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat) -{ - int array=-1; - - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(polymat); - - - for (size_t i=0;i<ao->m_VertexArrayCache1.size();i++) - { - if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES) - { - if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES)) - { - array = i; - ao->m_TriangleArrayCount[array]+=numverts-2; - break; - } - } - } - - - if (array == -1) - { - array = ao->m_VertexArrayCache1.size(); - - vector<RAS_TexVert>* va = new vector<RAS_TexVert>; - ao->m_VertexArrayCache1.push_back(va); - - KX_IndexArray *ia = new KX_IndexArray(); - ao->m_IndexArrayCache1.push_back(ia); - - KX_IndexArray *bva = new KX_IndexArray(); - ao->m_MvertArrayCache1.push_back(bva); - - BL_DeformVertArray *dva = new BL_DeformVertArray(); - ao->m_DvertArrayCache1.push_back(dva); - - KX_IndexArray *da = new KX_IndexArray(); - ao->m_DIndexArrayCache1.push_back(da); - - ao->m_TriangleArrayCount.push_back(numverts-2); - - } - - - return array; -} - - //void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,RAS_BucketManager* bucketmgr) void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec) { diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index cc2b8de600e..c21fb64204b 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -44,78 +44,19 @@ #include "DNA_key_types.h" #include "DNA_meshdata_types.h" -typedef vector<struct MVert*> BL_MVertArray; -typedef vector<struct MDeformVert*> BL_DeformVertArray; -typedef vector<class BL_TexVert> BL_VertexArray; - - -typedef vector<vector<struct MDeformVert*>*> vecMDVertArray; -typedef vector<vector<class BL_TexVert>*> vecBVertexArray; - -class BL_SkinArrayOptimizer : public KX_ArrayOptimizer -{ -public: - BL_SkinArrayOptimizer(int index) - :KX_ArrayOptimizer (index) {}; - virtual ~BL_SkinArrayOptimizer(){ - - for (vector<KX_IndexArray*>::iterator itv = m_MvertArrayCache1.begin(); - !(itv == m_MvertArrayCache1.end());itv++) - { - delete (*itv); - } - for (vector<BL_DeformVertArray*>::iterator itd = m_DvertArrayCache1.begin(); - !(itd == m_DvertArrayCache1.end());itd++) - { - delete (*itd); - } - for (vector<KX_IndexArray*>::iterator iti = m_DIndexArrayCache1.begin(); - !(iti == m_DIndexArrayCache1.end());iti++) - { - delete (*iti); - } - - m_MvertArrayCache1.clear(); - m_DvertArrayCache1.clear(); - m_DIndexArrayCache1.clear(); - }; - - vector<KX_IndexArray*> m_MvertArrayCache1; - vector<BL_DeformVertArray*> m_DvertArrayCache1; - vector<KX_IndexArray*> m_DIndexArrayCache1; - -}; - class BL_SkinMeshObject : public RAS_MeshObject { // enum { BUCKET_MAX_INDICES = 16384};//2048};//8192}; // enum { BUCKET_MAX_TRIANGLES = 4096}; - KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat) - { - KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]); - if (aop) - return *aop; - int numelements = m_matVertexArrayS.size(); - m_sortedMaterials.push_back(polymat); - - BL_SkinArrayOptimizer* ao = new BL_SkinArrayOptimizer(numelements); - m_matVertexArrayS.insert(*polymat,ao); - return ao; - } - protected: vector<int> m_cacheWeightIndex; public: - struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; }; - vector<vector<BL_MDVertMap> > m_mvert_to_dvert_mapping; - void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec); // void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr); - int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat); BL_SkinMeshObject(Mesh* mesh, int lightlayer) : RAS_MeshObject (mesh, lightlayer) { m_class = 1; @@ -144,42 +85,7 @@ public: } } }; - - const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_DIndexArrayCache1; - } - const vecMDVertArray& GetDVertCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_DvertArrayCache1; - } - const vecIndexArrays& GetMVertCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_MvertArrayCache1; - } - void AddPolygon(RAS_Polygon* poly); - int FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat); - int FindOrAddVertex(int vtxarray,const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, - const MT_Vector4& tangent, - const unsigned int rgbacolor, - const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat, int origindex) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat); - int numverts = ao->m_VertexArrayCache1[vtxarray]->size(); - int index = RAS_MeshObject::FindOrAddVertex(vtxarray, xyz, uv, uv2, tangent, rgbacolor, normal, flat, mat, origindex); - - /* this means a new vertex was added, so we add the defnr too */ - if(index == numverts) - ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr); - - return index; - } // for shape keys, void CheckWeightCache(struct Object* obj); diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 06e012123b1..dd45d522b9f 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -1,9 +1,11 @@ #include "DNA_customdata_types.h" +#include "DNA_material_types.h" #include "BL_BlenderShader.h" +#include "BL_Material.h" -#if 0 +#ifdef BLENDER_GLSL #include "GPU_extensions.h" #include "GPU_material.h" #endif @@ -13,29 +15,32 @@ const bool BL_BlenderShader::Ok()const { -#if 0 +#ifdef BLENDER_GLSL return (mGPUMat != 0); +#else + return 0; #endif - - return false; } -BL_BlenderShader::BL_BlenderShader(struct Material *ma) +BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer) : -#if 0 +#ifdef BLENDER_GLSL mGPUMat(0), #endif - mBound(false) + mBound(false), + mLightLayer(lightlayer) { -#if 0 - if(ma) - mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH); +#ifdef BLENDER_GLSL + if(ma) { + GPU_material_from_blender(ma); + mGPUMat = ma->gpumaterial; + } #endif } BL_BlenderShader::~BL_BlenderShader() { -#if 0 +#ifdef BLENDER_GLSL if(mGPUMat) { GPU_material_unbind(mGPUMat); mGPUMat = 0; @@ -43,16 +48,12 @@ BL_BlenderShader::~BL_BlenderShader() #endif } -void BL_BlenderShader::ApplyShader() -{ -} - void BL_BlenderShader::SetProg(bool enable) { -#if 0 +#ifdef BLENDER_GLSL if(mGPUMat) { if(enable) { - GPU_material_bind(mGPUMat); + GPU_material_bind(mGPUMat, mLightLayer); mBound = true; } else { @@ -65,7 +66,7 @@ void BL_BlenderShader::SetProg(bool enable) int BL_BlenderShader::GetAttribNum() { -#if 0 +#ifdef BLENDER_GLSL GPUVertexAttribs attribs; int i, enabled = 0; @@ -82,17 +83,19 @@ int BL_BlenderShader::GetAttribNum() enabled = BL_MAX_ATTRIB; return enabled; -#endif - +#else return 0; +#endif } -void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) +void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) { -#if 0 +#ifdef BLENDER_GLSL GPUVertexAttribs attribs; int i, attrib_num; + ras->SetAttribNum(0); + if(!mGPUMat) return; @@ -109,14 +112,24 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) if(attribs.layer[i].glindex > attrib_num) continue; - if(attribs.layer[i].type == CD_MTFACE) - ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + if(attribs.layer[i].type == CD_MTFACE) { + if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex); + else + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + } else if(attribs.layer[i].type == CD_TANGENT) ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_ORCO) ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_NORMAL) ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex); + else if(attribs.layer[i].type == CD_MCOL) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex); + else + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex); } ras->EnableTextures(true); @@ -128,8 +141,8 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) { -#if 0 - float obmat[4][4], viewmat[4][4]; +#ifdef BLENDER_GLSL + float obmat[4][4], viewmat[4][4], viewinvmat[4][4]; if(!mGPUMat || !mBound) return; @@ -142,7 +155,20 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) model.getValue((float*)obmat); view.getValue((float*)viewmat); - GPU_material_bind_uniforms(mGPUMat, obmat, viewmat); + view.invert(); + view.getValue((float*)viewinvmat); + + GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat); +#endif +} + +bool BL_BlenderShader::Equals(BL_BlenderShader *blshader) +{ +#ifdef BLENDER_GLSL + /* to avoid unneeded state switches */ + return (blshader && mGPUMat == blshader->mGPUMat && mLightLayer == blshader->mLightLayer); +#else + return true; #endif } diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index 4cab0e644c3..b758d1a9cba 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -2,7 +2,7 @@ #ifndef __BL_GPUSHADER_H__ #define __BL_GPUSHADER_H__ -#if 0 +#ifdef BLENDER_GLSL #include "GPU_material.h" #endif @@ -12,7 +12,10 @@ #include "MT_Tuple3.h" #include "MT_Tuple4.h" +#include "RAS_IPolygonMaterial.h" + struct Material; +class BL_Material; #define BL_MAX_ATTRIB 16 @@ -23,22 +26,24 @@ struct Material; class BL_BlenderShader { private: -#if 0 +#ifdef BLENDER_GLSL GPUMaterial *mGPUMat; #endif bool mBound; + int mLightLayer; public: - BL_BlenderShader(struct Material *ma); + BL_BlenderShader(struct Material *ma, int lightlayer); virtual ~BL_BlenderShader(); const bool Ok()const; void SetProg(bool enable); - void ApplyShader(); - void SetTexCoords(class RAS_IRasterizer* ras); int GetAttribNum(); + void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat); void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty); + + bool Equals(BL_BlenderShader *blshader); }; #endif//__BL_GPUSHADER_H__ diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index f5312ccd023..7e3d6984f19 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -105,7 +105,8 @@ void BL_Material::GetConversionRGB(unsigned int *nrgb) { *nrgb = rgb[3]; } -void BL_Material::SetConversionUV(MT_Point2 *nuv) { +void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) { + uvName = name; uv[0] = *nuv++; uv[1] = *nuv++; uv[2] = *nuv++; @@ -118,7 +119,8 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){ *nuv++ = uv[2]; *nuv = uv[3]; } -void BL_Material::SetConversionUV2(MT_Point2 *nuv) { +void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) { + uv2Name = name; uv2[0] = *nuv++; uv2[1] = *nuv++; uv2[2] = *nuv++; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index ddb6662830a..568f7e171de 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -83,13 +83,16 @@ public: MT_Point2 uv[4]; MT_Point2 uv2[4]; + STR_String uvName; + STR_String uv2Name; + void SetConversionRGB(unsigned int *rgb); void GetConversionRGB(unsigned int *rgb); - void SetConversionUV(MT_Point2 *uv); + void SetConversionUV(const STR_String& name, MT_Point2 *uv); void GetConversionUV(MT_Point2 *uv); - void SetConversionUV2(MT_Point2 *uv); + void SetConversionUV2(const STR_String& name, MT_Point2 *uv); void GetConversionUV2(MT_Point2 *uv); void SetSharedMaterial(bool v); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 02b1ffd432a..0f445a9f32e 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -38,6 +38,8 @@ extern "C" { // ------------------------------------ #define spit(x) std::cout << x << std::endl; +BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; + //static PyObject *gTextureDict = 0; KX_BlenderMaterial::KX_BlenderMaterial( @@ -126,32 +128,31 @@ void KX_BlenderMaterial::OnConstruction() // when material are reused between objects return; - if(mMaterial->glslmat) { + if(mMaterial->glslmat) SetBlenderGLSLShader(); - } - else { - // for each unique material... - int i; - for(i=0; i<mMaterial->num_enabled; i++) { - if( mMaterial->mapping[i].mapping & USEENV ) { - if(!GLEW_ARB_texture_cube_map) { - spit("CubeMap textures not supported"); - continue; - } - if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) + + // for each unique material... + int i; + for(i=0; i<mMaterial->num_enabled; i++) { + if( mMaterial->mapping[i].mapping & USEENV ) { + if(!GLEW_ARB_texture_cube_map) { + spit("CubeMap textures not supported"); + continue; + } + if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) + spit("unable to initialize image("<<i<<") in "<< + mMaterial->matname<< ", image will not be available"); + } + + else { + if( mMaterial->img[i] ) { + if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) spit("unable to initialize image("<<i<<") in "<< - mMaterial->matname<< ", image will not be available"); - } - - else { - if( mMaterial->img[i] ) { - if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) - spit("unable to initialize image("<<i<<") in "<< - mMaterial->matname<< ", image will not be available"); - } + mMaterial->matname<< ", image will not be available"); } } } + mBlendFunc[0] =0; mBlendFunc[1] =0; mConstructed = true; @@ -168,7 +169,11 @@ void KX_BlenderMaterial::OnExit() } if( mBlenderShader ) { - mBlenderShader->SetProg(false); + if(mBlenderShader == mLastBlenderShader) { + mBlenderShader->SetProg(false); + mLastBlenderShader = NULL; + } + delete mBlenderShader; mBlenderShader = 0; } @@ -225,14 +230,23 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras { if( !enable || !mBlenderShader->Ok() ) { // frame cleanup. - mBlenderShader->SetProg(false); + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } BL_Texture::DisableAllTextures(); return; } - BL_Texture::DisableAllTextures(); - mBlenderShader->SetProg(true); - mBlenderShader->ApplyShader(); + if(!mBlenderShader->Equals(mLastBlenderShader)) { + BL_Texture::DisableAllTextures(); + + if(mLastBlenderShader) + mLastBlenderShader->SetProg(false); + + mBlenderShader->SetProg(true); + mLastBlenderShader= mBlenderShader; + } } void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) @@ -298,7 +312,12 @@ KX_BlenderMaterial::ActivatShaders( // reset... if(tmp->mMaterial->IsShared()) cachingInfo =0; - + + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } + if (GetCachingInfo() != cachingInfo) { if (!cachingInfo) @@ -372,7 +391,7 @@ KX_BlenderMaterial::ActivateBlenderShaders( } ActivatGLMaterials(rasty); - mBlenderShader->SetTexCoords(rasty); + mBlenderShader->SetAttribs(rasty, mMaterial); } void @@ -382,6 +401,12 @@ KX_BlenderMaterial::ActivateMat( )const { KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); + + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } + if (GetCachingInfo() != cachingInfo) { if (!cachingInfo) tmp->setTexData( false,rasty ); @@ -460,17 +485,29 @@ KX_BlenderMaterial::Activate( return dopass; } +bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const +{ + if(!RAS_IPolyMaterial::UsesLighting(rasty)) + return false; + + if(mShader && mShader->Ok()); + else if(mBlenderShader && mBlenderShader->Ok()) + return false; + + return true; +} + void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const { if(mShader && GLEW_ARB_shader_objects) mShader->Update(ms, rasty); - if(mBlenderShader && GLEW_ARB_shader_objects) + else if(mBlenderShader && GLEW_ARB_shader_objects) mBlenderShader->Update(ms, rasty); } void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const { - if(!mBlenderShader) { + if(mShader || !mBlenderShader) { rasty->SetSpecularity( mMaterial->speccolor[0]*mMaterial->spec_f, mMaterial->speccolor[1]*mMaterial->spec_f, @@ -506,6 +543,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const ras->SetAttribNum(0); if(mShader && GLEW_ARB_shader_objects) { if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) { + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0); ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1); ras->SetAttribNum(2); } @@ -793,7 +831,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") void KX_BlenderMaterial::SetBlenderGLSLShader(void) { if(!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mMaterial->material); + mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer); if(!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 62e96b71937..bf6d2095e7c 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -94,6 +94,7 @@ private: BL_Material* mMaterial; BL_Shader* mShader; BL_BlenderShader* mBlenderShader; + static BL_BlenderShader *mLastBlenderShader; KX_Scene* mScene; BL_Texture mTextures[MAXTEX]; // texture array bool mUserDefBlend; @@ -106,6 +107,7 @@ private: void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; + bool UsesLighting(RAS_IRasterizer *rasty) const; // message centers void setTexData( bool enable,RAS_IRasterizer *ras); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index db13d30e2f1..2ac4f909077 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1306,7 +1306,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, return meshproxy; } } - return NULL; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 56a06786679..20187a193ba 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -55,6 +55,7 @@ #include "KX_Scene.h" #include "MT_CmMatrix4x4.h" #include "KX_Camera.h" +#include "KX_Light.h" #include "KX_PythonInit.h" #include "KX_PyConstraintBinding.h" #include "PHY_IPhysicsEnvironment.h" @@ -614,6 +615,9 @@ void KX_KetsjiEngine::Render() // pass the scene's worldsettings to the rasterizer SetWorldSettings(scene->GetWorldInfo()); + // shadow buffers + RenderShadowBuffers(scene); + // Avoid drawing the scene with the active camera twice when it's viewport is enabled if(cam && !cam->GetViewport()) { @@ -885,8 +889,48 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam) viewport.GetTop() ); -} +} + +void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) +{ + CListValue *lightlist = scene->GetLightList(); + int i, drawmode; + for(i=0; i<lightlist->GetCount(); i++) { + KX_LightObject *light = (KX_LightObject*)lightlist->GetValue(i); + + light->Update(); + + if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) { + /* make temporary camera */ + RAS_CameraData camdata = RAS_CameraData(); + KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false); + cam->SetName("__shadow__cam__"); + + MT_Transform camtrans; + + /* switch drawmode for speed */ + drawmode = m_rasterizer->GetDrawingMode(); + m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW); + + /* binds framebuffer object, sets up camera .. */ + light->BindShadowBuffer(m_rasterizer, cam, camtrans); + + /* update scene */ + scene->UpdateMeshTransformations(); + scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer()); + + /* render */ + m_rasterizer->ClearDepthBuffer(); + scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + + /* unbind framebuffer object, restore drawmode, free camera */ + light->UnbindShadowBuffer(m_rasterizer); + m_rasterizer->SetDrawingMode(drawmode); + cam->Release(); + } + } +} // update graphics void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 4c09bc3fcd5..77b69ec2d9e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -179,6 +179,7 @@ private: void RenderFrame(KX_Scene* scene, KX_Camera* cam); void PostRenderFrame(); void RenderDebugProperties(); + void RenderShadowBuffers(KX_Scene *scene); void SetBackGround(KX_WorldInfo* worldinfo); void SetWorldSettings(KX_WorldInfo* worldinfo); void DoSound(KX_Scene* scene); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 7decc5bc769..4e3d6180d22 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -36,14 +36,20 @@ #endif #include "KX_Light.h" +#include "KX_Camera.h" +#include "RAS_IRasterizer.h" #include "RAS_IRenderTools.h" #include "KX_PyMath.h" +#ifdef BLENDER_GLSL +#include "GPU_material.h" +#endif KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, + struct GPULamp *gpulamp, PyTypeObject* T ) : @@ -53,12 +59,12 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_lightobj = lightobj; m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); m_rendertools->AddLight(&m_lightobj); + m_gpulamp = gpulamp; }; KX_LightObject::~KX_LightObject() { - m_rendertools->RemoveLight(&m_lightobj); } @@ -78,6 +84,78 @@ CValue* KX_LightObject::GetReplica() return replica; } +void KX_LightObject::Update() +{ +#ifdef BLENDER_GLSL + if(m_gpulamp) { + float obmat[4][4]; + double *dobmat = GetOpenGLMatrixPtr()->getPointer(); + + for(int i=0; i<4; i++) + for(int j=0; j<4; j++, dobmat++) + obmat[i][j] = (float)*dobmat; + + GPU_lamp_update(m_gpulamp, obmat); + } +#endif +} + +bool KX_LightObject::HasShadowBuffer() +{ +#ifdef BLENDER_GLSL + return (m_gpulamp && GPU_lamp_has_shadow_buffer(m_gpulamp)); +#else + return false; +#endif +} + +int KX_LightObject::GetShadowLayer() +{ +#ifdef BLENDER_GLSL + if(m_gpulamp) + return GPU_lamp_shadow_layer(m_gpulamp); + else +#endif + return 0; +} + +void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans) +{ +#ifdef BLENDER_GLSL + float viewmat[4][4], winmat[4][4]; + int winsize; + + /* bind framebuffer */ + GPU_lamp_shadow_buffer_bind(m_gpulamp, viewmat, &winsize, winmat); + + /* setup camera transformation */ + MT_Matrix4x4 modelviewmat((float*)viewmat); + MT_Matrix4x4 projectionmat((float*)winmat); + + MT_Transform trans = MT_Transform((float*)viewmat); + camtrans.invert(trans); + + cam->SetModelviewMatrix(modelviewmat); + cam->SetProjectionMatrix(projectionmat); + + cam->NodeSetLocalPosition(camtrans.getOrigin()); + cam->NodeSetLocalOrientation(camtrans.getBasis()); + cam->NodeUpdateGS(0,true); + + /* setup rasterizer transformations */ + ras->SetProjectionMatrix(projectionmat); + ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(), + cam->GetCameraLocation(), cam->GetCameraOrientation()); +#endif +} + +void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) +{ +#ifdef BLENDER_GLSL + GPU_lamp_shadow_buffer_unbind(m_gpulamp); +#endif +} + PyObject* KX_LightObject::_getattr(const STR_String& attr) { if (attr == "layer") diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 236d3e4e12e..62eb26c61a8 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -32,19 +32,33 @@ #include "RAS_LightObject.h" #include "KX_GameObject.h" +struct GPULamp; +class KX_Camera; +class RAS_IRasterizer; +class RAS_IRenderTools; +class MT_Transform; + class KX_LightObject : public KX_GameObject { Py_Header; protected: RAS_LightObject m_lightobj; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj + struct GPULamp *m_gpulamp; static char doc[]; public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct GPULamp *gpulamp, PyTypeObject *T = &Type); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} + + /* GLSL shadow */ + bool HasShadowBuffer(); + int GetShadowLayer(); + void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans); + void UnbindShadowBuffer(class RAS_IRasterizer *ras); + void Update(); virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */ virtual int _setattr(const STR_String& attr, PyObject *pyvalue); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c5f6230b2f2..065800379d8 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -888,6 +888,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) else if (bHasArmature) { BL_SkinDeformer* skinDeformer = new BL_SkinDeformer( + newobj, oldblendobj, blendobj, static_cast<BL_SkinMeshObject*>(mesh), true, @@ -899,7 +900,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) else if (bHasDvert) { BL_MeshDeformer* meshdeformer = new BL_MeshDeformer( - oldblendobj, static_cast<BL_SkinMeshObject*>(mesh) + newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh) ); newobj->m_pDeformer = meshdeformer; } @@ -1004,12 +1005,13 @@ void KX_Scene::UpdateMeshTransformations() } } -void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam) +void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer) { int intersect = KX_Camera::INTERSECT; KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL; - bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right(); - + bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer))); + bool dotest = visible || node->Left() || node->Right(); + /* If the camera is inside the box, assume intersect. */ if (dotest && !node->inside( cam->NodeGetWorldPosition())) { @@ -1033,19 +1035,19 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam break; case KX_Camera::INTERSECT: if (gameobj) - MarkVisible(rasty, gameobj,cam); + MarkVisible(rasty, gameobj, cam, layer); if (node->Left()) - MarkVisible(node->Left(), rasty,cam); + MarkVisible(node->Left(), rasty, cam, layer); if (node->Right()) - MarkVisible(node->Right(), rasty,cam); + MarkVisible(node->Right(), rasty, cam, layer); break; case KX_Camera::INSIDE: - MarkSubTreeVisible(node, rasty, true,cam); + MarkSubTreeVisible(node, rasty, true, cam, layer); break; } } -void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam) +void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer) { if (node->Client()) { @@ -1068,16 +1070,23 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi } } if (node->Left()) - MarkSubTreeVisible(node->Left(), rasty, visible,cam); + MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer); if (node->Right()) - MarkSubTreeVisible(node->Right(), rasty, visible,cam); + MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer); } -void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam) +void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam,int layer) { // User (Python/Actuator) has forced object invisible... if (!gameobj->GetVisible()) return; + + // Shadow lamp layers + if(layer && !(gameobj->GetLayer() & layer)) { + gameobj->MarkVisible(false); + return; + } + // If Frustum culling is off, the object is always visible. bool vis = !cam->GetFrustumCulling(); @@ -1127,20 +1136,20 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam } } -void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam) +void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer) { // FIXME: When tree is operational #if 1 // do this incrementally in the future for (int i = 0; i < m_objectlist->GetCount(); i++) { - MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam); + MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer); } #else if (cam->GetFrustumCulling()) - MarkVisible(m_objecttree, rasty, cam); + MarkVisible(m_objecttree, rasty, cam, layer); else - MarkSubTreeVisible(m_objecttree, rasty, true, cam); + MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer); #endif } diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 733df2f69a1..28dee1b5893 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -260,9 +260,9 @@ protected: /** * Visibility testing functions. */ - void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam); - void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam); - void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam); + void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0); + void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0); + void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0); double m_suspendedtime; double m_suspendeddelta; @@ -483,7 +483,7 @@ public: void SetNetworkScene(NG_NetworkScene *newScene); void SetWorldInfo(class KX_WorldInfo* wi); KX_WorldInfo* GetWorldInfo(); - void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam); + void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam, int layer=0); void UpdateMeshTransformations(); KX_Camera* GetpCamera(); SND_Scene* GetSoundScene(); diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index 50df1a1e2ea..b4492ca03a9 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -109,7 +109,7 @@ void RAS_BucketManager::RenderAlphaBuckets( // it is needed for compatibility. rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED); - int drawingmode; + RAS_IRasterizer::DrawMode drawingmode; std::multiset< alphamesh, backtofront>::iterator msit = alphameshset.begin(); for (; msit != alphameshset.end(); ++msit) { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index bff98abe058..cb10ba6bf37 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -27,6 +27,7 @@ */ #include "RAS_IPolygonMaterial.h" +#include "RAS_IRasterizer.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -148,4 +149,19 @@ const unsigned int RAS_IPolyMaterial::GetFlag() const return m_flag; } +bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const +{ + bool dolights = false; + + if(m_flag & RAS_BLENDERMAT) + dolights = (m_flag &RAS_MULTILIGHT)!=0; + else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); + else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); + else + dolights = (m_drawingmode & 16)!=0; + + return dolights; +} + unsigned int RAS_IPolyMaterial::m_newpolymatid = 0; + diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 09824f6975c..d2d1dba99d9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -140,6 +140,8 @@ public: const STR_String& GetMaterialName() const; const STR_String& GetTextureName() const; const unsigned int GetFlag() const; + + virtual bool UsesLighting(RAS_IRasterizer *rasty) const; /* * PreCalculate texture gen diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index dbedc492afa..d4a9177a85d 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -33,12 +33,23 @@ #pragma warning (disable:4786) #endif +#include "STR_HashedString.h" + #include "MT_CmMatrix4x4.h" #include "MT_Matrix4x4.h" +#include "RAS_TexVert.h" + +#include <vector> +using namespace std; + class RAS_ICanvas; class RAS_IPolyMaterial; -#include "RAS_MaterialBucket.h" + +typedef vector<unsigned short> KX_IndexArray; +typedef vector<RAS_TexVert> KX_VertexArray; +typedef vector< KX_VertexArray* > vecVertexArray; +typedef vector< KX_IndexArray* > vecIndexArrays; /** * 3D rendering device context interface. @@ -62,7 +73,18 @@ public: KX_WIREFRAME, KX_SOLID, KX_SHADED, - KX_TEXTURED + KX_TEXTURED, + KX_SHADOW + }; + + /** + * Drawing modes + */ + + enum DrawMode { + KX_MODE_LINES = 1, + KX_MODE_TRIANGLES, + KX_MODE_QUADS }; /** @@ -111,6 +133,7 @@ public: RAS_TEXCO_NORM, //< Normal coordinates RAS_TEXTANGENT, //< RAS_TEXCO_UV2, //< + RAS_TEXCO_VCOL, //< Vertex Color RAS_TEXCO_DISABLE //< Disable this texture unit (cached) }; @@ -197,45 +220,37 @@ public: * IndexPrimitives: Renders primitives. * @param vertexarrays is an array of vertex arrays * @param indexarrays is an array of index arrays - * @param mode determines the type of primitive stored in the vertex/index arrays: - * 0 triangles - * 1 lines (default) - * 2 quads - * @param polymat (reserved) + * @param mode determines the type of primitive stored in the vertex/index arrays * @param useObjectColor will render the object using @param rgbacolor instead of * vertex colors. */ - virtual void IndexPrimitives( const vecVertexArray& vertexarrays, + virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot)=0; + virtual void IndexPrimitivesMulti( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + DrawMode mode, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot)=0; + /** * IndexPrimitives_3DText will render text into the polygons. * The text to be rendered is from @param rendertools client object's text property. */ virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, const MT_Vector4& rgbacolor)=0; - virtual void IndexPrimitivesMulti( - const vecVertexArray& vertexarrays, - const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, - bool useObjectColor, - const MT_Vector4& rgbacolor, - class KX_ListSlot** slot)=0; - virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0; /* This one should become our final version, methinks. */ /** diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 1beade7acf7..e295d69e48e 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -167,38 +167,30 @@ RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msEnd() } bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools, int &drawmode) + RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode &drawmode) { rendertools->SetViewMat(cameratrans); if (!rasty->SetMaterial(*m_material)) return false; - bool dolights = false; - const unsigned int flag = m_material->GetFlag(); - - if( flag & RAS_BLENDERMAT) - dolights = (flag &RAS_MULTILIGHT)!=0; + if (m_material->UsesLighting(rasty)) + rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/); else - dolights = (m_material->GetDrawingMode()&16)!=0; - - if ((rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) || !dolights) - { rendertools->ProcessLighting(-1); - } - else - { - rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/); - } - drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ? - 1: (m_material->UsesTriangles() ? 0 : 2)); + if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) + drawmode = RAS_IRasterizer::KX_MODE_LINES; + else if(m_material->UsesTriangles()) + drawmode = RAS_IRasterizer::KX_MODE_TRIANGLES; + else + drawmode = RAS_IRasterizer::KX_MODE_QUADS; return true; } void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode) + RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode) { if (!ms.m_bVisible) return; @@ -225,6 +217,17 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_DisplayList->SetModified(ms.m_mesh->MeshModified()); } + // verify if we can use display list, not for deformed object, and + // also don't create a new display list when drawing shadow buffers, + // then it won't have texture coordinates for actual drawing + KX_ListSlot **displaylist; + if(ms.m_pDeformer) + displaylist = 0; + else if(!ms.m_DisplayList && rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) + displaylist = 0; + else + displaylist = &ms.m_DisplayList; + // Use the text-specific IndexPrimitives for text faces if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT) { @@ -245,12 +248,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_mesh->GetVertexCache(m_material), ms.m_mesh->GetIndexCache(m_material), drawmode, - m_material, - rendertools, ms.m_bObjectColor, ms.m_RGBAcolor, - (ms.m_pDeformer)? 0: &ms.m_DisplayList - ); + displaylist); } // Use the normal IndexPrimitives @@ -260,12 +260,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_mesh->GetVertexCache(m_material), ms.m_mesh->GetIndexCache(m_material), drawmode, - m_material, - rendertools, // needed for textprinting on polys ms.m_bObjectColor, ms.m_RGBAcolor, - (ms.m_pDeformer)? 0: &ms.m_DisplayList - ); + displaylist); } if(rasty->QueryLists()) { @@ -287,7 +284,7 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, //rasty->SetMaterial(*m_material); - int drawmode; + RAS_IRasterizer::DrawMode drawmode; for (T_MeshSlotList::const_iterator it = m_meshSlots.begin(); ! (it == m_meshSlots.end()); ++it) { diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 5ad0c173a56..13d8a53714a 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -35,17 +35,13 @@ #include "MT_Transform.h" #include "RAS_IPolygonMaterial.h" +#include "RAS_IRasterizer.h" #include "RAS_Deformer.h" // __NLA #include <vector> #include <map> #include <set> using namespace std; -typedef vector<unsigned short> KX_IndexArray; -typedef vector<RAS_TexVert> KX_VertexArray; -typedef vector< KX_VertexArray* > vecVertexArray; -typedef vector< KX_IndexArray* > vecIndexArrays; - /** * KX_VertexIndex */ @@ -146,9 +142,9 @@ public: const MT_Vector4& rgbavec); void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode); + RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode); bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools, int &drawmode); + RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode& drawmode); unsigned int NumMeshSlots(); T_MeshSlotList::iterator msBegin(); diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index d7ab88a6b06..4420f16c56d 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -68,8 +68,8 @@ RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer) m_lightlayer(lightlayer), m_zsort(false), m_MeshMod(true), - m_class(0), - m_mesh(mesh) + m_mesh(mesh), + m_class(0) { } @@ -259,18 +259,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, const MT_Vector3& normal, bool flat, RAS_IPolyMaterial* mat, - int orgindex) + int origindex) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0); + RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0,origindex); #define KX_FIND_SHARED_VERTICES #ifdef KX_FIND_SHARED_VERTICES if(!flat) { - for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin(); - it != m_xyz_index_to_vertex_index_mapping[orgindex].end(); + for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[origindex].begin(); + it != m_xyz_index_to_vertex_index_mapping[origindex].end(); it++) { if ((*it).m_arrayindex1 == ao->m_index1 && @@ -293,22 +293,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, idx.m_array = vtxarray; idx.m_index = numverts; idx.m_matid = mat; - m_xyz_index_to_vertex_index_mapping[orgindex].push_back(idx); + m_xyz_index_to_vertex_index_mapping[origindex].push_back(idx); return numverts; } - - -const vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat) +vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); return ao->m_VertexArrayCache1; } - - int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat) { int len = 0; @@ -362,7 +358,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid, const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); return ao->m_IndexArrayCache1; } @@ -371,16 +367,27 @@ const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat) KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat) { - KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]); + KX_ArrayOptimizer** aop = m_matVertexArrayS[polymat]; - if (aop) + if(aop) return *aop; + // didn't find array, but an array might already exist + // for a material equal to this one + for(int i=0;i<m_matVertexArrayS.size();i++) { + RAS_IPolyMaterial *mat = (RAS_IPolyMaterial*)(m_matVertexArrayS.getKey(i)->getValue()); + if(*mat == *polymat) { + m_matVertexArrayS.insert(polymat, *m_matVertexArrayS.at(i)); + return *m_matVertexArrayS.at(i); + } + } + + // create new array int numelements = m_matVertexArrayS.size(); m_sortedMaterials.push_back(polymat); - + KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements); - m_matVertexArrayS.insert(*polymat,ao); + m_matVertexArrayS.insert(polymat, ao); return ao; } @@ -463,7 +470,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array, unsigned int index, RAS_IPolyMaterial* polymat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);//*(m_matVertexArrays[*polymat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat); return &((*(ao->m_VertexArrayCache1)[array])[index]); } @@ -471,13 +478,19 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array, void RAS_MeshObject::ClearArrayData() { - for (int i=0;i<m_matVertexArrayS.size();i++) - { + for (int i=0;i<m_matVertexArrayS.size();i++) { KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i); + + // we have duplicate entries, only free once + for(int j=i+1;j<m_matVertexArrayS.size();j++) { + if(ao == m_matVertexArrayS.at(j)) { + ao = NULL; + break; + } + } + if (ao) - { delete *ao; - } } } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index d9aa133efb2..0d06748f91f 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -142,7 +142,7 @@ protected: enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192}; enum { BUCKET_MAX_TRIANGLES = 65535 }; - GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS; + GEN_Map<GEN_HashedPtr,KX_ArrayOptimizer*> m_matVertexArrayS; RAS_MaterialBucket::Set m_materials; Mesh* m_mesh; @@ -242,10 +242,10 @@ public: const MT_Vector3& normal, bool flat, RAS_IPolyMaterial* mat, - int orgindex + int origindex ); - const vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat); + vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat); int GetVertexArrayLength(RAS_IPolyMaterial* mat); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 39080b80492..c2687319717 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -161,9 +161,7 @@ void RAS_ListRasterizer::ReleaseAlloc() void RAS_ListRasterizer::IndexPrimitives( const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) @@ -185,15 +183,13 @@ void RAS_ListRasterizer::IndexPrimitives( if (mUseVertexArrays) { RAS_VAOpenGLRasterizer::IndexPrimitives( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } else { RAS_OpenGLRasterizer::IndexPrimitives( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } @@ -208,9 +204,7 @@ void RAS_ListRasterizer::IndexPrimitives( void RAS_ListRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) @@ -230,18 +224,19 @@ void RAS_ListRasterizer::IndexPrimitivesMulti( } } - if (mUseVertexArrays) { + // 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) { RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } else { RAS_OpenGLRasterizer::IndexPrimitivesMulti( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 4b3304d7396..b1b19144c12 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -52,9 +52,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot @@ -63,9 +61,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 18147b53f4c..dcc36bf5a39 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -368,23 +368,11 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) switch (m_drawingmode) { - case KX_BOUNDINGBOX: - { - } case KX_WIREFRAME: { glDisable (GL_CULL_FACE); break; } - case KX_TEXTURED: - { - } - case KX_SHADED: - { - } - case KX_SOLID: - { - } default: { } @@ -603,33 +591,14 @@ void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - - const RAS_TexVert* vertexarray ; - unsigned int numindices,vt; + const RAS_TexVert* vertexarray; + unsigned int numindices, vt; for (vt=0;vt<vertexarrays.size();vt++) { @@ -643,7 +612,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -655,7 +624,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, glEnd(); } break; - case 2: + case KX_MODE_QUADS: { glBegin(GL_QUADS); vindex=0; @@ -723,7 +692,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, glEnd(); break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; @@ -788,32 +757,14 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, const MT_Vector4& rgbacolor ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - - const RAS_TexVert* vertexarray ; - + const RAS_TexVert* vertexarray; unsigned int numindices, vt; if (useObjectColor) @@ -838,7 +789,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -850,7 +801,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa glEnd(); } break; - case 2: + case KX_MODE_QUADS: { vindex=0; for (unsigned int i=0;i<numindices;i+=4) @@ -883,7 +834,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa } break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; @@ -999,6 +950,9 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) case RAS_TEXCO_UV2: glVertexAttrib2fvARB(unit, tv.getUV2()); break; + case RAS_TEXCO_VCOL: + glVertexAttrib4ubvARB(unit, tv.getRGBA()); + break; default: break; } @@ -1037,32 +991,14 @@ void RAS_OpenGLRasterizer::Tangent( const RAS_TexVert& v1, void RAS_OpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - const RAS_TexVert* vertexarray ; + const RAS_TexVert* vertexarray; unsigned int numindices,vt; for (vt=0;vt<vertexarrays.size();vt++) @@ -1077,7 +1013,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -1089,7 +1025,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glEnd(); } break; - case 2: + case KX_MODE_QUADS: { glBegin(GL_QUADS); vindex=0; @@ -1166,7 +1102,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glEnd(); break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 1f0709e081a..0d54552db05 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -148,9 +148,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot @@ -159,7 +157,7 @@ public: virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, @@ -169,9 +167,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index c4702fe5a74..c78a97ad7be 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -59,9 +59,9 @@ bool RAS_VAOpenGLRasterizer::Init(void) if (result) { glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -77,13 +77,16 @@ void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) { case KX_BOUNDINGBOX: case KX_WIREFRAME: - glDisable (GL_CULL_FACE); + glDisableClientState(GL_COLOR_ARRAY); + glDisable(GL_CULL_FACE); + break; + case KX_SOLID: + glDisableClientState(GL_COLOR_ARRAY); break; case KX_TEXTURED: case KX_SHADED: + case KX_SHADOW: glEnableClientState(GL_COLOR_ARRAY); - case KX_SOLID: - break; default: break; } @@ -102,30 +105,23 @@ void RAS_VAOpenGLRasterizer::Exit() void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) { static const GLsizei vtxstride = sizeof(RAS_TexVert); GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 2: - drawmode = GL_QUADS; - break; - case 1: //lines - default: - drawmode = GL_LINES; - break; - } + if(mode == KX_MODE_TRIANGLES) + drawmode = GL_TRIANGLES; + else if(mode == KX_MODE_QUADS) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + const RAS_TexVert* vertexarray; unsigned int numindices, vt; + if (drawmode != GL_LINES) { if (useObjectColor) @@ -157,9 +153,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays continue; glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); - glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); + glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); + if(glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); //if(m_Lock) // local->Begin(vertexarrays[vt]->size()); @@ -169,8 +166,6 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays //if(m_Lock) // local->End(); - - } glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -178,28 +173,21 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) { static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 2: - drawmode = GL_QUADS; - break; - case 1: //lines - default: - drawmode = GL_LINES; - break; - } + if(mode == KX_MODE_TRIANGLES) + drawmode = GL_TRIANGLES; + else if(mode == KX_MODE_QUADS) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + const RAS_TexVert* vertexarray; unsigned int numindices, vt; @@ -232,10 +220,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa continue; glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - TexCoordPtr(vertexarray); - - glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); + TexCoordPtr(vertexarray); + if(glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); //if(m_Lock) // local->Begin(vertexarrays[vt]->size()); @@ -296,19 +284,22 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) switch(m_attrib[unit]) { case RAS_TEXCO_ORCO: case RAS_TEXCO_GLOB: - glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ()); + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ()); break; case RAS_TEXCO_UV1: - glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); break; case RAS_TEXCO_NORM: - glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); break; case RAS_TEXTANGENT: - glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); break; case RAS_TEXCO_UV2: - glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + break; + case RAS_TEXCO_VCOL: + glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); break; default: break; @@ -386,11 +377,12 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) case RAS_TEXCO_NORM: case RAS_TEXTANGENT: case RAS_TEXCO_UV2: - if(enable) glEnableVertexAttribArray(unit); - else glDisableVertexAttribArray(unit); + case RAS_TEXCO_VCOL: + if(enable) glEnableVertexAttribArrayARB(unit); + else glDisableVertexAttribArrayARB(unit); break; default: - glDisableVertexAttribArray(unit); + glDisableVertexAttribArrayARB(unit); break; } } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index ea08887028f..e4cc4ace0e8 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -52,9 +52,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); @@ -62,9 +60,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 61ac456b2bc..935633dc636 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -40,7 +40,8 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, - const short flag) + const short flag, + const unsigned int origindex) { xyz.getValue(m_localxyz); uv.getValue(m_uv1); @@ -49,6 +50,7 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, SetNormal(normal); tangent.getValue(m_tangent); m_flag = flag; + m_origindex = origindex; m_unit = 2; } @@ -107,44 +109,6 @@ void RAS_TexVert::SetNormal(const MT_Vector3& normal) normal.getValue(m_normal); } -#ifndef RAS_TexVert_INLINE - -// leave multiline for debugging -const float* RAS_TexVert::getUV1 () const -{ - return m_uv1; -} - -const float* RAS_TexVert::getUV2 () const -{ - return m_uv2; -} - - - -const float* RAS_TexVert::getNormal() const -{ - return m_normal; -} - -const float* RAS_TexVert::getTangent() const -{ - return m_tangent; -} - - -const float* RAS_TexVert::getLocalXYZ() const -{ - return m_localxyz; -} - -const unsigned char* RAS_TexVert::getRGBA() const -{ - return (unsigned char*) &m_rgba; -} - -#endif - // compare two vertices, and return TRUE if both are almost identical (they can be shared) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 84135db918f..bf092b4b230 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -42,8 +42,6 @@ static MT_Point2 g_pt2; #define TV_MAX 3//match Def in BL_Material.h -#define RAS_TexVert_INLINE 1 - class RAS_TexVert { @@ -55,9 +53,10 @@ class RAS_TexVert float m_normal[3]; // 3*2 = 6 short m_flag; // 2 unsigned int m_unit; // 4 + unsigned int m_origindex; // 4 //--------- - // 52 - //32 bytes total size, fits nice = 52 = not fit nice. + // 56 + // 32 bytes total size, fits nice = 56 = not fit nice. // We'll go for 64 bytes total size - 24 bytes left. public: short getFlag() const; @@ -71,11 +70,10 @@ public: const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, - const short flag); + const short flag, + const unsigned int origindex); ~RAS_TexVert() {}; - // leave multiline for debugging -#ifdef RAS_TexVert_INLINE const float* getUV1 () const { return m_uv1; }; @@ -99,13 +97,11 @@ public: const unsigned char* getRGBA() const { return (unsigned char *) &m_rgba; } -#else - const float* getUV1 () const; - const float* getUV2 () const; - const float* getNormal() const; - const float* getLocalXYZ() const; - const unsigned char* getRGBA() const; -#endif + + const unsigned int getOrigIndex() const { + return m_origindex; + } + void SetXYZ(const MT_Point3& xyz); void SetUV(const MT_Point2& uv); void SetUV2(const MT_Point2& uv); diff --git a/source/kernel/gen_system/GEN_HashedPtr.h b/source/kernel/gen_system/GEN_HashedPtr.h index 777ec76e067..13faa5f227b 100644 --- a/source/kernel/gen_system/GEN_HashedPtr.h +++ b/source/kernel/gen_system/GEN_HashedPtr.h @@ -39,6 +39,7 @@ public: GEN_HashedPtr(void* val) : m_valptr(val) {}; unsigned int hash() const { return GEN_Hash(m_valptr);}; inline friend bool operator ==(const GEN_HashedPtr & rhs, const GEN_HashedPtr & lhs) { return rhs.m_valptr == lhs.m_valptr;}; + void *getValue() const { return m_valptr; } }; #endif //__GEN_HASHEDPTR diff --git a/source/kernel/gen_system/GEN_Map.h b/source/kernel/gen_system/GEN_Map.h index f9c14800499..37c75d8293a 100644 --- a/source/kernel/gen_system/GEN_Map.h +++ b/source/kernel/gen_system/GEN_Map.h @@ -82,6 +82,24 @@ public: } return 0; } + + Key* getKey(int index) { + int count=0; + for (int i=0;i<m_num_buckets;i++) + { + Entry* bucket = m_buckets[i]; + while(bucket) + { + if (count==index) + { + return &bucket->m_key; + } + bucket = bucket->m_next; + count++; + } + } + return 0; + } void clear() { for (int i = 0; i < m_num_buckets; ++i) { |