From e4790aef46f7ca0b4ab01c34f043be9e7b1fa7f1 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Mon, 13 Feb 2006 05:45:32 +0000 Subject: Improved OpenGL Shader Language support for game engine. The python interface is much simplified. Drawback is that scripts need to be updated next release. Testfiles: http://www.continuousphysics.com/ftp/pub/test/index.php?dir=blender/&file=demos-2.42.zip patch by Charlie Carley (snailrose @ elysiun.com) --- source/gameengine/BlenderRoutines/KX_BlenderGL.cpp | 45 +- .../Converter/BL_BlenderDataConversion.cpp | 137 +++++- source/gameengine/Converter/BL_SkinMeshObject.h | 3 +- .../gameengine/GameLogic/SCA_PythonController.cpp | 5 +- source/gameengine/Ketsji/BL_Material.cpp | 20 + source/gameengine/Ketsji/BL_Material.h | 20 +- source/gameengine/Ketsji/BL_Shader.cpp | 512 +++++++++++++++++---- source/gameengine/Ketsji/BL_Shader.h | 86 +++- source/gameengine/Ketsji/BL_Texture.cpp | 402 ++++++++++++---- source/gameengine/Ketsji/BL_Texture.h | 62 ++- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 490 +++++--------------- source/gameengine/Ketsji/KX_BlenderMaterial.h | 51 +- source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- source/gameengine/Ketsji/KX_GameObject.h | 2 - source/gameengine/Ketsji/KX_PythonInit.cpp | 18 + .../gameengine/Rasterizer/RAS_IPolygonMaterial.h | 2 +- source/gameengine/Rasterizer/RAS_IRasterizer.h | 24 + .../gameengine/Rasterizer/RAS_MaterialBucket.cpp | 9 +- source/gameengine/Rasterizer/RAS_MaterialBucket.h | 3 +- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 4 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 1 + .../RAS_OpenGLRasterizer/ARB_multitexture.h | 47 +- .../RAS_GLExtensionManager.cpp | 54 +++ .../RAS_OpenGLRasterizer/RAS_GLExtensionManager.h | 22 +- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 257 ++++------- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 9 + source/gameengine/Rasterizer/RAS_TexVert.cpp | 8 + source/gameengine/Rasterizer/RAS_TexVert.h | 5 + 28 files changed, 1458 insertions(+), 842 deletions(-) (limited to 'source') diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 50751be7c7d..af367f1797e 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -48,6 +48,17 @@ #include "BMF_Api.h" +#ifdef __APPLE__ +#define GL_GLEXT_LEGACY 1 +#include +#include +#else +#include +#include +#endif +#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" +#include "RAS_OpenGLRasterizer/ARB_multitexture.h" +#include "BL_Material.h" // MAXTEX /* Data types encoding the game world: */ #include "DNA_object_types.h" @@ -166,10 +177,39 @@ void BL_RenderText(int mode,const char* textstr,int textlen,struct TFace* tface, } +void DisableForText() +{ + if(glIsEnabled(GL_BLEND)) + glDisable(GL_BLEND); + + if(glIsEnabled(GL_LIGHTING)) { + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + } +#ifdef GL_ARB_multitexture + for(int i=0; iflag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0; material->ras_mode|= ( tface->transp &(TF_ADD | TF_ALPHA))?TRANSP:0; - material->mapping[i].mapping |= ( (material->img[i]->flag & IMA_REFLECT)!=0 )?USEREFL:0; - //material->blend_mode[i] = BLEND_MUL; - i++;// skip to the next image + if(material->img[i]->flag & IMA_REFLECT) + material->mapping[i].mapping |= USEREFL; + else + material->mapping[i].mapping |= USEUV; + i++; valid_index++; } } @@ -416,6 +418,16 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* if(mttmp->object) material->mapping[i].objconame = mttmp->object->id.name; } + else if(mttmp->texco &TEXCO_REFL) + material->mapping[i].mapping |= USEREFL; + else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB)) + material->mapping[i].mapping |= USEORCO; + else if(mttmp->texco &TEXCO_UV) + material->mapping[i].mapping |= USEUV; + else if(mttmp->texco &TEXCO_NORM) + material->mapping[i].mapping |= USENORM; + else + material->mapping[i].mapping |= DISABLE; material->mapping[i].scale[0] = mttmp->size[0]; material->mapping[i].scale[1] = mttmp->size[1]; @@ -463,6 +475,7 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* material->IdMode = GREATERTHAN2; break; } + material->SetUsers(mat->id.us); material->num_enabled = valid_index; @@ -497,6 +510,7 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* valid++; } } + material->SetUsers(-1); material->num_enabled = valid; material->IdMode = TEXFACE; material->speccolor[0] = 1.f; @@ -556,6 +570,87 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* } +static void BL_ComputeTriTangentSpace(const MT_Vector3 &v1, const MT_Vector3 &v2, const MT_Vector3 &v3, + const MT_Vector2 &uv1, const MT_Vector2 &uv2, const MT_Vector2 &uv3, + MFace* mface, MT_Vector3 *tan1, MT_Vector3 *tan2) +{ + MT_Vector3 dx1(v2 - v1), dx2(v3 - v1); + MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1); + + MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y()); + duv1 *= r; + duv2 *= r; + MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2); + MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1); + + tan1[mface->v1] += sdir; + tan1[mface->v2] += sdir; + tan1[mface->v3] += sdir; + + tan2[mface->v1] += tdir; + tan2[mface->v2] += tdir; + tan2[mface->v3] += tdir; +} + +static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh) +{ + MFace* mface = static_cast(mesh->mface); + TFace* tface = static_cast(mesh->tface); + + MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert]; + MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert]; + + unsigned 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++) + { + MT_Vector3 v1(mesh->mvert[mface->v1].co), + v2(mesh->mvert[mface->v2].co), + v3(mesh->mvert[mface->v3].co); + + MT_Vector2 uv1(tface->uv[0]), + uv2(tface->uv[1]), + uv3(tface->uv[2]); + + BL_ComputeTriTangentSpace(v1, v2, v3, uv1, uv2, uv3, mface, tan1, tan2); + if (mface->v4) + { + MT_Vector3 v4(mesh->mvert[mface->v4].co); + MT_Vector2 uv4(tface->uv[3]); + + BL_ComputeTriTangentSpace(v1, v3, v4, uv1, uv3, uv4, mface, tan1, tan2); + } + } + + MT_Vector4 *tangent = new MT_Vector4[mesh->totvert]; + for (v = 0; v < mesh->totvert; v++) + { + const MT_Vector3 no(mesh->mvert[v].no[0]/32767.0, + mesh->mvert[v].no[1]/32767.0, + mesh->mvert[v].no[2]/32767.0); + // Gram-Schmidt orthogonalize + MT_Vector3 t(tan1[v] - no.cross(no.cross(tan1[v]))); + if (!MT_fuzzyZero(t)) + t /= t.length(); + + tangent[v].x() = t.x(); + tangent[v].y() = t.y(); + tangent[v].z() = t.z(); + // Calculate handedness + tangent[v].w() = no.dot(tan1[v].cross(tan2[v])) < 0.0 ? -1.0 : 1.0; + } + + delete [] tan1; + delete [] tan2; + + return tangent; +} + RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter) { RAS_MeshObject *meshobj; @@ -576,6 +671,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* else { meshobj = new RAS_MeshObject(lightlayer); } + MT_Vector4 *tangent = 0; + if (tface) + tangent = BL_ComputeMeshTangentSpace(mesh); meshobj->SetName(mesh->id.name); @@ -600,7 +698,11 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* pt1(mesh->mvert[mface->v2].co), pt2(mesh->mvert[mface->v3].co), pt3(0.0, 0.0, 0.0); - + MT_Vector4 tan0(0.0, 0.0, 0.0, 0.0), + tan1(0.0, 0.0, 0.0, 0.0), + tan2(0.0, 0.0, 0.0, 0.0), + tan3(0.0, 0.0, 0.0, 0.0); + no0 /= 32767.0; no1 /= 32767.0; no2 /= 32767.0; @@ -655,6 +757,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* uv1 = uv[1]; uv2 = uv[2]; uv3 = uv[3]; + if(tangent){ + tan0 = tangent[mface->v1]; + tan1 = tangent[mface->v2]; + tan2 = tangent[mface->v3]; + if (mface->v4) + tan3 = tangent[mface->v4]; + } // this is needed to free up memory afterwards converter->RegisterPolyMaterial(polymat); } @@ -800,19 +909,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,rgb0,no0,d1,flat, polymat)); - poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,d2,flat, polymat)); - poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,d3,flat, polymat)); + poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,tan0,rgb0,no0,d1,flat, polymat)); + poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,tan1,rgb1,no1,d2,flat, polymat)); + poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,tan2,rgb2,no2,d3,flat, polymat)); if (nverts==4) - poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,d4, flat,polymat)); + poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,tan3,rgb3,no3,d4, flat,polymat)); } else { - poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,polymat,mface->v3)); + poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,tan0,rgb0,no0,polymat,mface->v1)); + poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,tan1,rgb1,no1,polymat,mface->v2)); + poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,tan2,rgb2,no2,polymat,mface->v3)); if (nverts==4) - poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,polymat,mface->v4)); + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,tan3,rgb3,no3,polymat,mface->v4)); } meshobj->AddPolygon(poly); if (poly->IsCollider()) @@ -850,7 +959,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* mit != meshobj->GetLastMaterial(); ++ mit) { (*mit)->GetPolyMaterial()->OnConstruction(); } - // ----------------------------------- + + if(tangent) + delete [] tangent; return meshobj; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index b233088acba..b4e194a3941 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -139,10 +139,11 @@ public: 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_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat) { - RAS_TexVert tempvert(xyz,uv,rgbacolor,normal,flat ? TV_CALCFACENORMAL : 0); + RAS_TexVert tempvert(xyz,uv,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]); diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index a5360d99a8b..48d24bef623 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -277,7 +277,8 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) PyDict_Clear(excdict); Py_DECREF(excdict);*/ -// FIXME:: still happining, will try to fix. snailrose... + +#if 1 PyObject *excdict= PyDict_Copy(m_pythondictionary); PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, excdict, @@ -285,7 +286,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) ); PyDict_Clear(excdict); Py_DECREF(excdict); - +#endif #if 0 PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 29012904ea1..63ba0924b1c 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -54,6 +54,8 @@ BL_Material::BL_Material() material_index = 0; amb=0.5f; num_enabled = 0; + num_users = 1; + share = false; int i; for(i=0; i<4; i++) @@ -114,3 +116,21 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){ } +void BL_Material::SetSharedMaterial(bool v) +{ + if((v && num_users == -1) || num_users > 1 ) + share = true; + else + share = false; +} + +bool BL_Material::IsShared() +{ + return share; +} + +void BL_Material::SetUsers(int num) +{ + num_users = num; +} + diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index cf753414245..7a813cc6c72 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 +#define MAXTEX 3//match in RAS_TexVert & RAS_OpenGLRasterizer // different mapping modes class BL_Mapping @@ -39,6 +39,10 @@ class BL_Material private: unsigned int rgb[4]; MT_Point2 uv[4]; + + int num_users; + bool share; + public: // ----------------------------------- BL_Material(); @@ -82,6 +86,9 @@ public: void SetConversionUV(MT_Point2 *uv); void GetConversionUV(MT_Point2 *uv); + void SetSharedMaterial(bool v); + bool IsShared(); + void SetUsers(int num); }; // BL_Material::IdMode @@ -132,9 +139,14 @@ enum BL_ras_mode // BL_Material::mapping[index]::mapping enum BL_MappingFlag { - USEREFL=1, - USEENV=2, - USEOBJ=4 + USEENV =1, + // -- + USEREFL =2, + USEOBJ =4, + USENORM =8, + USEORCO =16, + USEUV =32, + DISABLE =64 }; // BL_Material::BL_Mapping::projplane diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index f6aa8f625d6..bd9983a2ba7 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -23,6 +23,8 @@ #include "MEM_guardedalloc.h" #include "RAS_GLExtensionManager.h" +#include "RAS_MeshObject.h" +#include "RAS_IRasterizer.h" //using namespace bgl; #define spit(x) std::cout << x << std::endl; @@ -32,19 +34,20 @@ const bool BL_Shader::Ok()const return (mShader !=0 && mOk && mUse); } + BL_Shader::BL_Shader(PyTypeObject *T) : PyObjectPlus(T), mShader(0), - mVert(0), - mFrag(0), mPass(1), mOk(0), mUse(0), vertProg(""), fragProg(""), mError(0), - mLog(0) - + mAttr(0), + mPreDefLoc(-1), + mPreDefType(-1), + mDeleteTexture(0) { // if !RAS_EXT_support._ARB_shader_objects this class will not be used @@ -53,7 +56,8 @@ BL_Shader::BL_Shader(PyTypeObject *T) mSampler[i].pass = 0; mSampler[i].unit = -1; mSampler[i].loc = -1; - mSampler[i].glTexture =0; + mSampler[i].gl_texture = 0; + mSampler[i].flag=0; } } @@ -62,23 +66,18 @@ using namespace bgl; BL_Shader::~BL_Shader() { #ifdef GL_ARB_shader_objects - if(mLog) { - MEM_freeN(mLog); - mLog=0; + for (int i=0; iDeleteTex(); + } } if( mShader ) { bgl::blDeleteObjectARB(mShader); mShader = 0; } - if( mFrag ) { - bgl::blDeleteObjectARB(mFrag); - mFrag = 0; - } - if( mVert ) { - bgl::blDeleteObjectARB(mVert); - mVert = 0; - } - vertProg = 0; fragProg = 0; mOk = 0; @@ -92,8 +91,8 @@ bool BL_Shader::LinkProgram() { #ifdef GL_ARB_shader_objects - GLint vertlen = 0, fraglen=0, proglen=0; - GLint vertstatus=0, fragstatus=0, progstatus=0; + int vertlen = 0, fraglen=0, proglen=0; + int vertstatus=0, fragstatus=0, progstatus=0; unsigned int tmpVert=0, tmpFrag=0, tmpProg=0; int char_len=0; @@ -118,28 +117,44 @@ bool BL_Shader::LinkProgram() bgl::blShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0); bgl::blCompileShaderARB(tmpVert); bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertlen); + // print info if any - if( vertlen > 1){ - PrintInfo(vertlen,tmpVert, &char_len); - goto programError; + if( vertlen > 0){ + STR_String str("",vertlen); + bgl::blGetInfoLogARB(tmpVert, vertlen, &char_len, str.Ptr()); + if(char_len >0) { + spit("---- Vertex Shader Error ----"); + spit(str.ReadPtr()); + } + str.Clear(); } // check for compile errors bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB, &vertstatus); - if(!vertstatus) + if(!vertstatus) { + spit("---- Vertex shader failed to compile ----"); goto programError; + } // -- fragment shader ---------------- tmpFrag = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); bgl::blShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0); bgl::blCompileShaderARB(tmpFrag); bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fraglen); - if(fraglen >1 ){ - PrintInfo(fraglen,tmpFrag, &char_len); - goto programError; + if(fraglen >0 ){ + STR_String str("",fraglen); + bgl::blGetInfoLogARB(tmpFrag, fraglen, &char_len, str.Ptr()); + if(char_len >0) { + spit("---- Fragment Shader Error ----"); + spit(str.ReadPtr()); + } + str.Clear(); } + bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, &fragstatus); - if(!fragstatus) + if(!fragstatus){ + spit("---- Fragment shader failed to compile ----"); goto programError; + } // -- program ------------------------ @@ -150,22 +165,29 @@ bool BL_Shader::LinkProgram() bgl::blLinkProgramARB(tmpProg); bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, &proglen); bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, &progstatus); - if(!progstatus) - goto programError; + if(proglen > 0) { - // print success - PrintInfo(proglen,tmpProg, &char_len); - if(char_len >0) - spit(mLog); - mError = 0; + STR_String str("",proglen); + bgl::blGetInfoLogARB(tmpProg, proglen, &char_len, str.Ptr()); + if(char_len >0) { + spit("---- GLSL Program ----"); + spit(str.ReadPtr()); + } + str.Clear(); + } + + if(!progstatus){ + spit("---- GLSL program failed to link ----"); + goto programError; } // set mShader = tmpProg; - mVert = tmpVert; - mFrag = tmpFrag; + bgl::blDeleteObjectARB(tmpVert); + bgl::blDeleteObjectARB(tmpFrag); mOk = 1; + mError = 0; return true; programError: @@ -183,32 +205,15 @@ programError: tmpProg=0; } - mOk = 0; - mUse=0; - mError = 1; - spit("----------"); - spit("GLSL Error "); - if(mLog) - spit(mLog); - spit("--------------------"); + mOk = 0; + mUse = 0; + mError = 1; return false; #else return false; #endif//GL_ARB_shader_objects } -void BL_Shader::PrintInfo(int len, unsigned int handle, int* num) -{ -#ifdef GL_ARB_shader_objects - GLsizei number; - mLog = (char*)MEM_mallocN(sizeof(char)*len, "print_log"); - //MT_assert(mLog, "Failed to create memory"); - bgl::blGetInfoLogARB(handle, len, &number, mLog); - *num = number; -#endif//GL_ARB_shader_objects -} - - char *BL_Shader::GetVertPtr() { return vertProg?vertProg:0; @@ -234,34 +239,303 @@ unsigned int BL_Shader::GetProg() return mShader; } -unsigned int BL_Shader::GetVertexShader() -{ - return mVert; -} - -unsigned int BL_Shader::GetFragmentShader() -{ - return mFrag; -} - const uSampler* BL_Shader::getSampler(int i) { MT_assert(i<=MAXTEX); return &mSampler[i]; } +void BL_Shader::SetSampler(int loc, int unit) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + bgl::blUniform1iARB(loc, unit); + } +#endif +} + + void BL_Shader::InitializeSampler( int type, int unit, int pass, - unsigned int texture) + BL_Texture* texture) { MT_assert(unit<=MAXTEX); - mSampler[unit].glTexture = texture; + mSampler[unit].gl_texture = texture; mSampler[unit].loc =-1; mSampler[unit].pass=0; mSampler[unit].type=type; mSampler[unit].unit=unit; + mSampler[unit].flag = 0; +} + + +void BL_Shader::SetProg(bool enable) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + if( mShader != 0 && mOk && enable) { + bgl::blUseProgramObjectARB(mShader); + } + else { + bgl::blUseProgramObjectARB(0); + } + } +#endif +} + +void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) +{ +#ifdef GL_ARB_shader_objects + if(!Ok()) return; + + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + MT_Matrix4x4 model; + model.setValue(ms.m_OpenGLMatrix); + MT_Matrix4x4 view; + rasty->GetViewMatrix(view); + switch (mPreDefType) + { + case MODELMATRIX: + { + SetUniform(mPreDefLoc, model); + break; + } + case MODELMATRIX_TRANSPOSE: + { + SetUniform(mPreDefLoc, model, true); + break; + } + case MODELMATRIX_INVERSE: + { + model.invert(); + SetUniform(mPreDefLoc, model); + break; + } + case MODELMATRIX_INVERSETRANSPOSE: + { + model.invert(); + SetUniform(mPreDefLoc, model, true); + break; + } + case MODELVIEWMATRIX: + { + SetUniform(mPreDefLoc, view*model); + break; + } + + case MODELVIEWMATRIX_TRANSPOSE: + { + MT_Matrix4x4 mat(view*model); + SetUniform(mPreDefLoc, mat, true); + break; + } + case MODELVIEWMATRIX_INVERSE: + { + MT_Matrix4x4 mat(view*model); + mat.invert(); + SetUniform(mPreDefLoc, mat); + break; + } + case MODELVIEWMATRIX_INVERSETRANSPOSE: + { + MT_Matrix4x4 mat(view*model); + mat.invert(); + SetUniform(mPreDefLoc, mat, true); + break; + } + case CAM_POS: + { + MT_Point3 pos(rasty->GetCameraPosition()); + SetUniform(mPreDefLoc, pos); + break; + } + case VIEWMATRIX: + { + SetUniform(mPreDefLoc, view); + break; + } + case VIEWMATRIX_TRANSPOSE: + { + SetUniform(mPreDefLoc, view, true); + break; + } + case VIEWMATRIX_INVERSE: + { + view.invert(); + SetUniform(mPreDefLoc, view); + break; + } + case VIEWMATRIX_INVERSETRANSPOSE: + { + view.invert(); + SetUniform(mPreDefLoc, view, true); + break; + } + default: + break; + } + } +#endif +} + + +int BL_Shader::GetAttribLocation(const STR_String& name) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + return bgl::blGetAttribLocationARB(mShader, name.ReadPtr()); + } +#endif + return -1; +} + +void BL_Shader::BindAttribute(const STR_String& attr, int loc) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + bgl::blBindAttribLocationARB(mShader, loc, attr.ReadPtr()); + } +#endif +} + +int BL_Shader::GetUniformLocation(const STR_String& name) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + return bgl::blGetUniformLocationARB(mShader, name.ReadPtr()); + } +#endif + return -1; +} + +void BL_Shader::SetUniform(int uniform, const MT_Tuple2& vec) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + float value[2]; + vec.getValue(value); + bgl::blUniform2fvARB(uniform, 1, value); + } +#endif + +} + +void BL_Shader::SetUniform(int uniform, const MT_Tuple3& vec) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + float value[3]; + vec.getValue(value); + bgl::blUniform3fvARB(uniform, 1, value); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const MT_Tuple4& vec) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + float value[4]; + vec.getValue(value); + bgl::blUniform4fvARB(uniform, 1, value); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const unsigned int& val) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + bgl::blUniform1iARB(uniform, val); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const float& val) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + bgl::blUniform1fARB(uniform, val); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + float value[16]; + vec.getValue(value); + bgl::blUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose) +{ +#ifdef GL_ARB_shader_objects + if( RAS_EXT_support._ARB_fragment_shader && + RAS_EXT_support._ARB_vertex_shader && + RAS_EXT_support._ARB_shader_objects + ) + { + float value[9]; + value[0] = vec[0][0]; value[1] = vec[1][0]; value[2] = vec[2][0]; + value[3] = vec[0][1]; value[4] = vec[1][1]; value[5] = vec[2][1]; + value[6] = vec[0][2]; value[7] = vec[1][2]; value[7] = vec[2][2]; + bgl::blUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); + } +#endif } PyObject* BL_Shader::_getattr(const STR_String& attr) @@ -289,9 +563,11 @@ PyMethodDef BL_Shader::Methods[] = KX_PYMETHODTABLE( BL_Shader, setUniform2i ), KX_PYMETHODTABLE( BL_Shader, setUniform3i ), KX_PYMETHODTABLE( BL_Shader, setUniform4i ), + KX_PYMETHODTABLE( BL_Shader, setAttrib ), KX_PYMETHODTABLE( BL_Shader, setUniformfv ), KX_PYMETHODTABLE( BL_Shader, setUniformiv ), + KX_PYMETHODTABLE( BL_Shader, setUniformDef ), KX_PYMETHODTABLE( BL_Shader, setSampler ), KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ), @@ -332,7 +608,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg // already set... Py_Return; } - char *v,*f; int apply=0; if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) ) @@ -360,11 +635,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) { #ifdef GL_ARB_shader_objects bgl::blDeleteObjectARB(mShader); - bgl::blDeleteObjectARB(mFrag); - bgl::blDeleteObjectARB(mVert); mShader = 0; - mFrag = 0; - mVert = 0; vertProg = 0; fragProg = 0; mOk = 0; @@ -397,18 +668,26 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") Py_INCREF(Py_None); return Py_None; } - if(mShader==0) { PyErr_Format(PyExc_TypeError, "invalid shader object"); return NULL; } - GLint stat = 0; + int stat = 0; bgl::blValidateProgramARB(mShader); bgl::blGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat); - return PyInt_FromLong(0); -#else - Py_Return; + + if(stat > 0) { + int char_len=0; + STR_String str("",stat); + bgl::blGetInfoLogARB(mShader, stat, &char_len, str.Ptr()); + if(char_len >0) { + spit("---- GLSL Validation ----"); + spit(str.ReadPtr()); + } + str.Clear(); + } #endif//GL_ARB_shader_objects + Py_Return; } @@ -424,25 +703,22 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" ) int index=-1; if(PyArg_ParseTuple(args, "si", &uniform, &index)) { - if(mShader==0) - { + if(mShader==0) { PyErr_Format(PyExc_ValueError, "invalid shader object"); return NULL; } + int loc= bgl::blGetUniformLocationARB(mShader, uniform); - if( loc==-1 ) - { + if( loc==-1 ) { spit("Invalid uniform value: " << uniform << "."); Py_Return; - }else - { + } + + else { if(index <= MAXTEX) - { mSampler[index].loc = loc; - }else - { + else spit("Invalid texture sample index: " << index); - } Py_Return; } } @@ -990,3 +1266,63 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, Py_Return; #endif//GL_ARB_shader_objects } + +KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" ) +{ +#ifdef GL_ARB_shader_objects + if(mError) { + Py_INCREF(Py_None); + return Py_None; + } + int attr=0; + if(PyArg_ParseTuple(args, "i", &attr )) + { + if(mShader==0) + { + PyErr_Format(PyExc_ValueError, "invalid shader object"); + return NULL; + } + mAttr=SHD_TANGENT; + bgl::blUseProgramObjectARB(mShader); + bgl::blBindAttribLocationARB(mShader, mAttr, "Tangent"); + Py_Return; + } + return NULL; +#endif + Py_Return; +} + +KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" ) +{ +#ifdef GL_ARB_shader_objects + if(mError) { + Py_INCREF(Py_None); + return Py_None; + } + + char *uniform=""; + int nloc; + if(PyArg_ParseTuple(args, "si",&uniform, &nloc)) + { + if(mShader==0) { + PyErr_Format(PyExc_ValueError, "invalid shader object"); + return NULL; + } + int loc= bgl::blGetUniformLocationARB(mShader , uniform); + if( loc==-1 ) + { + spit("Invalid uniform value: " << uniform << "."); + Py_Return; + }else + { + mPreDefLoc = loc; + mPreDefType = nloc; + Py_Return; + } + } + return NULL; + +#endif +} + + diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 25db6a0b9f4..6536fdc8175 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -3,6 +3,13 @@ #include "PyObjectPlus.h" #include "BL_Material.h" +#include "BL_Texture.h" +// -- +#include "MT_Matrix4x4.h" +#include "MT_Matrix3x3.h" +#include "MT_Tuple2.h" +#include "MT_Tuple3.h" +#include "MT_Tuple4.h" // ----------------------------------- // user state management @@ -12,20 +19,26 @@ typedef struct uSampler int pass; int unit; int loc; - unsigned int glTexture; + BL_Texture* gl_texture; + int flag; }uSampler; #define SAMP_2D 1 #define SAMP_CUBE 2 +#define ATTRIBMAX 1 + +// uSampler::flag; +enum +{ + OWN=1 +}; // ---------------- class BL_Shader : public PyObjectPlus { Py_Header; private: - unsigned int mShader, - mVert, - mFrag; + unsigned int mShader; int mPass; bool mOk; bool mUse; @@ -33,14 +46,41 @@ private: char* vertProg; char* fragProg; bool mError; - char* mLog; + + int mAttr; + int mPreDefLoc; + int mPreDefType; + bool mDeleteTexture; bool LinkProgram(); - void PrintInfo( int len, unsigned int handle,int *num); public: BL_Shader(PyTypeObject *T=&Type); virtual ~BL_Shader(); + enum AttribTypes{ + SHD_TANGENT =1 + }; + + enum GenType { + MODELVIEWMATRIX, + MODELVIEWMATRIX_TRANSPOSE, + MODELVIEWMATRIX_INVERSE, + MODELVIEWMATRIX_INVERSETRANSPOSE, + + // Model matrix + MODELMATRIX, + MODELMATRIX_TRANSPOSE, + MODELMATRIX_INVERSE, + MODELMATRIX_INVERSETRANSPOSE, + + // View Matrix + VIEWMATRIX, + VIEWMATRIX_TRANSPOSE, + VIEWMATRIX_INVERSE, + VIEWMATRIX_INVERSETRANSPOSE, + CAM_POS + }; + char* GetVertPtr(); char* GetFragPtr(); void SetVertPtr( char *vert ); @@ -53,18 +93,28 @@ public: // --- // access const uSampler* getSampler(int i); - const bool Ok()const; + void SetSampler(int loc, int unit); + const bool Ok()const; unsigned int GetProg(); - unsigned int GetVertexShader(); - unsigned int GetFragmentShader(); - - void InitializeSampler( - int type, - int unit, - int pass, - unsigned int texture - ); + void SetProg(bool enable); + int GetAttribute(){return mAttr;}; + + void InitializeSampler( int type, int unit, int pass, BL_Texture* texture ); + + void Update( const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty ); + + // form tuhopuu2 + virtual int GetAttribLocation(const STR_String& name); + virtual void BindAttribute(const STR_String& attr, int loc); + virtual int GetUniformLocation(const STR_String& name); + virtual void SetUniform(int uniform, const MT_Tuple2& vec); + virtual void SetUniform(int uniform, const MT_Tuple3& vec); + virtual void SetUniform(int uniform, const MT_Tuple4& vec); + virtual void SetUniform(int uniform, const unsigned int& val); + virtual void SetUniform(int uniform, const float& val); + virtual void SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose=false); + virtual void SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose=false); // ----------------------------------- // python interface @@ -94,6 +144,10 @@ public: KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix4 ); KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix3 ); + KX_PYMETHOD_DOC( BL_Shader, setUniformDef ); + + KX_PYMETHOD_DOC( BL_Shader, setAttrib ); + // these come from within the material buttons // sampler2d/samplerCube work KX_PYMETHOD_DOC( BL_Shader, setSampler); diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 7cabb65a3ba..4ff31b885ba 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -23,19 +23,22 @@ #include "BKE_image.h" #include "BLI_blenlib.h" -#include "RAS_GLExtensionManager.h" +#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" +#include "RAS_OpenGLRasterizer/ARB_multitexture.h" +#include "RAS_ICanvas.h" +#include "RAS_Rect.h" + +#include "KX_GameObject.h" + using namespace bgl; #define spit(x) std::cout << x << std::endl; #include "MEM_guardedalloc.h" - - extern "C" { // envmaps #include "IMB_imbuf.h" - void my_envmap_split_ima(EnvMap *env); void my_free_envmapdata(EnvMap *env); } @@ -50,15 +53,14 @@ static int smaller_pow2(int num) { return num; } - - BL_Texture::BL_Texture() : mTexture(0), mError(0), mOk(0), mNeedsDeleted(0), mType(0), - mName("") + mName(""), + mUnit(0) { // -- } @@ -71,14 +73,14 @@ BL_Texture::~BL_Texture() void BL_Texture::DeleteTex() { if( mNeedsDeleted ) { - glDeleteTextures(1, (GLuint*)&(*mTexture)); + glDeleteTextures(1, (GLuint*)&mTexture); mNeedsDeleted = 0; mOk = 0; } } -bool BL_Texture::InitFromImage( Image *img, bool mipmap) +bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) { if(!img || img->ok==0 ) { mError = true; @@ -94,17 +96,20 @@ bool BL_Texture::InitFromImage( Image *img, bool mipmap) return mOk; } } - mTexture = &img->bindcode; + mTexture = img->bindcode; + mName = img->id.name; - mType = BL_TEX2D; - + mType = GL_TEXTURE_2D; + mUnit = unit; + // smoke em if we got em - if (*mTexture != 0) { - glBindTexture(GL_TEXTURE_2D, *mTexture ); + if (mTexture != 0) { + glBindTexture(GL_TEXTURE_2D, mTexture ); Validate(); return mOk; } - glGenTextures(1, (GLuint*)mTexture); + mNeedsDeleted = 1; + glGenTextures(1, (GLuint*)&mTexture); InitGLTex(img->ibuf->rect, img->ibuf->x, img->ibuf->y, mipmap); Validate(); return mOk; @@ -117,7 +122,7 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap) return; } - glBindTexture(GL_TEXTURE_2D, *mTexture ); + glBindTexture(GL_TEXTURE_2D, mTexture ); if( mipmap ) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -141,7 +146,7 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int)); gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels); - glBindTexture(GL_TEXTURE_2D, *mTexture ); + glBindTexture(GL_TEXTURE_2D, mTexture ); if( mipmap ) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); @@ -158,7 +163,7 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) } -bool BL_Texture::InitCubeMap( EnvMap *cubemap ) +bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap ) { #ifdef GL_ARB_texture_cube_map if(!RAS_EXT_support._ARB_texture_cube_map) { @@ -186,13 +191,14 @@ bool BL_Texture::InitCubeMap( EnvMap *cubemap ) EnvMap *CubeMap = cubemap; mNeedsDeleted = 1; - mBlankTexture = 0; - mType = BL_TEXCUBE; - mTexture = &mBlankTexture; + mType = GL_TEXTURE_CUBE_MAP_ARB; + mTexture = 0; mName = CubeMap->ima->id.name; + mUnit = unit; - glGenTextures(1, (GLuint*)(mTexture)); - glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *mTexture ); + + glGenTextures(1, (GLuint*)&mTexture); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture ); bool needs_split = false; if(!CubeMap->cube[0]) needs_split = true; @@ -202,72 +208,49 @@ bool BL_Texture::InitCubeMap( EnvMap *cubemap ) my_envmap_split_ima(CubeMap); } - int x = cubemap->ima->ibuf->x; - int y = cubemap->ima->ibuf->y; - unsigned int *data= (unsigned int *)malloc(x*y*sizeof(unsigned int)); + int x = CubeMap->ima->ibuf->x; + int y = CubeMap->ima->ibuf->y; // ----------------------------------- x = CubeMap->cube[0]->ibuf->x; y = CubeMap->cube[0]->ibuf->y; // check the first image, and assume the rest - if (!is_pow2(x) || !is_pow2(y)) - { + if (!is_pow2(x) || !is_pow2(y)) { spit("invalid envmap size please render with CubeRes @ power of two"); - free(data); - data = 0; + my_free_envmapdata(CubeMap); mError = true; mOk = false; return mOk; } - memcpy(data, CubeMap->cube[0]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - // ----------------------------------- - x = CubeMap->cube[1]->ibuf->x; - y = CubeMap->cube[1]->ibuf->y; - memcpy(data, CubeMap->cube[1]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - // ----------------------------------- - x = CubeMap->cube[2]->ibuf->x; - y = CubeMap->cube[2]->ibuf->y; - memcpy(data, CubeMap->cube[2]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - // ----------------------------------- - x = CubeMap->cube[3]->ibuf->x; - y = CubeMap->cube[3]->ibuf->y; - memcpy(data, CubeMap->cube[3]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - // ----------------------------------- - x = CubeMap->cube[4]->ibuf->x; - y = CubeMap->cube[4]->ibuf->y; - memcpy(data, CubeMap->cube[4]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - // ----------------------------------- - x = CubeMap->cube[5]->ibuf->x; - y = CubeMap->cube[5]->ibuf->y; - memcpy(data, CubeMap->cube[5]->ibuf->rect, (x*y*sizeof(unsigned int))); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + /* + */ + +#define SetCubeMapFace(face, num) \ + glTexImage2D(face, 0,GL_RGBA, \ + CubeMap->cube[num]->ibuf->x, \ + CubeMap->cube[num]->ibuf->y, \ + 0, GL_RGBA, GL_UNSIGNED_BYTE, \ + CubeMap->cube[num]->ibuf->rect) + + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 5); + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 3); + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0); + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 1); + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 2); + SetCubeMapFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 4); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT ); - - if(data) { - free(data); - data = 0; - } + if(needs_split) { - // okay we allocated, swap back to orig and free used cubemap->ima = CubeMap->ima; my_free_envmapdata(CubeMap); } + mOk = IsValid(); return mOk; @@ -289,7 +272,7 @@ STR_String BL_Texture::GetName() const bool BL_Texture::IsValid() { - return (mTexture && *mTexture!= 0)?glIsTexture(*mTexture)!=0:false; + return (mTexture!= 0)?glIsTexture(mTexture)!=0:false; } @@ -301,7 +284,7 @@ void BL_Texture::Validate() bool BL_Texture::Ok() { - return ( mTexture?((!mError || mOk ) && *mTexture!= 0):0 ); + return (mTexture!= 0); } @@ -310,15 +293,282 @@ unsigned int BL_Texture::GetTextureType() const return mType; } +int BL_Texture::GetMaxUnits() +{ + GLint unit=0; +#ifdef GL_ARB_multitexture + if(RAS_EXT_support._ARB_multitexture) { + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit); + return (MAXTEX>=unit?unit:MAXTEX); + } +#endif + return 0; +} + +void BL_Texture::ActivateFirst() +{ +#ifdef GL_ARB_multitexture + if(RAS_EXT_support._ARB_multitexture) + bgl::blActiveTextureARB(GL_TEXTURE0_ARB); +#endif +} + +void BL_Texture::ActivateUnit(int unit) +{ +#ifdef GL_ARB_multitexture + if(RAS_EXT_support._ARB_multitexture) { + if(unit <= MAXTEX) + bgl::blActiveTextureARB(GL_TEXTURE0_ARB+unit); + } +#endif +} + -BL_Texture::operator const unsigned int () const +void BL_Texture::DisableUnit() { - return mTexture? *mTexture:0; +#ifdef GL_ARB_multitexture + if(RAS_EXT_support._ARB_multitexture) + bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit); +#endif + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + +#ifdef GL_ARB_texture_cube_map + if(RAS_EXT_support._ARB_texture_cube_map) + glDisable(GL_TEXTURE_CUBE_MAP_ARB); +#endif + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + glDisable(GL_TEXTURE_GEN_Q); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } -bool BL_Texture::SetGLTex(unsigned int tex) + +void BL_Texture::DisableAllTextures() { - return false; +#ifdef GL_ARB_multitexture + glDisable(GL_BLEND); + for(int i=0; iflag[mUnit] &TEXALPHA ) { + combiner = GL_COMBINE_ALPHA_ARB; + source0 = GL_SOURCE0_ALPHA_ARB; + source1 = GL_SOURCE1_ALPHA_ARB; + source2 = GL_SOURCE2_ALPHA_ARB; + op0 = GL_OPERAND0_ALPHA_ARB; + op1 = GL_OPERAND1_ALPHA_ARB; + op2 = GL_OPERAND2_ALPHA_ARB; + blend_operand = GL_SRC_ALPHA; + blend_operand_prev = GL_SRC_ALPHA; + // invert + if(mat->flag[mUnit] &TEXNEG) { + blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA; + blend_operand = GL_ONE_MINUS_SRC_ALPHA; + } + } + else { + if(mat->flag[mUnit] &TEXNEG) { + blend_operand_prev=GL_ONE_MINUS_SRC_COLOR; + blend_operand = GL_ONE_MINUS_SRC_COLOR; + } + } + bool using_alpha = false; + + if(mat->flag[mUnit] &USEALPHA){ + alphaOp = GL_ONE_MINUS_SRC_ALPHA; + using_alpha=true; + } + else if(mat->flag[mUnit] &USENEGALPHA){ + alphaOp = GL_SRC_ALPHA; + using_alpha = true; + } + + switch( mat->blend_mode[mUnit] ) { + case BLEND_MIX: + { + // ------------------------------ + if(!using_alpha) { + GLfloat base_col[4]; + base_col[0] = base_col[1] = base_col[2] = 0.f; + base_col[3] = 1.f-mat->color_blend[mUnit]; + glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col ); + } + glTexEnvf( GL_TEXTURE_ENV, combiner, GL_INTERPOLATE_ARB); + glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB); + glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); + glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); + glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); + if(!using_alpha) + glTexEnvf( GL_TEXTURE_ENV, source2, GL_CONSTANT_ARB ); + else + glTexEnvf( GL_TEXTURE_ENV, source2, GL_TEXTURE ); + + glTexEnvf( GL_TEXTURE_ENV, op2, alphaOp); + }break; + case BLEND_MUL: + { + // ------------------------------ + glTexEnvf( GL_TEXTURE_ENV, combiner, GL_MODULATE); + glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB); + glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev); + glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); + if(using_alpha) + glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); + else + glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); + }break; + case BLEND_ADD: + { + // ------------------------------ + glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD_SIGNED_ARB); + glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); + glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); + glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); + if(using_alpha) + glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); + else + glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); + }break; + case BLEND_SUB: + { + // ------------------------------ + glTexEnvf( GL_TEXTURE_ENV, combiner, GL_SUBTRACT_ARB); + glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); + glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); + glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); + glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); + }break; + case BLEND_SCR: + { + // ------------------------------ + glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD); + glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); + glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); + glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); + if(using_alpha) + glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); + else + glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); + } break; + } + glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0); +#endif //!GL_ARB_texture_env_combine +} + +int BL_Texture::GetPow2(int n) +{ + if(!is_pow2(n)) + n = smaller_pow2(n); + + return n; } extern "C" { @@ -384,7 +634,5 @@ void my_free_envmapdata(EnvMap *env) } -} - -unsigned int BL_Texture::mBlankTexture = 0; +} // extern C diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index 51bf7270d2d..2df14580e65 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -1,9 +1,20 @@ #ifndef __BL_TEXTURE_H__ #define __BL_TEXTURE_H__ + #include +#include + +#include "MT_Matrix4x4.h" +#include "KX_Camera.h" + // -- struct Image; struct EnvMap; +class BL_Material; +class RTData; +class RAS_Rect; +class RAS_ICanvas; + // -- #include "STR_String.h" @@ -11,14 +22,13 @@ class BL_Texture { private: // ----------------------------------- - unsigned int* mTexture; + unsigned int mTexture; bool mError; bool mOk; bool mNeedsDeleted; unsigned int mType; STR_String mName; - static unsigned int mBlankTexture; - std::vectormCubeMem; + int mUnit; // ----------------------------------- void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap ); void InitGLTex(unsigned int *p,int x,int y,bool mipmap ); @@ -27,27 +37,45 @@ public: BL_Texture(); ~BL_Texture( ); - operator const unsigned int () const; + //operator const unsigned int () const; bool Ok(); + int GetUnit() {return mUnit;} + void SetUnit(int unit) {mUnit = unit;} STR_String GetName() const; unsigned int GetTextureType() const; - void DeleteTex(); - bool InitFromImage( Image *img, bool mipmap); - bool InitCubeMap( EnvMap *cubemap ); - // - bool SetGLTex(unsigned int tex); - - void PopCubeMap(); - bool IsValid(); - void Validate(); -}; + void DeleteTex(); -enum TexType{ - BL_TEX2D = 1, - BL_TEXCUBE = 2 + bool InitFromImage(int unit, Image *img, bool mipmap); + bool InitCubeMap(int unit,EnvMap *cubemap ); + + bool IsValid(); + void Validate(); + + static void ActivateFirst(); + static void DisableAllTextures(); + static void ActivateUnit(int unit); + static int GetMaxUnits(); + static int GetPow2(int x); + + /** todo + void CreateRenderTexture(RAS_Rect r, RTData d); + void ReadDepth(RAS_Rect r, RTData d); + static void BeginDepth(RAS_ICanvas *can, RTData d); + static void EndDepth(RAS_ICanvas *can,RTData d); + void SetDepthMapping(MT_Matrix4x4& p, MT_Matrix4x4& m); + */ + + void ActivateTexture(); + void SetMapping(int mode); + void DisableUnit(); + void setTexEnv(BL_Material *mat, bool modulate=false); }; +/* Render to texture support, managed by the scene + TODO +*/ + #endif//__BL_TEXTURE_H__ diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index b530edbd17c..d416ef55613 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -91,13 +91,11 @@ KX_BlenderMaterial::KX_BlenderMaterial( m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0; // figure max - #ifdef GL_ARB_multitexture int enabled = mMaterial->num_enabled; - mMaterial->num_enabled = enabled>=bgl::max_texture_units?bgl::max_texture_units:enabled; - #else - mMaterial->num_enabled=0; - #endif + int max = BL_Texture::GetMaxUnits(); + mMaterial->num_enabled = enabled>=max?max:enabled; + // base class m_enabled = mMaterial->num_enabled; // test the sum of the various modes for equality @@ -114,7 +112,6 @@ KX_BlenderMaterial::KX_BlenderMaterial( } - KX_BlenderMaterial::~KX_BlenderMaterial() { // cleanup work @@ -132,204 +129,100 @@ TFace* KX_BlenderMaterial::GetTFace(void) const void KX_BlenderMaterial::OnConstruction() { // for each unique material... - #ifdef GL_ARB_multitexture -/* will be used to switch textures - if(!gTextureDict) - gTextureDict = PyDict_New(); -*/ int i; for(i=0; inum_enabled; i++) { - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); - #ifdef GL_ARB_texture_cube_map + BL_Texture::ActivateUnit(i); if( mMaterial->mapping[i].mapping & USEENV ) { if(!RAS_EXT_support._ARB_texture_cube_map) { spit("CubeMap textures not supported"); continue; } - if(!mTextures[i].InitCubeMap( mMaterial->cubemap[i] ) ) + if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) spit("unable to initialize image("<matname<< ", image will not be available"); } else { - #endif//GL_ARB_texture_cube_map if( mMaterial->img[i] ) { - if( ! mTextures[i].InitFromImage(mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) + if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) spit("unable to initialize image("<matname<< ", image will not be available"); } - #ifdef GL_ARB_texture_cube_map } - #endif//GL_ARB_texture_cube_map - /*PyDict_SetItemString(gTextureDict, mTextures[i].GetName().Ptr(), PyInt_FromLong(mTextures[i]));*/ } - #endif//GL_ARB_multitexture - mBlendFunc[0] =0; mBlendFunc[1] =0; } void KX_BlenderMaterial::OnExit() { - #ifdef GL_ARB_multitexture - - #ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_shader_objects && mShader ) { + if( mShader ) { //note, the shader here is allocated, per unique material //and this function is called per face - bgl::blUseProgramObjectARB(0); + mShader->SetProg(0); delete mShader; mShader = 0; } - #endif //GL_ARB_shader_objects + BL_Texture::ActivateFirst(); for(int i=0; inum_enabled; i++) { - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); - + BL_Texture::ActivateUnit(i); mTextures[i].DeleteTex(); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - - #ifdef GL_ARB_texture_cube_map - if(RAS_EXT_support._ARB_texture_cube_map) - glDisable(GL_TEXTURE_CUBE_MAP_ARB); - #endif//GL_ARB_texture_cube_map - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + mTextures[i].DisableUnit(); } - - /*if (gTextureDict) { - PyDict_Clear(gTextureDict); - Py_DECREF(gTextureDict); - gTextureDict = 0; - }*/ - - bgl::blActiveTextureARB(GL_TEXTURE0_ARB); - - #ifdef GL_ARB_texture_cube_map - if(RAS_EXT_support._ARB_texture_cube_map) - glDisable(GL_TEXTURE_CUBE_MAP_ARB); - #endif//GL_ARB_texture_cube_map - - glDisable(GL_TEXTURE_2D); - #endif//GL_ARB_multitexture - - // make sure multi texture units - // revert back to blender... - // -- if( mMaterial->tface ) set_tpage(mMaterial->tface); } -void KX_BlenderMaterial::DisableTexData() +void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) { - glDisable(GL_BLEND); - #ifdef GL_ARB_multitexture - int i=(MAXTEX>=bgl::max_texture_units?bgl::max_texture_units:MAXTEX)-1; - for(; i>=0; i--) { - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - - #ifdef GL_ARB_texture_cube_map - if(RAS_EXT_support._ARB_texture_cube_map) - glDisable(GL_TEXTURE_CUBE_MAP_ARB); - #endif//GL_ARB_texture_cube_map - - glDisable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - } - #endif//GL_ARB_multitexture -} - - -void KX_BlenderMaterial::setShaderData( bool enable ) -{ - #ifdef GL_ARB_multitexture - #ifdef GL_ARB_shader_objects - MT_assert(RAS_EXT_support._ARB_shader_objects && mShader); int i; if( !enable || !mShader->Ok() ) { // frame cleanup. - bgl::blUseProgramObjectARB( 0 ); - DisableTexData(); + mShader->SetProg(false); + BL_Texture::DisableAllTextures(); return; } - DisableTexData(); - bgl::blUseProgramObjectARB( mShader->GetProg() ); + BL_Texture::DisableAllTextures(); + mShader->SetProg(true); + BL_Texture::ActivateFirst(); + // for each enabled unit for(i=0; inum_enabled; i++) { - const uSampler *samp = mShader->getSampler(i); - if( samp->loc == -1 || samp->glTexture == 0 ) continue; - - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); - - #ifdef GL_ARB_texture_cube_map - if( mMaterial->mapping[i].mapping &USEENV ) { - glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, samp->glTexture /* mTextures[i]*/ ); - glEnable( GL_TEXTURE_CUBE_MAP_ARB ); - } - else { - #endif//GL_ARB_texture_cube_map - glBindTexture( GL_TEXTURE_2D, samp->glTexture /*mTextures[i]*/ ); - glEnable( GL_TEXTURE_2D ); - #ifdef GL_ARB_texture_cube_map - } - #endif//GL_ARB_texture_cube_map - // use a sampler - bgl::blUniform1iARB(samp->loc, i ); + BL_Texture *tex = samp->gl_texture; + if( samp->loc == -1 || !tex || !tex->Ok() ) + continue; + tex->ActivateTexture(); + mShader->SetSampler(samp->loc, i); } - if(!mUserDefBlend) { setDefaultBlending(); }else { - glEnable(GL_BLEND); // tested to be valid enums + glEnable(GL_BLEND); glBlendFunc(mBlendFunc[0], mBlendFunc[1]); } - - #endif//GL_ARB_shader_objects - #endif//GL_ARB_multitexture } -void KX_BlenderMaterial::setTexData( bool enable ) +void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) { - #ifdef GL_ARB_multitexture - int i; - - #ifdef GL_ARB_shader_objects - if(RAS_EXT_support._ARB_shader_objects) { - // switch back to fixed func - bgl::blUseProgramObjectARB( 0 ); - } - #endif//GL_ARB_shader_objects + if(RAS_EXT_support._ARB_shader_objects && mShader) + mShader->SetProg(false); - if( !enable ) { - // frame cleanup. - DisableTexData(); + BL_Texture::DisableAllTextures(); + if( !enable ) return; - } - - DisableTexData(); + + BL_Texture::ActivateFirst(); if( mMaterial->IdMode == DEFAULT_BLENDER ) { setDefaultBlending(); @@ -337,71 +230,40 @@ void KX_BlenderMaterial::setTexData( bool enable ) } if( mMaterial->IdMode == TEXFACE ) { - // no material connected to the object - if( mTextures[0] ) { - if( !mTextures[0].Ok() ) return; - bgl::blActiveTextureARB(GL_TEXTURE0_ARB); - glBindTexture( GL_TEXTURE_2D, mTextures[0] ); - glEnable(GL_TEXTURE_2D); - setTextureEnvironment( -1 ); // modulate - setEnvMap( (mMaterial->mapping[0].mapping &USEREFL)!=0 ); + if( mTextures[0].Ok() ) { + mTextures[0].ActivateTexture(); + mTextures[0].setTexEnv(0, true); + mTextures[0].SetMapping(mMaterial->mapping[0].mapping); setDefaultBlending(); } return; } - // for each enabled unit + int mode = 0,i=0; for(i=0; (inum_enabled); i++) { if( !mTextures[i].Ok() ) continue; - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); - - #ifdef GL_ARB_texture_cube_map - // use environment maps - if( mMaterial->mapping[i].mapping &USEENV && RAS_EXT_support._ARB_texture_cube_map ) { - glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTextures[i] ); - glEnable(GL_TEXTURE_CUBE_MAP_ARB); - setTextureEnvironment( i ); - - if( mMaterial->mapping[i].mapping &USEREFL ) - setEnvMap( true, true ); - else if(mMaterial->mapping[i].mapping &USEOBJ) - setObjectMatrixData(i); - else - setTexMatrixData( i ); - } - // 2d textures - else { - #endif//GL_ARB_texture_cube_map - glBindTexture( GL_TEXTURE_2D, mTextures[i] ); - glEnable( GL_TEXTURE_2D ); - setTextureEnvironment( i ); - - if( mMaterial->mapping[i].mapping &USEREFL ){ - setEnvMap( true ); - } - else if(mMaterial->mapping[i].mapping &USEOBJ){ - setObjectMatrixData(i); - } - else { - setTexMatrixData( i ); - } + mTextures[i].ActivateTexture(); + mTextures[i].setTexEnv(mMaterial); + mode = mMaterial->mapping[i].mapping; - #ifdef GL_ARB_texture_cube_map - } - #endif//GL_ARB_texture_cube_map + if(mode &USEOBJ) + setObjectMatrixData(i, ras); + else + mTextures[i].SetMapping(mode); + + if(!(mode &USEOBJ)) + setTexMatrixData( i ); } + if(!mUserDefBlend) { setDefaultBlending(); - }else - { + } + else { glEnable(GL_BLEND); - // tested to be valid enums glBlendFunc(mBlendFunc[0], mBlendFunc[1]); } - - #endif//GL_ARB_multitexture } void @@ -409,20 +271,25 @@ KX_BlenderMaterial::ActivatShaders( RAS_IRasterizer* rasty, TCachingInfo& cachingInfo)const { + KX_BlenderMaterial *tmp = const_cast(this); + + // reset... + if(tmp->mMaterial->IsShared()) + cachingInfo =0; + if (GetCachingInfo() != cachingInfo) { - KX_BlenderMaterial *tmp = const_cast(this); if (!cachingInfo) - tmp->setShaderData( false ); + tmp->setShaderData( false, rasty); cachingInfo = GetCachingInfo(); if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) { - tmp->setShaderData( true ); + tmp->setShaderData( true, rasty); rasty->EnableTextures(true); } else { - tmp->setShaderData( false ); + tmp->setShaderData( false, rasty); rasty->EnableTextures(false); } @@ -463,12 +330,13 @@ KX_BlenderMaterial::ActivatShaders( 1.0 ); - // Lagan's patch... - // added material factor rasty->SetAmbient(mMaterial->amb); if (mMaterial->material) rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); + + tmp->applyTexGen(rasty); + } void @@ -477,20 +345,19 @@ KX_BlenderMaterial::ActivateMat( TCachingInfo& cachingInfo )const { + KX_BlenderMaterial *tmp = const_cast(this); if (GetCachingInfo() != cachingInfo) { - KX_BlenderMaterial *tmp = const_cast(this); - if (!cachingInfo) - tmp->setTexData( false ); + tmp->setTexData( false,rasty ); cachingInfo = GetCachingInfo(); if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { - tmp->setTexData( true ); + tmp->setTexData( true,rasty ); rasty->EnableTextures(true); } else{ - tmp->setTexData( false ); + tmp->setTexData( false,rasty); rasty->EnableTextures(false); } @@ -526,15 +393,14 @@ KX_BlenderMaterial::ActivateMat( mMaterial->matcolor[2]*mMaterial->emit, 1.0 ); - - // Lagan's patch... - // added material factor rasty->SetAmbient(mMaterial->amb); - if (mMaterial->material) rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); + + tmp->applyTexGen(rasty); } + bool KX_BlenderMaterial::Activate( RAS_IRasterizer* rasty, @@ -542,24 +408,20 @@ KX_BlenderMaterial::Activate( )const { bool dopass = false; - #ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_shader_objects && - ( mShader && mShader->Ok() ) ) { - + if( RAS_EXT_support._ARB_shader_objects && ( mShader && mShader->Ok() ) ) { if( (mPass++) < mShader->getNumPass() ) { ActivatShaders(rasty, cachingInfo); dopass = true; return dopass; } else { - bgl::blUseProgramObjectARB( 0 ); + mShader->SetProg(false); mPass = 0; dopass = false; return dopass; } } else { - #endif//GL_ARB_shader_objects switch (mPass++) { case 0: @@ -571,143 +433,17 @@ KX_BlenderMaterial::Activate( dopass = false; break; } - #ifdef GL_ARB_shader_objects } - #endif//GL_ARB_shader_objects return dopass; } -void KX_BlenderMaterial::setTextureEnvironment( int textureIndex ) +void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const { -#ifndef GL_ARB_texture_env_combine - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - return; -#else - if(textureIndex == -1 || !RAS_EXT_support._ARB_texture_env_combine){ - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - return; - } - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); - - GLfloat blend_operand = GL_SRC_COLOR; - GLfloat blend_operand_prev = GL_SRC_COLOR; - - GLenum combiner = GL_COMBINE_RGB_ARB; - GLenum source0 = GL_SOURCE0_RGB_ARB; - GLenum source1 = GL_SOURCE1_RGB_ARB; - GLenum source2 = GL_SOURCE2_RGB_ARB; - GLenum op0 = GL_OPERAND0_RGB_ARB; - GLenum op1 = GL_OPERAND1_RGB_ARB; - GLenum op2 = GL_OPERAND2_RGB_ARB; - GLfloat alphaOp = GL_SRC_ALPHA; - - // switch to alpha combiners - if( (mMaterial->flag[textureIndex] &TEXALPHA) ) { - combiner = GL_COMBINE_ALPHA_ARB; - source0 = GL_SOURCE0_ALPHA_ARB; - source1 = GL_SOURCE1_ALPHA_ARB; - source2 = GL_SOURCE2_ALPHA_ARB; - op0 = GL_OPERAND0_ALPHA_ARB; - op1 = GL_OPERAND1_ALPHA_ARB; - op2 = GL_OPERAND2_ALPHA_ARB; - blend_operand = GL_SRC_ALPHA; - - // invert - if(mMaterial->flag[textureIndex] &TEXNEG) { - blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA; - blend_operand = GL_ONE_MINUS_SRC_ALPHA; - } - } - else { - if(mMaterial->flag[textureIndex] &TEXNEG) { - blend_operand_prev=GL_ONE_MINUS_SRC_COLOR; - blend_operand = GL_ONE_MINUS_SRC_COLOR; - } - } - bool using_alpha = false; - - if(mMaterial->flag[textureIndex] &USEALPHA){ - alphaOp = GL_ONE_MINUS_SRC_ALPHA; - using_alpha=true; - } - else if(mMaterial->flag[textureIndex] &USENEGALPHA){ - alphaOp = GL_SRC_ALPHA; - using_alpha = true; - } - - switch( mMaterial->blend_mode[textureIndex] ) { - case BLEND_MIX: - { - // ------------------------------ - if(!using_alpha) { - GLfloat base_col[4]; - base_col[0] = base_col[1] = base_col[2] = 0.f; - base_col[3] = 1.f-mMaterial->color_blend[textureIndex]; - glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col ); - } - glTexEnvf( GL_TEXTURE_ENV, combiner, GL_INTERPOLATE_ARB); - glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB); - glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); - glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); - glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); - if(!using_alpha) - glTexEnvf( GL_TEXTURE_ENV, source2, GL_CONSTANT_ARB ); - else - glTexEnvf( GL_TEXTURE_ENV, source2, GL_TEXTURE ); - - glTexEnvf( GL_TEXTURE_ENV, op2, alphaOp); - }break; - case BLEND_MUL: - { - // ------------------------------ - glTexEnvf( GL_TEXTURE_ENV, combiner, GL_MODULATE); - glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB); - glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev); - glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); - if(using_alpha) - glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); - else - glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); - }break; - case BLEND_ADD: - { - // ------------------------------ - glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD_SIGNED_ARB); - glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); - glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); - glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); - if(using_alpha) - glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); - else - glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); - }break; - case BLEND_SUB: - { - // ------------------------------ - glTexEnvf( GL_TEXTURE_ENV, combiner, GL_SUBTRACT_ARB); - glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); - glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); - glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); - glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); - }break; - case BLEND_SCR: - { - // ------------------------------ - glTexEnvf( GL_TEXTURE_ENV, combiner, GL_ADD); - glTexEnvf( GL_TEXTURE_ENV, source0, GL_PREVIOUS_ARB ); - glTexEnvf( GL_TEXTURE_ENV, op0, blend_operand_prev ); - glTexEnvf( GL_TEXTURE_ENV, source1, GL_TEXTURE ); - if(using_alpha) - glTexEnvf( GL_TEXTURE_ENV, op1, alphaOp); - else - glTexEnvf( GL_TEXTURE_ENV, op1, blend_operand); - } break; - } - glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0); -#endif //!GL_ARB_texture_env_combine + if(mShader && RAS_EXT_support._ARB_shader_objects) + mShader->Update(ms, rasty); } + bool KX_BlenderMaterial::setDefaultBlending() { if( mMaterial->transp &TF_ADD) { @@ -726,40 +462,6 @@ bool KX_BlenderMaterial::setDefaultBlending() return false; } -void KX_BlenderMaterial::setEnvMap(bool val, bool cube) -{ - #ifdef GL_ARB_texture_cube_map - if( cube && RAS_EXT_support._ARB_texture_cube_map ) - { - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB ); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - } - else { - #endif//GL_ARB_texture_cube_map - if( val ) { - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - } - else { - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_R); - } - #ifdef GL_ARB_texture_cube_map - } - #endif//GL_ARB_texture_cube_map -} - - void KX_BlenderMaterial::setTexMatrixData(int i) { glMatrixMode(GL_TEXTURE); @@ -791,17 +493,13 @@ static void GetProjPlane(BL_Material *mat, int index,int num, float*param) param[2] = 1.f; } - -void KX_BlenderMaterial::setObjectMatrixData(int i) +void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) { - // will work without cubemaps - // but a cubemap will look the best KX_GameObject *obj = (KX_GameObject*) mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame); - if(!obj) - return; + if(!obj) return; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); @@ -824,9 +522,8 @@ void KX_BlenderMaterial::setObjectMatrixData(int i) glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); - float matr[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matr); - MT_Matrix4x4 mvmat(matr); + MT_Matrix4x4 mvmat; + ras->GetViewMatrix(mvmat); glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -846,6 +543,28 @@ void KX_BlenderMaterial::setObjectMatrixData(int i) } +void KX_BlenderMaterial::applyTexGen(RAS_IRasterizer *ras) +{ + if(mShader && RAS_EXT_support._ARB_shader_objects) + if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT); + + for(int i=0; inum_enabled; i++) { + int mode = mMaterial->mapping[i].mapping; + + if( mode &(USEREFL|USEOBJ)) + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_GEN, i); + else if(mode &USEORCO) + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_ORCO, i); + else if(mode &USENORM) + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_NORM, i); + else if(mode &USEUV) + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_UV1, i); + else + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + } +} + // ------------------------------------ void KX_BlenderMaterial::UpdateIPO( @@ -877,9 +596,6 @@ PyMethodDef KX_BlenderMaterial::Methods[] = KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ), KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ), KX_PYMETHODTABLE( KX_BlenderMaterial, setBlending ), -// KX_PYMETHODTABLE( KX_BlenderMaterial, getTexture ), -// KX_PYMETHODTABLE( KX_BlenderMaterial, setTexture ), - {NULL,NULL} //Sentinel }; @@ -956,14 +672,15 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") mShader = new BL_Shader(); for(int i= 0; inum_enabled; i++) { if(mMaterial->mapping[i].mapping & USEENV ) - mShader->InitializeSampler(SAMP_CUBE, i, 0, mTextures[i]); + mShader->InitializeSampler(SAMP_CUBE, i, 0, &mTextures[i]); else - mShader->InitializeSampler(SAMP_2D, i, 0, mTextures[i]); + mShader->InitializeSampler(SAMP_2D, i, 0, &mTextures[i]); } mModified = true; } if(mShader && !mShader->GetError()) { + mMaterial->SetSharedMaterial(true); Py_INCREF(mShader); return mShader; }else @@ -992,6 +709,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") #endif//GL_ARB_shader_objects } + KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") { return PyInt_FromLong( mMaterial->material_index ); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index a250dcf81c4..ad229509224 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -23,7 +23,7 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial public: // -------------------------------- KX_BlenderMaterial( - class KX_Scene* scene, // light/obj list + class KX_Scene* scene, BL_Material* mat, bool skin, int lightlayer, @@ -34,25 +34,32 @@ public: virtual ~KX_BlenderMaterial(); // -------------------------------- - virtual TCachingInfo GetCachingInfo(void) const - { - // -- + virtual TCachingInfo GetCachingInfo(void) const { return (void*) this; } - // -------------------------------- - virtual bool Activate( + virtual + bool Activate( RAS_IRasterizer* rasty, - TCachingInfo& cachingInfo) const; + TCachingInfo& cachingInfo + ) const; + + virtual + void ActivateMeshSlot( + const KX_MeshSlot & ms, + RAS_IRasterizer* rasty + ) const; void ActivateMat( - RAS_IRasterizer* rasty, - TCachingInfo& cachingInfo)const; - + RAS_IRasterizer* rasty, + TCachingInfo& cachingInfo + )const; + void ActivatShaders( RAS_IRasterizer* rasty, - TCachingInfo& cachingInfo)const; - // -------------------------------- + TCachingInfo& cachingInfo + )const; + TFace* GetTFace(void) const; @@ -73,36 +80,34 @@ public: KX_PYMETHOD_DOC( KX_BlenderMaterial, setTexture ); KX_PYMETHOD_DOC( KX_BlenderMaterial, setBlending ); + // -------------------------------- // pre calculate to avoid pops/lag at startup virtual void OnConstruction( ); - private: BL_Material* mMaterial; BL_Shader* mShader; KX_Scene* mScene; BL_Texture mTextures[MAXTEX]; // texture array - bool mUserDefBlend; unsigned int mBlendFunc[2]; bool mModified; + // message centers - void setTexData( bool enable ); - void setShaderData( bool enable ); + void setTexData( bool enable,RAS_IRasterizer *ras); + void setShaderData( bool enable, RAS_IRasterizer *ras); - void setTextureEnvironment( int textureIndex ); - void setEnvMap( bool val, bool cube=false); - void setTexMatrixData(int i); bool setDefaultBlending(); - void setObjectMatrixData(int i); + void setObjectMatrixData(int i, RAS_IRasterizer *ras); + void setTexMatrixData(int i); + + void setLightData(); + void applyTexGen(RAS_IRasterizer *ras); // cleanup stuff - void DisableTexData(); void OnExit(); - //void DisableNonEnabled(); - // -- mutable int mPass; }; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 42e5d550e57..85fdc51826a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -449,6 +449,7 @@ KX_GameObject::MarkVisible( } } + void KX_GameObject::addLinearVelocity(const MT_Vector3& lin_vel,bool local) { if (m_pPhysicsController1) @@ -1129,7 +1130,6 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo, return NULL; } - /* --------------------------------------------------------------------- * Some stuff taken from the header * --------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 98544cf14d0..0b65109cb8d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -526,7 +526,6 @@ public: void ); - /** * Was this object marked visible? (only for the ewxplicit * visibility system). @@ -609,7 +608,6 @@ public: KX_PYMETHOD(KX_GameObject,GetParent); KX_PYMETHOD(KX_GameObject,GetPhysicsId); KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo); - private : /** diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 6f7b73ee4fa..ceb5da67877 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -73,6 +73,7 @@ #include "SND_DeviceManager.h" #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" +#include "BL_Shader.h" #include "KX_PyMath.h" @@ -756,6 +757,23 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook KX_MACRO_addTypesToDict(d, BL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); KX_MACRO_addTypesToDict(d, BL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE); + + /* 9. UniformTypes */ + KX_MACRO_addTypesToDict(d, SHD_TANGENT, BL_Shader::SHD_TANGENT); + KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX, BL_Shader::MODELVIEWMATRIX); + KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_TRANSPOSE, BL_Shader::MODELVIEWMATRIX_TRANSPOSE); + KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSE, BL_Shader::MODELVIEWMATRIX_INVERSE); + KX_MACRO_addTypesToDict(d, MODELVIEWMATRIX_INVERSETRANSPOSE, BL_Shader::MODELVIEWMATRIX_INVERSETRANSPOSE); + KX_MACRO_addTypesToDict(d, MODELMATRIX, BL_Shader::MODELMATRIX); + KX_MACRO_addTypesToDict(d, MODELMATRIX_TRANSPOSE, BL_Shader::MODELMATRIX_TRANSPOSE); + KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSE, BL_Shader::MODELMATRIX_INVERSE); + KX_MACRO_addTypesToDict(d, MODELMATRIX_INVERSETRANSPOSE, BL_Shader::MODELMATRIX_INVERSETRANSPOSE); + KX_MACRO_addTypesToDict(d, VIEWMATRIX, BL_Shader::VIEWMATRIX); + KX_MACRO_addTypesToDict(d, VIEWMATRIX_TRANSPOSE, BL_Shader::VIEWMATRIX_TRANSPOSE); + KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSE, BL_Shader::VIEWMATRIX_INVERSE); + KX_MACRO_addTypesToDict(d, VIEWMATRIX_INVERSETRANSPOSE, BL_Shader::VIEWMATRIX_INVERSETRANSPOSE); + KX_MACRO_addTypesToDict(d, CAM_POS, BL_Shader::CAM_POS); + // Check for errors if (PyErr_Occurred()) { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 3e296c2b88b..6eef1647167 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -130,6 +130,7 @@ public: { return false; } + virtual void ActivateMeshSlot(const class KX_MeshSlot & ms, RAS_IRasterizer* rasty) const {} virtual bool Equals(const RAS_IPolyMaterial& lhs) const; bool Less(const RAS_IPolyMaterial& rhs) const; @@ -148,7 +149,6 @@ public: * PreCalculate texture gen */ virtual void OnConstruction(){} - }; inline bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial & lhs) diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 68a9429d066..7f44afec74e 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -98,6 +98,25 @@ public: RAS_STEREO_MAXSTEREO }; + + /** + * Texture gen modes. + */ + enum TexCoGen { + RAS_TEXCO_GEN, //< GPU will generate texture coordinates + RAS_TEXCO_ORCO, //< Vertex coordinates (object space) + RAS_TEXCO_GLOB, //< Vertex coordinates (world space) + RAS_TEXCO_UV1, //< UV coordinates + RAS_TEXCO_OBJECT, //< Use another object's position as coordinates + RAS_TEXCO_LAVECTOR, //< Light vector as coordinates + RAS_TEXCO_VIEW, //< View vector as coordinates + RAS_TEXCO_STICKY, //< Sticky coordinates + RAS_TEXCO_WINDOW, //< Window coordinates + RAS_TEXCO_NORM, //< Normal coordinates + RAS_TEXTANGENT, //< + RAS_TEXCO_DISABLE //< Disable this texture unit (cached) + }; + /** * Render pass identifiers for stereo. */ @@ -369,6 +388,11 @@ public: virtual void SetPolygonOffset(float mult, float add) = 0; 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 SetAttrib(int type) = 0; + virtual void GetViewMatrix(MT_Matrix4x4 &mat) const = 0; + }; #endif //__RAS_IRASTERIZER diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index b1d32326048..3aded0568cb 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -135,8 +135,6 @@ void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms, (*it).m_RGBAcolor= rgbavec; } - - bool RAS_MaterialBucket::IsTransparant() const { return (m_material->IsTransparant()); @@ -180,10 +178,11 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I bool dolights = false; const unsigned int flag = m_material->GetFlag(); + if( flag & RAS_BLENDERMAT) - dolights = flag &RAS_MULTILIGHT; + dolights = (flag &RAS_MULTILIGHT)!=0; else - dolights = m_material->GetDrawingMode()&16; + dolights = (m_material->GetDrawingMode()&16)!=0; if ((rasty->GetDrawingMode() <= RAS_IRasterizer::KX_SOLID) || !dolights) { @@ -206,6 +205,7 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa if (!ms.m_bVisible) return; + m_material->ActivateMeshSlot(ms, rasty); rendertools->SetClientObject(ms.m_clientObj); /* __NLA Do the deformation */ @@ -311,7 +311,6 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, } int 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 52f835a4575..448cbc6e343 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -78,7 +78,6 @@ public: mutable bool m_bVisible; // for visibility mutable bool m_bObjectColor; mutable MT_Vector4 m_RGBAcolor; - KX_MeshSlot() : m_pDeformer(NULL), m_bVisible(true) @@ -124,7 +123,7 @@ public: bool visible, bool color, const MT_Vector4& rgbavec); - + void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode); bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 6bc3b75fd5a..54e5364bc88 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -249,6 +249,7 @@ void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx, int RAS_MeshObject::FindOrAddVertex(int vtxarray, const MT_Point3& xyz, const MT_Point2& uv, + const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, RAS_IPolyMaterial* mat, @@ -257,7 +258,7 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - RAS_TexVert newvert(xyz,uv,rgbacolor,normal, 0); + RAS_TexVert newvert(xyz,uv,tangent,rgbacolor,normal, 0); #define KX_FIND_SHARED_VERTICES #ifdef KX_FIND_SHARED_VERTICES @@ -425,7 +426,6 @@ void RAS_MeshObject::MarkVisible(double* oglmatrix, } - void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix, void* clientobj) { diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 367aab750e0..d4884363731 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -236,6 +236,7 @@ public: int vtxarray, const MT_Point3& xyz, const MT_Point2& uv, + const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, RAS_IPolyMaterial* mat, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h index 2a760b09f5e..a2f27ce3361 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h @@ -7,12 +7,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_multitexture ---------------------------------------------------------------------------- */ -/* defined in glext.h -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#endif -*/ - #ifdef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 @@ -34,12 +28,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_texture_env_combine ---------------------------------------------------------------------------- */ -/* -#ifndef GL_ARB_texture_env_combine - #define GL_ARB_texture_env_combine 1 -#endif -*/ - #ifdef GL_ARB_texture_env_combine #define GL_COMBINE_ARB 0x8570 #define GL_COMBINE_RGB_ARB 0x8571 @@ -68,12 +56,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_texture_cube_map ---------------------------------------------------------------------------- */ -/* -#ifndef GL_ARB_texture_cube_map - #define GL_ARB_texture_cube_map 1 -#endif -*/ - #ifdef GL_ARB_texture_cube_map #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 @@ -92,11 +74,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_shader_objects ---------------------------------------------------------------------------- */ -/* -#ifndef GL_ARB_shader_objects - #define GL_ARB_shader_objects 1 -#endif -*/ #ifdef GL_ARB_shader_objects #define GL_PROGRAM_OBJECT_ARB 0x8B40 #define GL_SHADER_OBJECT_ARB 0x8B48 @@ -137,12 +114,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_vertex_shader ---------------------------------------------------------------------------- */ -/* -#ifndef GL_ARB_vertex_shader - #define GL_ARB_vertex_shader 1 -#endif -*/ - #ifdef GL_ARB_vertex_shader #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A @@ -157,12 +128,6 @@ /* ---------------------------------------------------------------------------- GL_ARB_fragment_shader ---------------------------------------------------------------------------- */ -/* -#ifndef GL_ARB_fragment_shader - #define GL_ARB_fragment_shader 1 -#endif -*/ - #ifdef GL_ARB_fragment_shader #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 @@ -170,4 +135,16 @@ #endif +/* ---------------------------------------------------------------------------- + GL_ARB_depth_texture +---------------------------------------------------------------------------- */ +#ifndef GL_ARB_depth_texture + #define GL_DEPTH_COMPONENT16_ARB 0x81A5 + #define GL_DEPTH_COMPONENT24_ARB 0x81A6 + #define GL_DEPTH_COMPONENT32_ARB 0x81A7 + #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A + #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + + #endif//__ARB_MULTITEXTURE_H__ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index af3a9bca03e..58cd8dc2aa1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -406,6 +406,22 @@ PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; #endif + +#ifdef GL_ARB_vertex_program + PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; + PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; + PFNGLVERTEXATTRIB2FARBPROC blVertexAttrib2fARB; + PFNGLVERTEXATTRIB2FVARBPROC blVertexAttrib2fvARB; + PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB; + PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; + PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; + PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; + PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; + PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; + PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; + PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; +#endif + } // namespace bgl using namespace bgl; @@ -589,6 +605,44 @@ static void LinkExtensions() } #endif +#if defined(GL_ARB_vertex_program) + if (QueryExtension("GL_ARB_vertex_program")) + { + bgl::blVertexAttrib1fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fARB")); + bgl::blVertexAttrib1fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fvARB")); + bgl::blVertexAttrib2fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fARB")); + bgl::blVertexAttrib2fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fvARB")); + bgl::blVertexAttrib3fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fARB")); + bgl::blVertexAttrib3fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fvARB")); + bgl::blVertexAttrib4fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fARB")); + bgl::blVertexAttrib4fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fvARB")); + bgl::blGetVertexAttribdvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribdvARB")); + bgl::blGetVertexAttribfvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribfvARB")); + bgl::blGetVertexAttribivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribivARB")); + if (bgl::blVertexAttrib1fARB && bgl::blVertexAttrib1fvARB && bgl::blVertexAttrib2fARB && bgl::blVertexAttrib2fvARB && bgl::blVertexAttrib3fARB && bgl::blVertexAttrib3fvARB && bgl::blGetVertexAttribdvARB) { + EnableExtension(_GL_ARB_vertex_program); + RAS_EXT_support._ARB_vertex_program = 1; + if (doDebugMessages) + std::cout << "Enabled GL_ARB_vertex_program" << std::endl; + } else { + std::cout << "ERROR: GL_ARB_vertex_program implementation is broken!" << std::endl; + } + } +#endif + + +#ifdef GL_ARB_depth_texture + if (QueryExtension("GL_ARB_depth_texture")) + { + EnableExtension(_GL_ARB_depth_texture); + RAS_EXT_support._ARB_depth_texture = 1; + if (doDebugMessages) + { + std::cout << "Detected GL_ARB_depth_texture" << std::endl; + } + } +#endif + if (QueryExtension("GL_EXT_separate_specular_color")) { EnableExtension(_GL_EXT_separate_specular_color); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h index a5dad19222b..00d1d0c9d05 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -397,7 +397,9 @@ typedef struct BL_EXTInfo _ARB_shader_objects(0), _ARB_vertex_shader(0), _ARB_fragment_shader(0), - _EXT_texture3D(0) + _EXT_texture3D(0), + _ARB_vertex_program(0), + _ARB_depth_texture(0) { // } @@ -409,6 +411,8 @@ typedef struct BL_EXTInfo bool _ARB_vertex_shader; bool _ARB_fragment_shader; bool _EXT_texture3D; + bool _ARB_vertex_program; + bool _ARB_depth_texture; }BL_EXTInfo; extern BL_EXTInfo RAS_EXT_support; @@ -500,6 +504,22 @@ extern PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; extern PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; #endif +#ifdef GL_ARB_vertex_program +extern PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; +extern PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; +extern PFNGLVERTEXATTRIB2FARBPROC blVertexAttrib2fARB; +extern PFNGLVERTEXATTRIB2FVARBPROC blVertexAttrib2fvARB; +extern PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB; +extern PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; +extern PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; +extern PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; +extern PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; +extern PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; +extern PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; +extern PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; +#endif + + } /* namespace bgl */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 38dfb7836b2..794562675ad 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -81,6 +81,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_focallength(0.0), m_setfocallength(false), m_noOfScanlines(32), + m_useTang(0), m_materialCachingInfo(0) { m_viewmatrix.Identity(); @@ -603,6 +604,15 @@ void RAS_OpenGLRasterizer::SwapBuffers() +void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const +{ + float viewmat[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, viewmat); + mat.setValue(viewmat); +} + + + void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, int mode, @@ -1191,6 +1201,59 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa } //for each vertexarray } +void RAS_OpenGLRasterizer::SetAttrib(int type) +{ + if(type == RAS_TEXTANGENT) m_useTang=true; +} + + +void RAS_OpenGLRasterizer::SetTexCoords(TexCoGen coords,int unit) +{ + // this changes from material to material + if(unit <= RAS_MAX) + m_texco[unit] = coords; +} + + +void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled) +{ +#ifdef GL_ARB_multitexture + if(bgl::RAS_EXT_support._ARB_multitexture) + { + for(int unit=0; unit m_debugLines; + virtual void SetTexCoords(TexCoGen coords,int enabled); + void TexCoord(const RAS_TexVert &tv, int unit); + virtual void SetAttrib(int type); + virtual void GetViewMatrix(MT_Matrix4x4 &mat) const; + }; #endif //__RAS_OPENGLRASTERIZER diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 9e9b5725b6b..f6174f6de62 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -39,6 +39,7 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, const MT_Point2& uv, + const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, const short flag) @@ -48,6 +49,7 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, uv.getValue(m_uv2); // ..py access SetRGBA(rgba); SetNormal(normal); + tangent.getValue(m_tangent); m_flag = flag; m_unit = 2; } @@ -127,6 +129,12 @@ 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; diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index f58eca7637f..822262aad48 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -71,6 +71,7 @@ public: {} RAS_TexVert(const MT_Point3& xyz, const MT_Point2& uv, + const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, const short flag); @@ -94,6 +95,10 @@ public: return m_normal; } + const float* getTangent() const { + return m_tangent; + } + const unsigned char* getRGBA() const { return (unsigned char *) &m_rgba; } -- cgit v1.2.3