From 99fdf27af92b9bd9d05c108f2c2c8a240c5536bc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jul 2008 12:47:20 +0000 Subject: 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. --- source/gameengine/BlenderRoutines/KX_BlenderGL.cpp | 2 +- .../Converter/BL_BlenderDataConversion.cpp | 118 +++++++------- source/gameengine/Converter/BL_MeshDeformer.cpp | 174 +++++++++++---------- source/gameengine/Converter/BL_MeshDeformer.h | 14 +- source/gameengine/Converter/BL_ShapeDeformer.h | 11 +- source/gameengine/Converter/BL_SkinDeformer.cpp | 61 ++++---- source/gameengine/Converter/BL_SkinDeformer.h | 6 +- source/gameengine/Converter/BL_SkinMeshObject.cpp | 84 ---------- source/gameengine/Converter/BL_SkinMeshObject.h | 94 ----------- source/gameengine/Ketsji/BL_BlenderShader.cpp | 80 ++++++---- source/gameengine/Ketsji/BL_BlenderShader.h | 15 +- source/gameengine/Ketsji/BL_Material.cpp | 6 +- source/gameengine/Ketsji/BL_Material.h | 7 +- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 100 ++++++++---- source/gameengine/Ketsji/KX_BlenderMaterial.h | 2 + source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 46 +++++- source/gameengine/Ketsji/KX_KetsjiEngine.h | 1 + source/gameengine/Ketsji/KX_Light.cpp | 80 +++++++++- source/gameengine/Ketsji/KX_Light.h | 16 +- source/gameengine/Ketsji/KX_Scene.cpp | 41 +++-- source/gameengine/Ketsji/KX_Scene.h | 8 +- source/gameengine/Rasterizer/RAS_BucketManager.cpp | 2 +- .../gameengine/Rasterizer/RAS_IPolygonMaterial.cpp | 16 ++ .../gameengine/Rasterizer/RAS_IPolygonMaterial.h | 2 + source/gameengine/Rasterizer/RAS_IRasterizer.h | 59 ++++--- .../gameengine/Rasterizer/RAS_MaterialBucket.cpp | 51 +++--- source/gameengine/Rasterizer/RAS_MaterialBucket.h | 10 +- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 61 +++++--- source/gameengine/Rasterizer/RAS_MeshObject.h | 6 +- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp | 25 ++- .../RAS_OpenGLRasterizer/RAS_ListRasterizer.h | 8 +- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 102 +++--------- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 10 +- .../RAS_VAOpenGLRasterizer.cpp | 94 +++++------ .../RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h | 8 +- source/gameengine/Rasterizer/RAS_TexVert.cpp | 42 +---- source/gameengine/Rasterizer/RAS_TexVert.h | 24 ++- 38 files changed, 730 insertions(+), 758 deletions(-) (limited to 'source/gameengine') 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; layuv[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(mesh->mface); MTFace* tface = static_cast(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;ftotface;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(ob->data), ob->lay, kxscene, rendertools, converter); + KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast(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; isize(); 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; imvert[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; iUsesTriangles()? 3: 4; for(j=0; jgetLocalXYZ(); + + 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; itotvert)][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*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 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; isize(); 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; im_MvertArrayCache1[vtxarray]->size(); - - /* Check to see if this has already been pushed */ - for (vector::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;im_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* va = new vector; - 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 BL_MVertArray; -typedef vector BL_DeformVertArray; -typedef vector BL_VertexArray; - - -typedef vector*> vecMDVertArray; -typedef vector*> vecBVertexArray; - -class BL_SkinArrayOptimizer : public KX_ArrayOptimizer -{ -public: - BL_SkinArrayOptimizer(int index) - :KX_ArrayOptimizer (index) {}; - virtual ~BL_SkinArrayOptimizer(){ - - for (vector::iterator itv = m_MvertArrayCache1.begin(); - !(itv == m_MvertArrayCache1.end());itv++) - { - delete (*itv); - } - for (vector::iterator itd = m_DvertArrayCache1.begin(); - !(itd == m_DvertArrayCache1.end());itd++) - { - delete (*itd); - } - for (vector::iterator iti = m_DIndexArrayCache1.begin(); - !(iti == m_DIndexArrayCache1.end());iti++) - { - delete (*iti); - } - - m_MvertArrayCache1.clear(); - m_DvertArrayCache1.clear(); - m_DIndexArrayCache1.clear(); - }; - - vector m_MvertArrayCache1; - vector m_DvertArrayCache1; - vector 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 m_cacheWeightIndex; public: - struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; }; - vector > 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; inum_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; inum_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("<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("<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("<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(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; iGetCount(); 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(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(mesh) + newobj, oldblendobj, static_cast(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(m_objectlist->GetValue(i)), cam); + MarkVisible(rasty, static_cast(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 @@ -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 +using namespace std; + class RAS_ICanvas; class RAS_IPolyMaterial; -#include "RAS_MaterialBucket.h" + +typedef vector KX_IndexArray; +typedef vector 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 #include #include using namespace std; -typedef vector KX_IndexArray; -typedef vector 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::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin(); - it != m_xyz_index_to_vertex_index_mapping[orgindex].end(); + for (std::vector::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;igetValue()); + 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; + GEN_Map 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;vtgetLocalXYZ()); - 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); -- cgit v1.2.3