diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-06-15 03:51:01 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-06-15 03:51:01 +0400 |
commit | 38fa819cbd5d8b61d9ebd1e8677a1d52232b2a8d (patch) | |
tree | 3bcd7f29473449acd5471f0501d30a769d5843d8 /source/gameengine | |
parent | 07e5dc0b969c4478829a60c66e6ec43bec77056a (diff) |
Apricot Branch:
Some optimizations to decrease game engine startup time:
* Exporting skinned meshes was doing O(n^2) lookups for vertices and
deform weights, now uses same trick as regular meshes.
* Share GLSL shaders with the game engine so they don't have to be
recompiled. This required changes to the rasterization in the game
engine to add an option to use attributes instead of texture
coordinates.
* Some small optimizations in bullet BVH building, though could be
improved more, since it takes about 50% of startup time still in
my test .blend.
Diffstat (limited to 'source/gameengine')
20 files changed, 216 insertions, 99 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 9826d752f0e..2760b18f811 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -732,14 +732,14 @@ static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh) MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert]; MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert]; - unsigned int v; + int v; for (v = 0; v < mesh->totvert; v++) { tan1[v] = MT_Vector3(0.0, 0.0, 0.0); tan2[v] = MT_Vector3(0.0, 0.0, 0.0); } - for (unsigned int p = 0; p < mesh->totface; p++, mface++, tface++) + for (int p = 0; p < mesh->totface; p++, mface++, tface++) { MT_Vector3 v1(mesh->mvert[mface->v1].co), v2(mesh->mvert[mface->v2].co), @@ -833,6 +833,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* 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++) { @@ -882,7 +884,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* Material* ma = 0; bool polyvisible = true; RAS_IPolyMaterial* polymat = NULL; - BL_Material *bl_mat; + BL_Material *bl_mat = NULL; if(converter->GetMaterials()) { @@ -1067,19 +1069,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* 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)); - poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat, polymat)); - poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat, 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)); + 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,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,polymat,mface->v3)); + 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,polymat,mface->v4)); + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,false,polymat,mface->v4)); } meshobj->AddPolygon(poly); if (poly->IsCollider()) @@ -1117,6 +1119,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* layer.face++; } } + 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 diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index a6be11d786e..7be3d84fb3f 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -48,9 +48,9 @@ public: BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ): m_pMeshObject(meshobj), m_bmesh((struct Mesh*)(obj->data)), - m_objMesh(obj), m_transnors(NULL), m_transverts(NULL), + m_objMesh(obj), m_tvtot(0) {}; virtual ~BL_MeshDeformer(); diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index e130dc15dbf..79f6453a25d 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -69,8 +69,8 @@ public: m_armobj(arma), m_lastUpdate(-1), m_defbase(&bmeshobj->defbase), - m_releaseobject(false), - m_restoremat(false) + m_restoremat(false), + m_releaseobject(false) { }; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 8bc78c7f757..f090cabd7ab 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -61,15 +61,23 @@ int BL_SkinMeshObject::FindOrAddDeform(unsigned int vtxarray, unsigned int mv, s { 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 (unsigned int i=0; i<ao->m_MvertArrayCache1[vtxarray]->size(); i++){ - if (mv == (*ao->m_MvertArrayCache1[vtxarray])[i]) - return i; + 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; }; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index 0ca7428c0f0..2422d4cd4c9 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -106,6 +106,9 @@ class BL_SkinMeshObject : public RAS_MeshObject protected: 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); @@ -139,37 +142,17 @@ public: const MT_Point2& uv2, const MT_Vector4& tangent, const unsigned int rgbacolor, - const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat) + const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat, int origindex) { - RAS_TexVert tempvert(xyz,uv,uv2, tangent,rgbacolor,normal,flat ? TV_CALCFACENORMAL : 0); - - // KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - - int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - - int index=-1; - - for (int i=0;i<numverts;i++) - { - const RAS_TexVert& vtx = (*ao->m_VertexArrayCache1[vtxarray])[i]; - if (tempvert.closeTo(&vtx)) - { - index = i; - break; - } - - } - if (index >= 0) - return index; - - // no vertex found, add one - ao->m_VertexArrayCache1[vtxarray]->push_back(tempvert); - ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr); - - return numverts; - - + 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; } }; diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 45e4ca17b1f..e0813c2a5ab 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -20,14 +20,13 @@ BL_BlenderShader::BL_BlenderShader(struct Material *ma) mBound(false) { if(ma) - mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_GAME); + mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH); } BL_BlenderShader::~BL_BlenderShader() { if(mGPUMat) { GPU_material_unbind(mGPUMat); - GPU_material_free(mGPUMat); mGPUMat = 0; } } @@ -50,27 +49,52 @@ void BL_BlenderShader::SetProg(bool enable) } } +int BL_BlenderShader::GetEnabledAttribs() +{ + GPUVertexAttribs attribs; + int i, enabled = 0; + + if(!mGPUMat) + return enabled; + + GPU_material_vertex_attributes(mGPUMat, &attribs); + + for(i = 0; i < attribs.totlayer; i++) + if(attribs.layer[i].glindex+1 > enabled) + enabled= attribs.layer[i].glindex+1; + + if(enabled > BL_MAX_ATTRIB) + enabled = BL_MAX_ATTRIB; + + return enabled; +} + void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) { GPUVertexAttribs attribs; - int i; + int i, enabled; if(!mGPUMat) return; GPU_material_vertex_attributes(mGPUMat, &attribs); + enabled = GetEnabledAttribs(); + for(i=0; i<enabled; i++) + ras->SetTexCoordsAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + for(i = 0; i < attribs.totlayer; i++) { + if(attribs.layer[i].glindex > enabled) + continue; + if(attribs.layer[i].type == CD_MTFACE) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_UV1, i); + ras->SetTexCoordsAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_TANGENT) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXTANGENT, i); + ras->SetTexCoordsAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_ORCO) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_ORCO, i); + ras->SetTexCoordsAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_NORMAL) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_NORM, i); - else - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + ras->SetTexCoordsAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex); } } diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index 95f2cfe044d..1a7c5117cb2 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -12,6 +12,8 @@ struct Material; +#define BL_MAX_ATTRIB 16 + /** * BL_BlenderShader * Blender GPU shader material @@ -31,6 +33,7 @@ public: void ApplyShader(); void SetTexCoords(class RAS_IRasterizer* ras); + int GetEnabledAttribs(); void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty); }; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index d4c6db9f598..ddb6662830a 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -20,7 +20,7 @@ struct EnvMap; although the more you add the slower the search time will be. we will go for three, which should be enough */ -#define MAXTEX 3//match in RAS_TexVert & RAS_OpenGLRasterizer +#define MAXTEX 3 //match in RAS_TexVert & RAS_OpenGLRasterizer // different mapping modes class BL_Mapping diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 903db2592a7..a4a9c89d17f 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -821,11 +821,14 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(void) { if(!mBlenderShader) mBlenderShader = new BL_BlenderShader(mMaterial->material); - + if(!mBlenderShader->Ok()) { + m_enabledattribs = 0; delete mBlenderShader; mBlenderShader = 0; } + else + m_enabledattribs = mBlenderShader->GetEnabledAttribs(); } KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 61860c4c405..ab00658dde6 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -57,6 +57,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, m_polymatid(m_newpolymatid++), m_flag(0), m_enabled(0), + m_enabledattribs(0), m_multimode(0) { m_shininess = 35.0; @@ -153,5 +154,11 @@ const unsigned int RAS_IPolyMaterial::GetEnabled() const return m_enabled; } +const unsigned int RAS_IPolyMaterial::GetEnabledAttribs() const +{ + return m_enabledattribs; +} + + unsigned int RAS_IPolyMaterial::m_newpolymatid = 0; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 3284ddb7ddd..0813b7f7463 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -78,6 +78,7 @@ protected: // will move... unsigned int m_flag;//MaterialProps unsigned int m_enabled;// enabled for this mat + unsigned int m_enabledattribs;// attribs enabled for this mat int m_multimode; // sum of values public: @@ -142,6 +143,7 @@ public: const STR_String& GetTextureName() const; const unsigned int GetFlag() const; const unsigned int GetEnabled() const; + const unsigned int GetEnabledAttribs() const; /* * PreCalculate texture gen diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 18a7f261c94..fb2c898cdd5 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -390,6 +390,7 @@ public: virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0; virtual void SetTexCoords(TexCoGen coords, int unit) = 0; + virtual void SetTexCoordsAttrib(TexCoGen coords, int unit) = 0; virtual void SetAttrib(int type) = 0; virtual void GetViewMatrix(MT_Matrix4x4 &mat) const = 0; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index e4b654343e7..0374ffba478 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -256,13 +256,14 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, + bool flat, RAS_IPolyMaterial* mat, int orgindex) { KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, 0); + RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0); #define KX_FIND_SHARED_VERTICES #ifdef KX_FIND_SHARED_VERTICES diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 89c472cd0d4..d8e7a3391aa 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -238,6 +238,7 @@ public: const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, + bool flat, RAS_IPolyMaterial* mat, int orgindex ); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index 81a7ccb7a5d..43405779998 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -426,6 +426,7 @@ PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; + PFNGLVERTEXATTRIBPOINTERARBPROC blVertexAttribPointerARB; PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; @@ -634,6 +635,7 @@ static void LinkExtensions() bgl::blVertexAttrib3fvARB = reinterpret_cast<PFNGLVERTEXATTRIB3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fvARB")); bgl::blVertexAttrib4fARB = reinterpret_cast<PFNGLVERTEXATTRIB4FARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fARB")); bgl::blVertexAttrib4fvARB = reinterpret_cast<PFNGLVERTEXATTRIB4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fvARB")); + bgl::blVertexAttribPointerARB = reinterpret_cast<PFNGLVERTEXATTRIBPOINTERARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttribPointerARB")); bgl::blGetVertexAttribdvARB = reinterpret_cast<PFNGLGETVERTEXATTRIBDVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribdvARB")); bgl::blGetVertexAttribfvARB = reinterpret_cast<PFNGLGETVERTEXATTRIBFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribfvARB")); bgl::blGetVertexAttribivARB = reinterpret_cast<PFNGLGETVERTEXATTRIBIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribivARB")); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h index 3e24ee204a1..fd253d7030c 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -523,6 +523,7 @@ extern PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB; extern PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; extern PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; extern PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; +extern PFNGLVERTEXATTRIBPOINTERARBPROC blVertexAttribPointerARB; extern PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; extern PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; extern PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index f99121e5b7c..f07e54d92a8 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -1213,12 +1213,19 @@ void RAS_OpenGLRasterizer::SetTexCoords(TexCoGen coords,int unit) m_texco[unit] = coords; } +void RAS_OpenGLRasterizer::SetTexCoordsAttrib(TexCoGen coords,int unit) +{ + // this changes from material to material + if(unit < RAS_MAX_ATTRIB) + m_texcoattrib[unit] = coords; +} + void RAS_OpenGLRasterizer::SetAttrib(int type) { if(type == RAS_TEXTANGENT) m_useTang=true; } -void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled) +void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled, int enabledattribs) { #if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) if (!getenv("WITHOUT_GLEXT")) { @@ -1256,8 +1263,39 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled) #endif #ifdef GL_ARB_vertex_program - if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program) - bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent()); + if(bgl::RAS_EXT_support._ARB_vertex_program) { + for(int unit=0; unit<enabledattribs; unit++) { + if( tv.getFlag() & TV_2NDUV && tv.getUnit() == unit ) { + bgl::blVertexAttrib2fvARB(unit, tv.getUV2()); + continue; + } + switch(m_texcoattrib[unit]) { + case RAS_TEXCO_DISABLE: + case RAS_TEXCO_OBJECT: + case RAS_TEXCO_GEN: + break; + case RAS_TEXCO_ORCO: + case RAS_TEXCO_GLOB: + bgl::blVertexAttrib3fvARB(unit, tv.getLocalXYZ()); + break; + case RAS_TEXCO_UV1: + bgl::blVertexAttrib2fvARB(unit, tv.getUV1()); + break; + case RAS_TEXCO_NORM: + bgl::blVertexAttrib3fvARB(unit, tv.getNormal()); + break; + case RAS_TEXTANGENT: + bgl::blVertexAttrib4fvARB(unit, tv.getTangent()); + break; + case RAS_TEXCO_UV2: + bgl::blVertexAttrib2fvARB(unit, tv.getUV2()); + break; + } + } + + if(m_useTang) + bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent()); + } #endif } @@ -1332,6 +1370,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( const KX_IndexArray & indexarray = (*indexarrays[vt]); numindices = indexarray.size(); const unsigned int enabled = polymat->GetEnabled(); + const unsigned int enabledattribs = polymat->GetEnabledAttribs(); if (!numindices) break; @@ -1364,25 +1403,25 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1399,28 +1438,28 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1440,19 +1479,19 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1464,21 +1503,21 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; // glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1533,6 +1572,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( const KX_IndexArray & indexarray = (*indexarrays[vt]); numindices = indexarray.size(); const unsigned int enabled = polymat->GetEnabled(); + const unsigned int enabledattribs = polymat->GetEnabledAttribs(); if (!numindices) continue; @@ -1584,27 +1624,27 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1640,7 +1680,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; @@ -1648,7 +1688,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; @@ -1656,7 +1696,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; @@ -1664,7 +1704,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1701,19 +1741,19 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1743,21 +1783,21 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - TexCoord(vertexarray[(indexarray[vindex])],enabled ); + TexCoord(vertexarray[(indexarray[vindex])],enabled,enabledattribs ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 23714a12151..4282df97df2 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -41,7 +41,8 @@ using namespace std; #include "RAS_MaterialBucket.h" #include "RAS_ICanvas.h" -#define RAS_MAX 3// match in BL_Material +#define RAS_MAX 3 // match in BL_Material +#define RAS_MAX_ATTRIB 16 // match in BL_BlenderShader struct OglDebugLine { @@ -95,6 +96,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer protected: int m_drawingmode; TexCoGen m_texco[RAS_MAX]; + TexCoGen m_texcoattrib[RAS_MAX_ATTRIB]; bool m_useTang; /** Stores the caching information for the last material activated. */ @@ -286,9 +288,10 @@ public: std::vector <OglDebugLine> m_debugLines; - virtual void SetTexCoords(TexCoGen coords,int enabled); + virtual void SetTexCoords(TexCoGen coords,int unit); + virtual void SetTexCoordsAttrib(TexCoGen coords,int unit); virtual void SetAttrib(int type); - void TexCoord(const RAS_TexVert &tv, int unit); + void TexCoord(const RAS_TexVert &tv, int enabled, int enabledattribs); virtual void GetViewMatrix(MT_Matrix4x4 &mat) const; void Tangent(const RAS_TexVert& v1, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index ddfcc3f3f9d..ec99e2c2c44 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -244,6 +244,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa const RAS_TexVert* vertexarray; unsigned int numindices, vt; const unsigned int enabled = polymat->GetEnabled(); + const unsigned int enabledattribs = polymat->GetEnabledAttribs(); if (drawmode != GL_LINES) { @@ -273,7 +274,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa continue; glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - TexCoordPtr(vertexarray, enabled); + TexCoordPtr(vertexarray, enabled, enabledattribs); //glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); @@ -290,7 +291,7 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa } } -void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled) +void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled, int enabledattribs) { #if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) if (!getenv("WITHOUT_GLEXT")) { @@ -331,11 +332,43 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled) } } } + } +#endif #ifdef GL_ARB_vertex_program - if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program) + if(bgl::RAS_EXT_support._ARB_vertex_program) { + for(int unit=0; unit<enabledattribs; unit++) { + if( tv->getFlag() & TV_2NDUV && tv->getUnit() == unit ) { + bgl::blVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + continue; + } + switch(m_texcoattrib[unit]) { + case RAS_TEXCO_DISABLE: + case RAS_TEXCO_OBJECT: + case RAS_TEXCO_GEN: + break; + case RAS_TEXCO_ORCO: + case RAS_TEXCO_GLOB: + bgl::blVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ()); + break; + case RAS_TEXCO_UV1: + bgl::blVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); + break; + case RAS_TEXCO_NORM: + bgl::blVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + break; + case RAS_TEXTANGENT: + bgl::blVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + break; + case RAS_TEXCO_UV2: + bgl::blVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + break; + } + } + + /* TODO brecht: this looks broken? test if it ever runs */ + if(m_useTang) bgl::blVertexAttrib4fvARB(1/*tangent*/, tv->getTangent()); -#endif } #endif } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index 4d478b0171f..a793e070a4c 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -33,7 +33,7 @@ class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer { - void TexCoordPtr(const RAS_TexVert *tv, int unit); + void TexCoordPtr(const RAS_TexVert *tv, int enabled, int enabledattribs); bool m_Lock; public: |