diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-04-03 01:04:20 +0400 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-04-03 01:04:20 +0400 |
commit | 6839ec66405f366d95641b1d5685369a1b19757c (patch) | |
tree | ecd65680f673221994758ab86dd563cf9462d8df /source | |
parent | 756bad72c4ca4538834aed7bbdc46a2cce41393f (diff) |
applied Charlies patch for game engine graphics. display list support, and bumpmapping shader improvements.
Diffstat (limited to 'source')
32 files changed, 1484 insertions, 822 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index f078fd14753..29874fb05c5 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -193,6 +193,7 @@ typedef struct Global { #define G_FILE_NO_UI (1 << 10) #define G_FILE_GAME_TO_IPO (1 << 11) #define G_FILE_GAME_MAT (1 << 12) +#define G_FILE_DIAPLAY_LISTS (1 << 13) /* G.windowstate */ #define G_WINDOWSTATE_USERDEF 0 diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 492705857a4..fc00b2080a6 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -1302,10 +1302,12 @@ static uiBlock *info_addmenu(void *arg_unused) /************************** GAME *****************************/ + static void do_info_gamemenu(void *arg, int event) { switch (event) { case G_FILE_ENABLE_ALL_FRAMES: + case G_FILE_DIAPLAY_LISTS: case G_FILE_SHOW_FRAMERATE: case G_FILE_SHOW_DEBUG_PROPS: case G_FILE_AUTOPLAY: @@ -1342,6 +1344,12 @@ static uiBlock *info_gamemenu(void *arg_unused) if(G.fileflags & G_FILE_GAME_TO_IPO) { uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); } else { + + if(G.fileflags & G_FILE_DIAPLAY_LISTS) { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Generate Display Lists", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_DIAPLAY_LISTS, ""); + } else { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Generate Display Lists", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_DIAPLAY_LISTS, ""); + } uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Record Game Physics to IPO", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_TO_IPO, ""); } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 83290c8899c..c338efec075 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -382,6 +382,8 @@ void space_set_commmandline_options(void) { a=(G.fileflags & G_FILE_GAME_MAT); SYS_WriteCommandLineInt(syshandle, "blender_material", a); + a=(G.fileflags & G_FILE_DIAPLAY_LISTS); + SYS_WriteCommandLineInt(syshandle, "displaylists", a); } diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 4dbddaf2d62..e24ade47783 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -61,6 +61,7 @@ #include "RAS_OpenGLRasterizer.h" #include "RAS_VAOpenGLRasterizer.h" +#include "RAS_ListRasterizer.h" #include "RAS_GLExtensionManager.h" #include "NG_LoopBackNetworkDeviceInterface.h" @@ -122,9 +123,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool game2ipo = (SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0); - + bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); bool usemat = false; - + #ifdef GL_ARB_multitexture if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) { usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0); @@ -148,8 +149,12 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1); bool useVertexArrays = (usevta > 0); - if (useVertexArrays && bgl::QueryVersion(1, 1)) - rasterizer = new RAS_VAOpenGLRasterizer(canvas); + bool lock_arrays = (displaylists && useVertexArrays); + + if(displaylists && !useVertexArrays) + rasterizer = new RAS_ListRasterizer(canvas); + else if (useVertexArrays && bgl::QueryVersion(1, 1)) + rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays); else rasterizer = new RAS_OpenGLRasterizer(canvas); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 8f93ad1a0aa..9ceae753908 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -94,8 +94,6 @@ int KX_BlenderRenderTools::ProcessLighting(int layer) { if (m_clientobject) { - - if (applyLights(layer)) { EnableOpenGLLights(); @@ -104,9 +102,7 @@ int KX_BlenderRenderTools::ProcessLighting(int layer) { DisableOpenGLLights(); result = false; - } - - + } } } return result; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b21eb743334..283120fe2f3 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -426,6 +426,8 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* material->mapping[i].mapping |= USEUV; else if(mttmp->texco &TEXCO_NORM) material->mapping[i].mapping |= USENORM; + else if(mttmp->texco &TEXCO_TANGENT) + material->mapping[i].mapping |= USETANG; else material->mapping[i].mapping |= DISABLE; diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 8de9e5784fe..19f387bc760 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -82,6 +82,7 @@ extern "C" #include "RAS_MeshObject.h" #include "RAS_OpenGLRasterizer.h" #include "RAS_VAOpenGLRasterizer.h" +#include "RAS_ListRasterizer.h" #include "RAS_GLExtensionManager.h" #include "KX_PythonInit.h" #include "KX_PyConstraintBinding.h" @@ -494,7 +495,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool useVertexArrays = SYS_GetCommandLineInt(syshandle,"vertexarrays",1) != 0; - + bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", G.fileflags & G_FILE_DIAPLAY_LISTS) != 0); #ifdef GL_ARB_multitexture int gameflag =(G.fileflags & G_FILE_GAME_MAT); // ---------------------------------- @@ -521,8 +522,10 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_rendertools = new GPC_RenderTools(); if (!m_rendertools) goto initFailed; - - if (useVertexArrays && bgl::QueryVersion(1, 1)) + + if(useLists) + m_rasterizer = new RAS_ListRasterizer(m_canvas); + else if (useVertexArrays && bgl::QueryVersion(1, 1)) m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas); else m_rasterizer = new RAS_OpenGLRasterizer(m_canvas); diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index 7a813cc6c72..27d59257cbd 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -146,7 +146,8 @@ enum BL_MappingFlag USENORM =8, USEORCO =16, USEUV =32, - DISABLE =64 + USETANG =64, + DISABLE =128 }; // BL_Material::BL_Mapping::projplane diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index c1e2028f3fb..a0da2690ccc 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -11,7 +11,6 @@ #include <GL/glu.h> #endif - #include <iostream> #include "BL_Shader.h" #include "BL_Material.h" @@ -29,12 +28,115 @@ //using namespace bgl; #define spit(x) std::cout << x << std::endl; +/* ---- + testing for a faster solution! + ... just compile out + The idea is to install a shader in other + areas if code, find the shader via the scene and, + install it with ... + + shader->ApplyShader() + ... + shader->UnloadShader() +*/ +#define SORT_UNIFORMS 1 + +#define UNIFORM_MAX_LEN sizeof(float)*16 + +BL_Uniform::BL_Uniform(int data_size) +: mLoc(-1), + mDirty(true), + mType(UNI_NONE), + mTranspose(0), + mDataLen(data_size) +{ +#ifdef SORT_UNIFORMS + MT_assert(mDataLen <= UNIFORM_MAX_LEN); + mData = (void*)MEM_mallocN(mDataLen, "shader-uniform-alloc"); +#endif +} + +BL_Uniform::~BL_Uniform() +{ +#ifdef SORT_UNIFORMS + if(mData) { + MEM_freeN(mData); + mData=0; + } +#endif +} + +void BL_Uniform::Apply(class BL_Shader *shader) +{ +#ifdef GL_ARB_shader_objects +#ifdef SORT_UNIFORMS + MT_assert(mType > UNI_NONE && mType < UNI_MAX && mData); + + if(!mDirty) + return; + + switch(mType) + { + case UNI_FLOAT: { + float *f = (float*)mData; + bgl::blUniform1fARB(mLoc,(GLfloat)*f); + }break; + case UNI_INT: { + int *f = (int*)mData; + bgl::blUniform1iARB(mLoc, (GLint)*f); + }break; + case UNI_FLOAT2: { + float *f = (float*)mData; + bgl::blUniform2fvARB(mLoc,1, (GLfloat*)f); + }break; + case UNI_FLOAT3: { + float *f = (float*)mData; + bgl::blUniform3fvARB(mLoc,1,(GLfloat*)f); + }break; + case UNI_FLOAT4: { + float *f = (float*)mData; + bgl::blUniform4fvARB(mLoc,1,(GLfloat*)f); + }break; + case UNI_INT2: { + int *f = (int*)mData; + bgl::blUniform2ivARB(mLoc,1,(GLint*)f); + }break; + case UNI_INT3: { + int *f = (int*)mData; + bgl::blUniform3ivARB(mLoc,1,(GLint*)f); + }break; + case UNI_INT4: { + int *f = (int*)mData; + bgl::blUniform4ivARB(mLoc,1,(GLint*)f); + }break; + case UNI_MAT4: { + float *f = (float*)mData; + bgl::blUniformMatrix4fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); + }break; + case UNI_MAT3: { + float *f = (float*)mData; + bgl::blUniformMatrix3fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); + }break; + } + mDirty = false; +#endif +#endif +} + +void BL_Uniform::SetData(int location, int type,bool transpose) +{ +#ifdef SORT_UNIFORMS + mType = type; + mLoc = location; + mDirty = true; +#endif +} + const bool BL_Shader::Ok()const { return (mShader !=0 && mOk && mUse); } - BL_Shader::BL_Shader(PyTypeObject *T) : PyObjectPlus(T), mShader(0), @@ -44,20 +146,11 @@ BL_Shader::BL_Shader(PyTypeObject *T) vertProg(""), fragProg(""), mError(0), - mAttr(0), - mPreDefLoc(-1), - mPreDefType(-1), - mDeleteTexture(0) + mDirty(true) { // if !RAS_EXT_support._ARB_shader_objects this class will not be used - for (int i=0; i<MAXTEX; i++) { - mSampler[i].type = 0; - mSampler[i].pass = 0; - mSampler[i].unit = -1; - mSampler[i].loc = -1; - mSampler[i].gl_texture = 0; - mSampler[i].flag=0; + mSampler[i] = BL_Sampler(); } } @@ -66,14 +159,14 @@ using namespace bgl; BL_Shader::~BL_Shader() { #ifdef GL_ARB_shader_objects - for (int i=0; i<MAXTEX; i++) - { - if(mSampler[i].flag & OWN) - { - if(mSampler[i].gl_texture) - mSampler[i].gl_texture->DeleteTex(); + for (int i=0; i<MAXTEX; i++){ + if(mSampler[i].mOwn) { + if(mSampler[i].mTexture) + mSampler[i].mTexture->DeleteTex(); } } + ClearUniforms(); + if( mShader ) { bgl::blDeleteObjectARB(mShader); mShader = 0; @@ -81,11 +174,113 @@ BL_Shader::~BL_Shader() vertProg = 0; fragProg = 0; mOk = 0; - bgl::blUseProgramObjectARB(0); #endif//GL_ARB_shader_objects } +void BL_Shader::ClearUniforms() +{ + BL_UniformVec::iterator it = mUniforms.begin(); + while(it != mUniforms.end()){ + delete (*it); + it++; + } + mUniforms.clear(); + + + BL_UniformVecDef::iterator itp = mPreDef.begin(); + while(itp != mPreDef.end()) { + delete (*itp); + itp++; + } + mPreDef.clear(); + +} + + +BL_Uniform *BL_Shader::FindUniform(const int location) +{ +#ifdef SORT_UNIFORMS + BL_UniformVec::iterator it = mUniforms.begin(); + while(it != mUniforms.end()) { + if((*it)->GetLocation() == location) + return (*it); + it++; + } +#endif + return 0; +} + +void BL_Shader::SetUniformfv(int location, int type, float *param,int size, bool transpose) +{ +#ifdef SORT_UNIFORMS +#ifndef NDEBUG + MT_assert(type > UNI_NONE && type < UNI_MAX); + MT_assert(location); + MT_assert(param); + MT_assert(size > 0 && size <= UNIFORM_MAX_LEN); +#endif + + BL_Uniform *uni= FindUniform(location); + if(uni) { + memcpy(uni->getData(), param, size); + uni->SetData(location, type, transpose); + } + else { + uni = new BL_Uniform(size); + memcpy(uni->getData(), param, size); + + uni->SetData(location, type, transpose); + mUniforms.push_back(uni); + } + mDirty = true; +#endif +} + +void BL_Shader::SetUniformiv(int location, int type, int *param,int size, bool transpose) +{ +#ifdef SORT_UNIFORMS +#ifndef NDEBUG + MT_assert(type > UNI_NONE && type < UNI_MAX); + MT_assert(location); + MT_assert(param); + MT_assert(size > 0 && size <= UNIFORM_MAX_LEN); +#endif + + BL_Uniform *uni= FindUniform(location); + if(uni) { + memcpy(uni->getData(), param, size); + uni->SetData(location, type, transpose); + } + else { + uni = new BL_Uniform(size); + memcpy(uni->getData(), param, size); + uni->SetData(location, type, transpose); + mUniforms.push_back(uni); + } + mDirty = true; +#endif +} + + +void BL_Shader::ApplyShader() +{ +#ifdef SORT_UNIFORMS + if(!mDirty) + return; + + for(unsigned int i=0; i<mUniforms.size(); i++) + mUniforms[i]->Apply(this); + + mDirty = false; +#endif +} + +void BL_Shader::UnloadShader() +{ + // +} + bool BL_Shader::LinkProgram() { @@ -214,12 +409,12 @@ programError: #endif//GL_ARB_shader_objects } -char *BL_Shader::GetVertPtr() +const char *BL_Shader::GetVertPtr() { return vertProg?vertProg:0; } -char *BL_Shader::GetFragPtr() +const char *BL_Shader::GetFragPtr() { return fragProg?fragProg:0; } @@ -239,7 +434,7 @@ unsigned int BL_Shader::GetProg() return mShader; } -const uSampler* BL_Shader::getSampler(int i) +const BL_Sampler* BL_Shader::GetSampler(int i) { MT_assert(i<=MAXTEX); return &mSampler[i]; @@ -258,23 +453,14 @@ void BL_Shader::SetSampler(int loc, int unit) #endif } - -void BL_Shader::InitializeSampler( - int type, - int unit, - int pass, - BL_Texture* texture) +void BL_Shader::InitializeSampler(int unit, BL_Texture* texture) { MT_assert(unit<=MAXTEX); - 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; + mSampler[unit].mTexture = texture; + mSampler[unit].mLoc =-1; + mSampler[unit].mOwn = 0; } - void BL_Shader::SetProg(bool enable) { #ifdef GL_ARB_shader_objects @@ -296,7 +482,8 @@ void BL_Shader::SetProg(bool enable) void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) { #ifdef GL_ARB_shader_objects - if(!Ok()) return; + if(!Ok() || !mPreDef.size()) + return; if( RAS_EXT_support._ARB_fragment_shader && RAS_EXT_support._ARB_vertex_shader && @@ -307,86 +494,99 @@ void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) model.setValue(ms.m_OpenGLMatrix); MT_Matrix4x4 view; rasty->GetViewMatrix(view); - switch (mPreDefType) + + BL_UniformVecDef::iterator it; + for(it = mPreDef.begin(); it!= mPreDef.end(); it++) { - 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; - } + BL_DefUniform *uni = (*it); + if(!uni->mLoc) continue; - 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); + switch (uni->mType) + { + case MODELMATRIX: + { + SetUniform(uni->mLoc, model); + break; + } + case MODELMATRIX_TRANSPOSE: + { + SetUniform(uni->mLoc, model, true); + break; + } + case MODELMATRIX_INVERSE: + { + model.invert(); + SetUniform(uni->mLoc, model); + break; + } + case MODELMATRIX_INVERSETRANSPOSE: + { + model.invert(); + SetUniform(uni->mLoc, model, true); + break; + } + case MODELVIEWMATRIX: + { + SetUniform(uni->mLoc, view*model); + break; + } + + case MODELVIEWMATRIX_TRANSPOSE: + { + MT_Matrix4x4 mat(view*model); + SetUniform(uni->mLoc, mat, true); + break; + } + case MODELVIEWMATRIX_INVERSE: + { + MT_Matrix4x4 mat(view*model); + mat.invert(); + SetUniform(uni->mLoc, mat); + break; + } + case MODELVIEWMATRIX_INVERSETRANSPOSE: + { + MT_Matrix4x4 mat(view*model); + mat.invert(); + SetUniform(uni->mLoc, mat, true); + break; + } + case CAM_POS: + { + MT_Point3 pos(rasty->GetCameraPosition()); + SetUniform(uni->mLoc, pos); + break; + } + case VIEWMATRIX: + { + SetUniform(uni->mLoc, view); + break; + } + case VIEWMATRIX_TRANSPOSE: + { + SetUniform(uni->mLoc, view, true); + break; + } + case VIEWMATRIX_INVERSE: + { + view.invert(); + SetUniform(uni->mLoc, view); + break; + } + case VIEWMATRIX_INVERSETRANSPOSE: + { + view.invert(); + SetUniform(uni->mLoc, view, true); + break; + } + case CONSTANT_TIMER: + { + SetUniform(uni->mLoc, (float)rasty->GetTime()); + break; + } + default: break; - } - default: - break; + } } } #endif @@ -428,7 +628,11 @@ int BL_Shader::GetUniformLocation(const STR_String& name) RAS_EXT_support._ARB_shader_objects ) { - return bgl::blGetUniformLocationARB(mShader, name.ReadPtr()); + MT_assert(mShader!=0); + int location = bgl::blGetUniformLocationARB(mShader, name.ReadPtr()); + if(location == -1) + spit("Invalid uniform value: " << name.ReadPtr() << "."); + return location; } #endif return -1; @@ -493,6 +697,19 @@ void BL_Shader::SetUniform(int uniform, const unsigned int& val) #endif } +void BL_Shader::SetUniform(int uniform, const 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 @@ -530,14 +747,55 @@ void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose) ) { 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]; + value[0] = (float)vec[0][0]; value[1] = (float)vec[1][0]; value[2] = (float)vec[2][0]; + value[3] = (float)vec[0][1]; value[4] = (float)vec[1][1]; value[5] = (float)vec[2][1]; + value[6] = (float)vec[0][2]; value[7] = (float)vec[1][2]; value[7] = (float)vec[2][2]; bgl::blUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); } #endif } +void BL_Shader::SetUniform(int uniform, const float* val, int len) +{ +#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(len == 2) + bgl::blUniform2fvARB(uniform, 1,(GLfloat*)val); + else if (len == 3) + bgl::blUniform3fvARB(uniform, 1,(GLfloat*)val); + else if (len == 4) + bgl::blUniform4fvARB(uniform, 1,(GLfloat*)val); + else + MT_assert(0); + } +#endif +} + +void BL_Shader::SetUniform(int uniform, const int* val, int len) +{ +#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(len == 2) + bgl::blUniform2ivARB(uniform, 1, (GLint*)val); + else if (len == 3) + bgl::blUniform3ivARB(uniform, 1, (GLint*)val); + else if (len == 4) + bgl::blUniform4ivARB(uniform, 1, (GLint*)val); + else + MT_assert(0); + } +#endif +} + + PyObject* BL_Shader::_getattr(const STR_String& attr) { _getattr_up(PyObjectPlus); @@ -563,7 +821,8 @@ PyMethodDef BL_Shader::Methods[] = KX_PYMETHODTABLE( BL_Shader, setUniform2i ), KX_PYMETHODTABLE( BL_Shader, setUniform3i ), KX_PYMETHODTABLE( BL_Shader, setUniform4i ), - KX_PYMETHODTABLE( BL_Shader, setAttrib ), +// TODO: GL_ARB_vertex/fragment_program support +// KX_PYMETHODTABLE( BL_Shader, setAttrib ), KX_PYMETHODTABLE( BL_Shader, setUniformfv ), KX_PYMETHODTABLE( BL_Shader, setUniformiv ), @@ -634,16 +893,15 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) { #ifdef GL_ARB_shader_objects + ClearUniforms(); + bgl::blUseProgramObjectARB(0); + bgl::blDeleteObjectARB(mShader); mShader = 0; - vertProg = 0; - fragProg = 0; mOk = 0; mUse = 0; - bgl::blUseProgramObjectARB(0); #endif Py_Return; - } KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" ) @@ -693,7 +951,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -703,29 +960,16 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" ) int index=-1; if(PyArg_ParseTuple(args, "si", &uniform, &index)) { - 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 { + int loc = GetUniformLocation(uniform); + if(loc != -1) { if(index <= MAXTEX) - mSampler[index].loc = loc; + mSampler[index].mLoc = loc; else spit("Invalid texture sample index: " << index); - Py_Return; } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" ) @@ -741,7 +985,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass ) /// access functions KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -751,34 +994,23 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" ) float value=0; if(PyArg_ParseTuple(args, "sf", &uniform, &value )) { - if( mShader==0 ) - { - PyErr_Format(PyExc_ValueError, "invalid shader object"); - return NULL; - } - int loc= bgl::blGetUniformLocationARB(mShader, uniform); - if( loc==-1 ) + int loc = GetUniformLocation(uniform); + if(loc != -1) { - spit("Invalid uniform value: " << uniform << "."); - Py_Return; - }else - { - bgl::blUseProgramObjectARB( mShader ); - bgl::blUniform1fARB( loc, value ); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT, &value, sizeof(float)); +#else + SetUniform( loc, (float)value ); +#endif } - + Py_Return; } return NULL; -#else - Py_Return; -#endif } KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -787,34 +1019,23 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)") float array[2]={ 0,0 }; if(PyArg_ParseTuple(args, "sff", &uniform, &array[0],&array[1] )) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { - bgl::blUseProgramObjectARB( mShader ); - bgl::blUniform2fARB(loc, array[0],array[1] ); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array, (sizeof(float)*2) ); +#else + SetUniform(loc, array, 2); +#endif } - + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -823,34 +1044,24 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ") float array[3]={0,0,0}; if(PyArg_ParseTuple(args, "sfff", &uniform, &array[0],&array[1],&array[2])) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform3fARB(loc, array[0],array[1],array[2]); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array, (sizeof(float)*3) ); +#else + SetUniform(loc, array, 3); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) ") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -859,33 +1070,23 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) " float array[4]={0,0,0,0}; if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3])) { - if(mShader==0) + int loc = GetUniformLocation(uniform); + if(loc != -1) { - 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 - { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform4fARB(loc, array[0],array[1],array[2], array[3]); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array, (sizeof(float)*4) ); +#else + SetUniform(loc, array, 4); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -894,33 +1095,23 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" ) int value=0; if(PyArg_ParseTuple(args, "si", &uniform, &value )) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { - bgl::blUseProgramObjectARB( mShader ); - bgl::blUniform1iARB( loc, value ); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT, &value, sizeof(int)); +#else + SetUniform(loc, (int)value); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -929,67 +1120,48 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)") int array[2]={ 0,0 }; if(PyArg_ParseTuple(args, "sii", &uniform, &array[0],&array[1] )) { - if( mShader==0 ) - { - PyErr_Format(PyExc_ValueError, "invalid shader object"); - return NULL; - } - int loc= bgl::blGetUniformLocationARB(mShader , uniform); - if( loc==-1 ) + int loc = GetUniformLocation(uniform); + if(loc != -1) { - spit("Invalid uniform value: " << uniform << "."); - Py_Return; - }else - { - bgl::blUseProgramObjectARB( mShader ); - bgl::blUniform2iARB(loc, array[0],array[1] ); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT2, array, sizeof(int)*2); +#else + SetUniform(loc, array, 2); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; } + char *uniform=""; int array[3]={0,0,0}; if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2])) { - if(mShader==0) + int loc = GetUniformLocation(uniform); + if(loc != -1) { - 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 - { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform3iARB(loc, array[0],array[1],array[2]); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT3, array, sizeof(int)*3); +#else + SetUniform(loc, array, 3); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) ") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -998,32 +1170,22 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) " int array[4]={0,0,0, 0}; if(PyArg_ParseTuple(args, "siiii", &uniform, &array[0],&array[1],&array[2], &array[3] )) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform4iARB(loc, array[0],array[1],array[2], array[3]); - Py_Return; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT4, array, sizeof(int)*4); +#else + SetUniform(loc, array, 4); +#endif } + Py_Return; } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or list3 or list4) )") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -1034,17 +1196,8 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr)) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { if(PySequence_Check(listPtr)) { @@ -1056,24 +1209,37 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis array_data[i] = (float)PyFloat_AsDouble(item); Py_DECREF(item); } + switch(list_size) { case 2: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform2fARB(loc, array_data[0],array_data[1]); + float array2[2] = { array_data[0],array_data[1] }; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT2, array2, sizeof(float)*2); +#else + SetUniform(loc, array2, 2); +#endif Py_Return; } break; case 3: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform3fARB(loc, array_data[0],array_data[1], array_data[2]); + float array3[3] = { array_data[0],array_data[1],array_data[2] }; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT3, array3, sizeof(float)*3); +#else + SetUniform(loc, array3, 3); +#endif Py_Return; }break; case 4: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform4fARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]); + float array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] }; +#ifdef SORT_UNIFORMS + SetUniformfv(loc, BL_Uniform::UNI_FLOAT4, array4, sizeof(float)*4); +#else + SetUniform(loc, array4, 4); +#endif Py_Return; }break; default: @@ -1086,15 +1252,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis } } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects - } KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 or list4) )") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -1105,17 +1266,8 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr)) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { if(PySequence_Check(listPtr)) { @@ -1131,20 +1283,34 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 { case 2: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform2iARB(loc, array_data[0],array_data[1]); + int array2[2] = { array_data[0],array_data[1]}; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT2, array2, sizeof(int)*2); +#else + SetUniform(loc, array2, 2); +#endif Py_Return; } break; case 3: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform3iARB(loc, array_data[0],array_data[1], array_data[2]); + int array3[3] = { array_data[0],array_data[1],array_data[2] }; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT3, array3, sizeof(int)*3); + +#else + SetUniform(loc, array3, 3); +#endif Py_Return; }break; case 4: { - bgl::blUseProgramObjectARB(mShader); - bgl::blUniform4iARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]); + int array4[4] = { array_data[0],array_data[1],array_data[2],array_data[3] }; +#ifdef SORT_UNIFORMS + SetUniformiv(loc, BL_Uniform::UNI_INT4, array4, sizeof(int)*4); + +#else + SetUniform(loc, array4, 4); +#endif Py_Return; }break; default: @@ -1157,16 +1323,12 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 } } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, "setUniformMatrix4(uniform-name, mat-4x4, transpose(row-major=true, col-major=false)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -1184,42 +1346,32 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, int transp=1; // MT_ is row major so transpose by default.... if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp)) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { if (PyObject_IsMT_Matrix(matrix, 4)) { MT_Matrix4x4 mat; if (PyMatTo(matrix, mat)) { +#ifdef SORT_UNIFORMS mat.getValue(matr); - bgl::blUseProgramObjectARB(mShader); - bgl::blUniformMatrix4fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr); + SetUniformfv(loc, BL_Uniform::UNI_MAT4, matr, (sizeof(float)*16), (transp!=0) ); +#else + SetUniform(loc,mat,(transp!=0)); +#endif Py_Return; } } } } return NULL; -#else - Py_Return; -#endif//GL_ARB_shader_objects } KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, "setUniformMatrix3(uniform-name, list[3x3], transpose(row-major=true, col-major=false)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -1236,93 +1388,72 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, int transp=1; // MT_ is row major so transpose by default.... if(PyArg_ParseTuple(args, "sO|i",&uniform, &matrix,&transp)) { - 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 + int loc = GetUniformLocation(uniform); + if(loc != -1) { if (PyObject_IsMT_Matrix(matrix, 3)) { MT_Matrix3x3 mat; if (PyMatTo(matrix, mat)) { +#ifdef SORT_UNIFORMS mat.getValue(matr); - bgl::blUseProgramObjectARB(mShader); - bgl::blUniformMatrix3fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr); + SetUniformfv(loc, BL_Uniform::UNI_MAT3, matr, (sizeof(float)*9), (transp!=0) ); +#else + SetUniform(loc,mat,(transp!=0)); +#endif Py_Return; + } } } } return NULL; -#else - 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; + int nloc=0; 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 ) + int loc = GetUniformLocation(uniform); + if(loc != -1) { - spit("Invalid uniform value: " << uniform << "."); - Py_Return; - }else - { - mPreDefLoc = loc; - mPreDefType = nloc; + bool defined = false; + BL_UniformVecDef::iterator it = mPreDef.begin(); + while(it != mPreDef.end()) { + if((*it)->mLoc == loc) { + defined = true; + break; + } + it++; + } + if(defined) + { + Py_Return; + } + + BL_DefUniform *uni = new BL_DefUniform(); + uni->mLoc = loc; + uni->mType = nloc; + uni->mFlag = 0; + mPreDef.push_back(uni); Py_Return; } } return NULL; - -#endif } - +// eof diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 6536fdc8175..550f4750a33 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -11,53 +11,124 @@ #include "MT_Tuple3.h" #include "MT_Tuple4.h" -// ----------------------------------- -// user state management -typedef struct uSampler +#define SHADER_ATTRIBMAX 1 + +/** + * BL_Sampler + * Sampler access + */ +class BL_Sampler +{ +public: + BL_Sampler(): + mLoc(-1), + mTexture(0), + mOwn(0) + { + } + int mLoc; // Sampler location + BL_Texture* mTexture; // Texture data + bool mOwn; // True if we own it +}; + +/** + * BL_Uniform + * uniform storage + */ +class BL_Uniform { - unsigned int type; - int pass; - int unit; - int loc; - BL_Texture* gl_texture; - int flag; -}uSampler; - -#define SAMP_2D 1 -#define SAMP_CUBE 2 -#define ATTRIBMAX 1 - -// uSampler::flag; -enum +private: + int mLoc; // Uniform location + void* mData; // Memory allocated for variable + bool mDirty; // Caching variable + int mType; // Enum UniformTypes + bool mTranspose; // Transpose matrices + const int mDataLen; // Length of our data +public: + BL_Uniform(int data_size); + ~BL_Uniform(); + + + void Apply(class BL_Shader *shader); + void SetData(int location, int type, bool transpose=false); + + enum UniformTypes { + UNI_NONE =0, + UNI_INT, + UNI_FLOAT, + UNI_INT2, + UNI_FLOAT2, + UNI_INT3, + UNI_FLOAT3, + UNI_INT4, + UNI_FLOAT4, + UNI_MAT3, + UNI_MAT4, + UNI_MAX + }; + + int GetLocation() { return mLoc; } + void* getData() { return mData; } +}; + +/** + * BL_DefUniform + * pre defined uniform storage + */ +class BL_DefUniform { - OWN=1 +public: + BL_DefUniform() : + mType(0), + mLoc(0), + mFlag(0) + { + } + int mType; + int mLoc; + unsigned int mFlag; }; -// ---------------- +/** + * BL_Shader + * shader access + */ class BL_Shader : public PyObjectPlus { Py_Header; private: - unsigned int mShader; - int mPass; - bool mOk; - bool mUse; - uSampler mSampler[MAXTEX]; - char* vertProg; - char* fragProg; - bool mError; - - int mAttr; - int mPreDefLoc; - int mPreDefType; - bool mDeleteTexture; + typedef std::vector<BL_Uniform*> BL_UniformVec; + typedef std::vector<BL_DefUniform*> BL_UniformVecDef; + + unsigned int mShader; // Shader object + int mPass; // 1.. unused + bool mOk; // Valid and ok + bool mUse; // ... + BL_Sampler mSampler[MAXTEX]; // Number of samplers + char* vertProg; // Vertex program string + char* fragProg; // Fragment program string + bool mError; // ... + bool mDirty; // + + // Compiles and links the shader + bool LinkProgram(); + + // Stored uniform variables + BL_UniformVec mUniforms; + BL_UniformVecDef mPreDef; + + // search by location + BL_Uniform* FindUniform(const int location); + // clears uniform data + void ClearUniforms(); - bool LinkProgram(); public: BL_Shader(PyTypeObject *T=&Type); virtual ~BL_Shader(); - enum AttribTypes{ + // Unused for now tangent is set as + // tex coords + enum AttribTypes { SHD_TANGENT =1 }; @@ -78,46 +149,61 @@ public: VIEWMATRIX_TRANSPOSE, VIEWMATRIX_INVERSE, VIEWMATRIX_INVERSETRANSPOSE, - CAM_POS + + // Current camera position + CAM_POS, + + // RAS timer + CONSTANT_TIMER }; - char* GetVertPtr(); - char* GetFragPtr(); - void SetVertPtr( char *vert ); - void SetFragPtr( char *frag ); + const char* GetVertPtr(); + const char* GetFragPtr(); + void SetVertPtr( char *vert ); + void SetFragPtr( char *frag ); // --- int getNumPass() {return mPass;} - bool use() {return mUse;} bool GetError() {return mError;} // --- - // access - const uSampler* getSampler(int i); + const BL_Sampler* GetSampler(int i); void SetSampler(int loc, int unit); const bool Ok()const; unsigned int GetProg(); void SetProg(bool enable); - int GetAttribute(){return mAttr;}; - void InitializeSampler( int type, int unit, int pass, BL_Texture* texture ); + // -- + // Apply methods : sets colected uniforms + void ApplyShader(); + void UnloadShader(); - void Update( const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty ); + // Update predefined uniforms each render call + 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); + // Set sampler units (copied) + void InitializeSampler(int unit, BL_Texture* texture ); - // ----------------------------------- - // python interface + + void SetUniformfv(int location,int type, float *param, int size,bool transpose=false); + void SetUniformiv(int location,int type, int *param, int size,bool transpose=false); + + int GetAttribLocation(const STR_String& name); + void BindAttribute(const STR_String& attr, int loc); + int GetUniformLocation(const STR_String& name); + + void SetUniform(int uniform, const MT_Tuple2& vec); + void SetUniform(int uniform, const MT_Tuple3& vec); + void SetUniform(int uniform, const MT_Tuple4& vec); + void SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose=false); + void SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose=false); + void SetUniform(int uniform, const float& val); + void SetUniform(int uniform, const float* val, int len); + void SetUniform(int uniform, const int* val, int len); + void SetUniform(int uniform, const unsigned int& val); + void SetUniform(int uniform, const int val); + + // Python interface virtual PyObject* _getattr(const STR_String& attr); KX_PYMETHOD_DOC( BL_Shader, setSource ); @@ -148,11 +234,9 @@ public: KX_PYMETHOD_DOC( BL_Shader, setAttrib ); - // these come from within the material buttons + // These come from within the material buttons // sampler2d/samplerCube work KX_PYMETHOD_DOC( BL_Shader, setSampler); }; - - #endif//__BL_SHADER_H__ diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 4ff31b885ba..e6356207225 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -59,8 +59,8 @@ BL_Texture::BL_Texture() mOk(0), mNeedsDeleted(0), mType(0), - mName(""), - mUnit(0) + mUnit(0), + mEnvState(0) { // -- } @@ -77,6 +77,16 @@ void BL_Texture::DeleteTex() mNeedsDeleted = 0; mOk = 0; } + + if(mEnvState) { + glDeleteLists((GLuint)mEnvState, 1); + mEnvState =0; + } + + if(mDisableState) { + glDeleteLists((GLuint)mDisableState, 1); + mDisableState =0; + } } @@ -98,7 +108,6 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap) } mTexture = img->bindcode; - mName = img->id.name; mType = GL_TEXTURE_2D; mUnit = unit; @@ -193,7 +202,6 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap ) mNeedsDeleted = 1; mType = GL_TEXTURE_CUBE_MAP_ARB; mTexture = 0; - mName = CubeMap->ima->id.name; mUnit = unit; @@ -263,13 +271,6 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap ) #endif//GL_ARB_texture_cube_map } - -STR_String BL_Texture::GetName() const -{ - return mName; -} - - bool BL_Texture::IsValid() { return (mTexture!= 0)?glIsTexture(mTexture)!=0:false; @@ -308,8 +309,12 @@ int BL_Texture::GetMaxUnits() void BL_Texture::ActivateFirst() { #ifdef GL_ARB_multitexture - if(RAS_EXT_support._ARB_multitexture) + if(RAS_EXT_support._ARB_multitexture) { bgl::blActiveTextureARB(GL_TEXTURE0_ARB); + //if(mVertexArray) + // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB); + } + #endif } @@ -318,7 +323,11 @@ 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); + //if(mVertexArray) + // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+unit); + } } #endif } @@ -327,8 +336,11 @@ void BL_Texture::ActivateUnit(int unit) void BL_Texture::DisableUnit() { #ifdef GL_ARB_multitexture - if(RAS_EXT_support._ARB_multitexture) + if(RAS_EXT_support._ARB_multitexture){ bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit); + //if(mVertexArray) + // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+mUnit); + } #endif glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -350,10 +362,23 @@ void BL_Texture::DisableUnit() void BL_Texture::DisableAllTextures() { #ifdef GL_ARB_multitexture + if(mDisableState != 0 && glIsList(mDisableState)) { + glCallList(mDisableState); + return; + } + if(!mDisableState) + mDisableState = glGenLists(1); + + glNewList(mDisableState, GL_COMPILE_AND_EXECUTE); + glDisable(GL_BLEND); for(int i=0; i<MAXTEX; i++) { if(RAS_EXT_support._ARB_multitexture) + { bgl::blActiveTextureARB(GL_TEXTURE0_ARB+i); + //if(mVertexArray) + // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+i); + } glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); @@ -368,6 +393,8 @@ void BL_Texture::DisableAllTextures() glDisable(GL_TEXTURE_GEN_Q); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } + + glEndList(); #endif } @@ -376,7 +403,11 @@ void BL_Texture::ActivateTexture() { #ifdef GL_ARB_multitexture if(RAS_EXT_support._ARB_multitexture) + { bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit); + // if(mVertexArray) + // bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+mUnit); + } #ifdef GL_ARB_texture_cube_map if(mType == GL_TEXTURE_CUBE_MAP_ARB && RAS_EXT_support._ARB_texture_cube_map ) { glDisable(GL_TEXTURE_2D); @@ -385,7 +416,10 @@ void BL_Texture::ActivateTexture() } else #endif { - glDisable(GL_TEXTURE_CUBE_MAP_ARB); +#ifdef GL_ARB_texture_cube_map + if(RAS_EXT_support._ARB_texture_cube_map ) + glDisable(GL_TEXTURE_CUBE_MAP_ARB); +#endif glBindTexture( GL_TEXTURE_2D, mTexture ); glEnable(GL_TEXTURE_2D); } @@ -443,6 +477,16 @@ void BL_Texture::setTexEnv(BL_Material *mat, bool modulate) return; } + if(glIsList(mEnvState)) + { + glCallList(mEnvState); + return; + } + if(!mEnvState) + mEnvState = glGenLists(1); + + glNewList(mEnvState, GL_COMPILE_AND_EXECUTE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); GLfloat blend_operand = GL_SRC_COLOR; @@ -560,6 +604,8 @@ void BL_Texture::setTexEnv(BL_Material *mat, bool modulate) } break; } glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0); + + glEndList(); #endif //!GL_ARB_texture_env_combine } @@ -571,6 +617,9 @@ int BL_Texture::GetPow2(int n) return n; } + +unsigned int BL_Texture::mDisableState = 0; + extern "C" { void my_envmap_split_ima(EnvMap *env) diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index 2df14580e65..0c12b11b12b 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -1,8 +1,8 @@ #ifndef __BL_TEXTURE_H__ #define __BL_TEXTURE_H__ -#include <vector> -#include <map> +// #include <vector> +// #include <map> #include "MT_Matrix4x4.h" #include "KX_Camera.h" @@ -11,39 +11,36 @@ struct Image; struct EnvMap; class BL_Material; -class RTData; class RAS_Rect; class RAS_ICanvas; +//class RTData; -// -- #include "STR_String.h" class BL_Texture { private: // ----------------------------------- - unsigned int mTexture; - bool mError; - bool mOk; - bool mNeedsDeleted; - unsigned int mType; - STR_String mName; - int mUnit; + unsigned int mTexture; // Bound texture unit data + bool mError; // Errors + bool mOk; // ... + bool mNeedsDeleted; // If generated + unsigned int mType; // enum TEXTURE_2D | CUBE_MAP + int mUnit; // Texture unit associated with mTexture + unsigned int mEnvState; // cache textureEnv + static unsigned int mDisableState; // speed up disabling calls // ----------------------------------- + void InitNonPow2Tex(unsigned int *p,int x,int y,bool mipmap ); void InitGLTex(unsigned int *p,int x,int y,bool mipmap ); - public: BL_Texture(); ~BL_Texture( ); - - //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(); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index d416ef55613..f61cab58392 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -193,14 +193,16 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) BL_Texture::ActivateFirst(); + mShader->ApplyShader(); + // for each enabled unit for(i=0; i<mMaterial->num_enabled; i++) { - const uSampler *samp = mShader->getSampler(i); - BL_Texture *tex = samp->gl_texture; - if( samp->loc == -1 || !tex || !tex->Ok() ) + const BL_Sampler *samp = mShader->GetSampler(i); + BL_Texture *tex = samp->mTexture; + if( samp->mLoc == -1 || !tex || !tex->Ok() ) continue; tex->ActivateTexture(); - mShader->SetSampler(samp->loc, i); + mShader->SetSampler(samp->mLoc, i); } if(!mUserDefBlend) { setDefaultBlending(); @@ -272,7 +274,7 @@ KX_BlenderMaterial::ActivatShaders( TCachingInfo& cachingInfo)const { KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); - + // reset... if(tmp->mMaterial->IsShared()) cachingInfo =0; @@ -299,44 +301,17 @@ KX_BlenderMaterial::ActivatShaders( rasty->SetCullFace(true); if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES) + { + if((mMaterial->ras_mode &WIRE)!=0) + rasty->SetCullFace(false); rasty->SetLines(true); + } else rasty->SetLines(false); } - - // shaders have access to the variables set here - // via builtin GLSL variables - // eg: gl_FrontMaterial.diffuse - // -- - rasty->SetSpecularity( - mMaterial->speccolor[0]*mMaterial->spec_f, - mMaterial->speccolor[1]*mMaterial->spec_f, - mMaterial->speccolor[2]*mMaterial->spec_f, - mMaterial->spec_f - ); - - rasty->SetShinyness( mMaterial->hard ); - - rasty->SetDiffuse( - mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, - 1.0f); - - rasty->SetEmissive( - mMaterial->matcolor[0]*mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->emit, - 1.0 - ); - - rasty->SetAmbient(mMaterial->amb); - - if (mMaterial->material) - rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); - - tmp->applyTexGen(rasty); + ActivatGLMaterials(rasty); + ActivateTexGen(rasty); } void @@ -367,37 +342,16 @@ KX_BlenderMaterial::ActivateMat( rasty->SetCullFace(true); if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES) + { + if((mMaterial->ras_mode &WIRE)!=0) + rasty->SetCullFace(false); rasty->SetLines(true); + } else rasty->SetLines(false); } - - rasty->SetSpecularity( - mMaterial->speccolor[0]*mMaterial->spec_f, - mMaterial->speccolor[1]*mMaterial->spec_f, - mMaterial->speccolor[2]*mMaterial->spec_f, - mMaterial->spec_f - ); - - rasty->SetShinyness( mMaterial->hard ); - - rasty->SetDiffuse( - mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, - 1.0f); - - rasty->SetEmissive( - mMaterial->matcolor[0]*mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->emit, - 1.0 - ); - rasty->SetAmbient(mMaterial->amb); - if (mMaterial->material) - rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); - - tmp->applyTexGen(rasty); + ActivatGLMaterials(rasty); + ActivateTexGen(rasty); } @@ -443,6 +397,57 @@ void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterize mShader->Update(ms, rasty); } +void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const +{ + rasty->SetSpecularity( + mMaterial->speccolor[0]*mMaterial->spec_f, + mMaterial->speccolor[1]*mMaterial->spec_f, + mMaterial->speccolor[2]*mMaterial->spec_f, + mMaterial->spec_f + ); + + rasty->SetShinyness( mMaterial->hard ); + + rasty->SetDiffuse( + mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, + mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, + mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, + 1.0f); + + rasty->SetEmissive( + mMaterial->matcolor[0]*mMaterial->emit, + mMaterial->matcolor[1]*mMaterial->emit, + mMaterial->matcolor[2]*mMaterial->emit, + 1.0 + ); + rasty->SetAmbient(mMaterial->amb); + if (mMaterial->material) + rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); +} + +void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const +{ + //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; i<mMaterial->num_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 if(mode &USETANG) + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXTANGENT, i); + else + ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + } +} bool KX_BlenderMaterial::setDefaultBlending() { @@ -543,29 +548,6 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) } -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; i<mMaterial->num_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( MT_Vector4 rgba, @@ -625,7 +607,6 @@ PyParentObject KX_BlenderMaterial::Parents[] = { PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr) { - // nodda ? _getattr_up(PyObjectPlus); } @@ -672,9 +653,9 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") mShader = new BL_Shader(); for(int i= 0; i<mMaterial->num_enabled; i++) { if(mMaterial->mapping[i].mapping & USEENV ) - mShader->InitializeSampler(SAMP_CUBE, i, 0, &mTextures[i]); + mShader->InitializeSampler(i, &mTextures[i]); else - mShader->InitializeSampler(SAMP_2D, i, 0, &mTextures[i]); + mShader->InitializeSampler(i, &mTextures[i]); } mModified = true; } diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index ad229509224..4dac7f294ec 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -93,6 +93,9 @@ private: unsigned int mBlendFunc[2]; bool mModified; + void ActivatGLMaterials( RAS_IRasterizer* rasty )const; + void ActivateTexGen( RAS_IRasterizer *ras ) const; + // message centers void setTexData( bool enable,RAS_IRasterizer *ras); @@ -104,7 +107,6 @@ private: void setLightData(); - void applyTexGen(RAS_IRasterizer *ras); // cleanup stuff void OnExit(); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index f6505c2965f..ebca3e13d7f 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -84,6 +84,12 @@ KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh), {NULL,NULL} //Sentinel }; +void KX_MeshProxy::SetMeshModified(bool v) +{ + m_meshobj->SetMeshModified(v); +} + + PyObject* KX_MeshProxy::_getattr(const STR_String& attr) { @@ -211,7 +217,7 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self, RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex); if (vertex) { - vertexob = new KX_VertexProxy(vertex); + vertexob = new KX_VertexProxy(this, vertex); } } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index 6aa832ea224..9a8aa2a6f33 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -43,6 +43,8 @@ public: KX_MeshProxy(class RAS_MeshObject* mesh); virtual ~KX_MeshProxy(); + void SetMeshModified(bool v); + // stuff for cvalue related things virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) ; virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index ceb5da67877..f86b984c789 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -773,6 +773,7 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook 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); + KX_MACRO_addTypesToDict(d, CONSTANT_TIMER, BL_Shader::CONSTANT_TIMER); // Check for errors if (PyErr_Occurred()) diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index b06e9ee8529..cacf3987e63 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -140,6 +140,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) if (PyVecTo(pyvalue, vec)) { m_vertex->SetXYZ(vec); + m_mesh->SetMeshModified(true); return 0; } return 1; @@ -151,6 +152,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) if (PyVecTo(pyvalue, vec)) { m_vertex->SetUV(vec); + m_mesh->SetMeshModified(true); return 0; } return 1; @@ -162,6 +164,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) if (PyVecTo(pyvalue, vec)) { m_vertex->SetRGBA(vec); + m_mesh->SetMeshModified(true); return 0; } return 1; @@ -173,6 +176,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) if (PyVecTo(pyvalue, vec)) { m_vertex->SetNormal(vec); + m_mesh->SetMeshModified(true); return 0; } return 1; @@ -188,6 +192,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { pos.x() = val; m_vertex->SetXYZ(pos); + m_mesh->SetMeshModified(true); return 0; } @@ -195,6 +200,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { pos.y() = val; m_vertex->SetXYZ(pos); + m_mesh->SetMeshModified(true); return 0; } @@ -202,6 +208,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { pos.z() = val; m_vertex->SetXYZ(pos); + m_mesh->SetMeshModified(true); return 0; } @@ -211,6 +218,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { uv[0] = val; m_vertex->SetUV(uv); + m_mesh->SetMeshModified(true); return 0; } @@ -218,6 +226,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { uv[1] = val; m_vertex->SetUV(uv); + m_mesh->SetMeshModified(true); return 0; } @@ -227,6 +236,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { uv[0] = val; m_vertex->SetUV2(uv); + m_mesh->SetMeshModified(true); return 0; } @@ -234,6 +244,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { uv[1] = val; m_vertex->SetUV2(uv); + m_mesh->SetMeshModified(true); return 0; } @@ -245,24 +256,28 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) { cp[0] = (unsigned char) val; m_vertex->SetRGBA(icol); + m_mesh->SetMeshModified(true); return 0; } if (attr == "g") { cp[1] = (unsigned char) val; m_vertex->SetRGBA(icol); + m_mesh->SetMeshModified(true); return 0; } if (attr == "b") { cp[2] = (unsigned char) val; m_vertex->SetRGBA(icol); + m_mesh->SetMeshModified(true); return 0; } if (attr == "a") { cp[3] = (unsigned char) val; m_vertex->SetRGBA(icol); + m_mesh->SetMeshModified(true); return 0; } } @@ -270,8 +285,9 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return SCA_IObject::_setattr(attr, pyvalue); } -KX_VertexProxy::KX_VertexProxy(RAS_TexVert* vertex) -:m_vertex(vertex) +KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex) +: m_vertex(vertex), + m_mesh(mesh) { } @@ -310,7 +326,7 @@ PyObject* KX_VertexProxy::PySetXYZ(PyObject*, if (PyVecArgTo(args, vec)) { m_vertex->SetXYZ(vec); - + m_mesh->SetMeshModified(true); Py_Return; } @@ -332,7 +348,7 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject*, if (PyVecArgTo(args, vec)) { m_vertex->SetNormal(vec); - + m_mesh->SetMeshModified(true); Py_Return; } @@ -356,6 +372,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject*, if (PyArg_ParseTuple(args, "(ffff)", &r, &g, &b, &a)) { m_vertex->SetRGBA(MT_Vector4(r, g, b, a)); + m_mesh->SetMeshModified(true); Py_Return; } PyErr_Clear(); @@ -364,6 +381,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject*, if (PyArg_ParseTuple(args,"i",&rgba)) { m_vertex->SetRGBA(rgba); + m_mesh->SetMeshModified(true); Py_Return; } @@ -386,7 +404,7 @@ PyObject* KX_VertexProxy::PySetUV(PyObject*, if (PyVecArgTo(args, vec)) { m_vertex->SetUV(vec); - + m_mesh->SetMeshModified(true); Py_Return; } @@ -414,10 +432,9 @@ PyObject* KX_VertexProxy::PySetUV2(PyObject*, m_vertex->SetFlag((m_vertex->getFlag()|TV_2NDUV)); m_vertex->SetUnit(unit); m_vertex->SetUV2(vec); + m_mesh->SetMeshModified(true); Py_Return; } } return NULL; } - - diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 49fa8ca88c9..acae9cf5a34 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -40,8 +40,9 @@ class KX_VertexProxy : public SCA_IObject protected: class RAS_TexVert* m_vertex; + class KX_MeshProxy* m_mesh; public: - KX_VertexProxy(class RAS_TexVert* vertex); + KX_VertexProxy(class KX_MeshProxy*mesh, class RAS_TexVert* vertex); virtual ~KX_VertexProxy(); // stuff for cvalue related things diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 7f44afec74e..66e0fe0678d 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -214,7 +214,8 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor)=0; + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot)=0; /** * @copydoc IndexPrimitives * IndexPrimitivesEx will renormalize faces if @param vertexarrays[i].getFlag() & TV_CALCFACENORMAL @@ -245,7 +246,8 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor)=0; + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot)=0; virtual void IndexPrimitivesMulti_Ex( const vecVertexArray& vertexarrays, @@ -390,9 +392,10 @@ 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 SetAttrib(int type) = 0; virtual void GetViewMatrix(MT_Matrix4x4 &mat) const = 0; + virtual bool QueryLists(){return false;} + virtual bool QueryArrays(){return false;} }; #endif //__RAS_IRASTERIZER diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 3aded0568cb..ef89477c345 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -61,9 +61,6 @@ void KX_VertexIndex::SetIndex(short loc,unsigned int index) m_indexarray[loc]=index; } - - - bool KX_MeshSlot::Less(const KX_MeshSlot& lhs) const { bool result = ((m_mesh < lhs.m_mesh ) || @@ -205,8 +202,8 @@ 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); + m_material->ActivateMeshSlot(ms, rasty); /* __NLA Do the deformation */ if (ms.m_pDeformer) @@ -222,6 +219,12 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa rendertools->PushMatrix(); rendertools->applyTransform(rasty,ms.m_OpenGLMatrix,m_material->GetDrawingMode()); + if(rasty->QueryLists()) + { + if(ms.m_DisplayList) + ms.m_DisplayList->SetModified(ms.m_mesh->MeshModified()); + } + // Use the text-specific IndexPrimitives for text faces if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT) { @@ -246,14 +249,15 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa m_material, rendertools, ms.m_bObjectColor, - ms.m_RGBAcolor + ms.m_RGBAcolor, + &ms.m_DisplayList ); } // for using glMultiTexCoord on deformer else if(m_material->GetFlag() & RAS_DEFMULTI ) { - rasty->IndexPrimitivesMulti( + rasty->IndexPrimitivesMulti_Ex( ms.m_mesh->GetVertexCache(m_material), ms.m_mesh->GetIndexCache(m_material), drawmode, @@ -287,10 +291,16 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa m_material, rendertools, // needed for textprinting on polys ms.m_bObjectColor, - ms.m_RGBAcolor + ms.m_RGBAcolor, + &ms.m_DisplayList ); } - + + if(rasty->QueryLists()) { + if(ms.m_DisplayList) + ms.m_mesh->SetMeshModified(false); + } + rendertools->PopMatrix(); } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 448cbc6e343..7d875242c2e 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -64,6 +64,17 @@ public: short m_size; }; +/** + * KX_ListSlot. + */ +class KX_ListSlot +{ +public: + KX_ListSlot(){} + virtual ~KX_ListSlot(){} + + virtual void SetModified(bool mod)=0; +}; /** * KX_MeshSlot. @@ -71,19 +82,21 @@ public: class KX_MeshSlot { public: - void* m_clientObj; + void* m_clientObj; RAS_Deformer* m_pDeformer; // __NLA - double* m_OpenGLMatrix; - class RAS_MeshObject* m_mesh; + double* m_OpenGLMatrix; + class RAS_MeshObject* m_mesh; mutable bool m_bVisible; // for visibility - mutable bool m_bObjectColor; + mutable bool m_bObjectColor; mutable MT_Vector4 m_RGBAcolor; + mutable KX_ListSlot* m_DisplayList; // for lists KX_MeshSlot() : m_pDeformer(NULL), - m_bVisible(true) + m_bVisible(true), + m_DisplayList(0) { } - ~KX_MeshSlot() {}; + ~KX_MeshSlot(){} bool Less(const KX_MeshSlot& lhs) const; }; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 54e5364bc88..360939f71e0 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -70,11 +70,17 @@ RAS_MeshObject::RAS_MeshObject(int lightlayer) : m_bModified(true), m_lightlayer(lightlayer), m_zsort(false), + m_MeshMod(true), m_class(0) { } +bool RAS_MeshObject::MeshModified() +{ + return m_MeshMod; +} + RAS_MeshObject::~RAS_MeshObject() { @@ -686,5 +692,7 @@ void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawing } m_bModified = false; + + m_MeshMod = true; } } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index d4884363731..7ca57093d90 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -132,8 +132,9 @@ class RAS_MeshObject vector<class RAS_Polygon*> m_Polygons; STR_String m_name; static STR_String s_emptyname; - bool m_zsort; - + bool m_zsort; + bool m_MeshMod; + struct polygonSlot; struct backtofront; struct fronttoback; @@ -255,6 +256,10 @@ public: const vecIndexArrays& GetIndexCache (RAS_IPolyMaterial* mat); void SetName(STR_String name); const STR_String& GetName(); + + bool MeshModified(); + void SetMeshModified(bool v){m_MeshMod = v;} + }; #endif //__RAS_MESHOBJECT diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index 58cd8dc2aa1..9e06fcda299 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -406,7 +406,7 @@ PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; #endif - +#if 0 // TODO: GL_ARB_vertex/fragment_program support #ifdef GL_ARB_vertex_program PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; @@ -421,6 +421,13 @@ PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; #endif +#endif + +#ifdef GL_EXT_compiled_vertex_array + PFNGLLOCKARRAYSEXTPROC blLockArraysEXT; + PFNGLUNLOCKARRAYSEXTPROC blUnlockArraysEXT; +#endif + } // namespace bgl @@ -605,6 +612,7 @@ static void LinkExtensions() } #endif +#if 0 // TODO: GL_ARB_vertex/fragment_program support #if defined(GL_ARB_vertex_program) if (QueryExtension("GL_ARB_vertex_program")) { @@ -629,6 +637,7 @@ static void LinkExtensions() } } #endif +#endif #ifdef GL_ARB_depth_texture @@ -643,6 +652,22 @@ static void LinkExtensions() } #endif +#ifdef GL_EXT_compiled_vertex_array + if (QueryExtension("GL_EXT_compiled_vertex_array")) + { + blLockArraysEXT = reinterpret_cast<PFNGLLOCKARRAYSEXTPROC>(bglGetProcAddress((const GLubyte *) "glLockArraysEXT")); + blUnlockArraysEXT = reinterpret_cast<PFNGLUNLOCKARRAYSEXTPROC>(bglGetProcAddress((const GLubyte *) "glUnlockArraysEXT")); + if (blLockArraysEXT && blUnlockArraysEXT) { + EnableExtension(_GL_EXT_compiled_vertex_array); + RAS_EXT_support._EXT_compiled_vertex_array = 1; + if (doDebugMessages) + std::cout << "Enabled GL_EXT_compiled_vertex_array" << std::endl; + } else { + std::cout << "ERROR: GL_EXT_compiled_vertex_array implementation is broken!" << 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 26217c1d78e..9e6df30708a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -403,7 +403,8 @@ typedef struct BL_EXTInfo _ARB_fragment_shader(0), _EXT_texture3D(0), _ARB_vertex_program(0), - _ARB_depth_texture(0) + _ARB_depth_texture(0), + _EXT_compiled_vertex_array(0) { // } @@ -417,6 +418,7 @@ typedef struct BL_EXTInfo bool _EXT_texture3D; bool _ARB_vertex_program; bool _ARB_depth_texture; + bool _EXT_compiled_vertex_array; }BL_EXTInfo; extern BL_EXTInfo RAS_EXT_support; @@ -508,6 +510,7 @@ extern PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; extern PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; #endif +#if 0 // TODO: GL_ARB_vertex/fragment_program support #ifdef GL_ARB_vertex_program extern PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; extern PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; @@ -522,7 +525,12 @@ extern PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; extern PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; extern PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; #endif +#endif +#ifdef GL_EXT_compiled_vertex_array +extern PFNGLLOCKARRAYSEXTPROC blLockArraysEXT; +extern PFNGLUNLOCKARRAYSEXTPROC blUnlockArraysEXT; +#endif } /* namespace bgl */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp new file mode 100644 index 00000000000..5f0541f8bac --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -0,0 +1,207 @@ +// +#include <iostream> + +#include "RAS_ListRasterizer.h" + +#ifdef WIN32 +#include <windows.h> +#endif // WIN32 +#ifdef __APPLE__ +#define GL_GLEXT_LEGACY 1 +#include <OpenGL/gl.h> +#else +#include <GL/gl.h> +#endif + +#include "RAS_TexVert.h" +#include "RAS_GLExtensionManager.h" +#include "MT_assert.h" + +#ifndef NDEBUG +#define spit(x) std::cout << x << std::endl; +#else +#define spit(x) +#endif + +RAS_ListSlot::RAS_ListSlot() +: KX_ListSlot(), + m_flag(LIST_MODIFY|LIST_CREATE), + m_list(0) +{ +} + +RAS_ListSlot::~RAS_ListSlot() +{ + RemoveList(); +} + + +void RAS_ListSlot::RemoveList() +{ + if(m_list != 0) { + spit("Releasing display list (" << m_list << ")"); + glDeleteLists((GLuint)m_list, 1); + m_list =0; + } +} + +void RAS_ListSlot::DrawList() +{ + if(m_flag &LIST_STREAM || m_flag& LIST_NOCREATE) { + RemoveList(); + return; + } + if(m_flag &LIST_MODIFY) { + if(m_flag &LIST_CREATE) { + if(m_list == 0) { + m_list = (unsigned int)glGenLists(1); + m_flag = m_flag &~ LIST_CREATE; + spit("Created display list (" << m_list << ")"); + } + } + if(m_list != 0) + glNewList((GLuint)m_list, GL_COMPILE_AND_EXECUTE); + + m_flag |= LIST_BEGIN; + return; + } + glCallList(m_list); +} + +void RAS_ListSlot::EndList() +{ + if(m_flag & LIST_BEGIN) { + glEndList(); + m_flag = m_flag &~(LIST_BEGIN|LIST_MODIFY); + m_flag |= LIST_END; + } +} + +void RAS_ListSlot::SetModified(bool mod) +{ + if(mod && !(m_flag & LIST_MODIFY)) { + spit("Modifying list (" << m_list << ")"); + m_flag = m_flag &~ LIST_END; + m_flag |= LIST_MODIFY; + } +} + +bool RAS_ListSlot::End() +{ + return (m_flag &LIST_END)!=0; +} + + + +RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas) +: RAS_OpenGLRasterizer(canvas) +{ + // -- +} + +RAS_ListRasterizer::~RAS_ListRasterizer() +{ + ReleaseAlloc(); +} + +RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(const vecVertexArray& vertexarrays, KX_ListSlot** slot) +{ + /* + Keep a copy of constant lists submitted for rendering, + this guards against (replicated)new...delete every frame, + and we can reuse lists! + :: sorted by vertex array + */ + RAS_ListSlot* localSlot = (RAS_ListSlot*)*slot; + if(!localSlot) { + RAS_Lists::iterator it = mLists.find(vertexarrays); + if(it == mLists.end()) { + localSlot = new RAS_ListSlot(); + mLists.insert(std::pair<vecVertexArray, RAS_ListSlot*>(vertexarrays, localSlot)); + } else { + localSlot = it->second; + } + } + MT_assert(localSlot); + return localSlot; +} + +void RAS_ListRasterizer::ReleaseAlloc() +{ + RAS_Lists::iterator it = mLists.begin(); + while(it != mLists.end()) { + delete it->second; + it++; + } + mLists.clear(); +} + + +void RAS_ListRasterizer::IndexPrimitives( + const vecVertexArray & vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot) +{ + RAS_ListSlot* localSlot =0; + + // useObjectColor(are we updating every frame?) + if(!useObjectColor) { + localSlot = FindOrAdd(vertexarrays, slot); + localSlot->DrawList(); + if(localSlot->End()) + return; + } + + RAS_OpenGLRasterizer::IndexPrimitives( + vertexarrays, indexarrays, + mode, polymat, + rendertools, useObjectColor, + rgbacolor,slot + ); + + if(!useObjectColor) { + localSlot->EndList(); + *slot = localSlot; + } +} + + +void RAS_ListRasterizer::IndexPrimitivesMulti( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot) +{ + RAS_ListSlot* localSlot =0; + + // useObjectColor(are we updating every frame?) + if(!useObjectColor) { + localSlot = FindOrAdd(vertexarrays, slot); + localSlot->DrawList(); + + if(localSlot->End()) + return; + } + + RAS_OpenGLRasterizer::IndexPrimitivesMulti( + vertexarrays, indexarrays, + mode, polymat, + rendertools, useObjectColor, + rgbacolor,slot + ); + if(!useObjectColor) { + localSlot->EndList(); + *slot = localSlot; + } +} + +// eof diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h new file mode 100644 index 00000000000..82840cd1399 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -0,0 +1,72 @@ +#ifndef __RAS_LISTRASTERIZER_H__ +#define __RAS_LISTRASTERIZER_H__ + +#include "RAS_MaterialBucket.h" +#include "RAS_OpenGLRasterizer.h" +#include <vector> + +class RAS_ListSlot : public KX_ListSlot +{ + unsigned int m_list; + unsigned int m_flag; +public: + RAS_ListSlot(); + virtual ~RAS_ListSlot(); + virtual void SetModified(bool mod); + + void RemoveList(); + void DrawList(); + void EndList(); + bool End(); + +}; + +enum RAS_ListSlotFlags { + LIST_CREATE =1, + LIST_MODIFY =2, + LIST_STREAM =4, + LIST_NOCREATE =8, + LIST_BEGIN =16, + LIST_END =32, + LIST_REGEN =64 +}; + +typedef std::map<const vecVertexArray, RAS_ListSlot*> RAS_Lists; + +class RAS_ListRasterizer : public RAS_OpenGLRasterizer +{ + RAS_Lists mLists; + + RAS_ListSlot* FindOrAdd(const vecVertexArray& vertexarrays, KX_ListSlot** slot); + void ReleaseAlloc(); + +public: + RAS_ListRasterizer(RAS_ICanvas* canvas); + virtual ~RAS_ListRasterizer(); + + virtual void IndexPrimitives( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot + ); + + virtual void IndexPrimitivesMulti( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot + ); + + virtual bool QueryLists(){return true;} +}; + +#endif diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index a576205b87c..8f7876f66a1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -81,7 +81,6 @@ 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(); @@ -619,7 +618,8 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot ) { GLenum drawmode; @@ -1201,12 +1201,6 @@ 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 @@ -1242,14 +1236,40 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled) case RAS_TEXCO_NORM: bgl::blMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal()); break; - + case RAS_TEXTANGENT: + bgl::blMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent()); } } } #endif -#ifdef GL_ARB_vertex_program - if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program) - bgl::blVertexAttrib4fvARB(1/*tangent*/, tv.getTangent()); +} +void RAS_OpenGLRasterizer::Tangent( const RAS_TexVert& v1, + const RAS_TexVert& v2, + const RAS_TexVert& v3, + const MT_Vector3 &no) +{ +#ifdef GL_ARB_multitexture + // TODO: set for deformer... + MT_Vector3 x1(v1.getLocalXYZ()), x2(v2.getLocalXYZ()), x3(v3.getLocalXYZ()); + MT_Vector2 uv1(v1.getUV1()), uv2(v2.getUV1()), uv3(v3.getUV1()); + MT_Vector3 dx1(x2 - x1), dx2(x3 - x1); + 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); + + // Gram-Schmidt orthogonalize + MT_Vector3 t(sdir - no.cross(no.cross(sdir))); + if (!MT_fuzzyZero(t)) + t /= t.length(); + + float tangent[4]; + t.getValue(tangent); + // Calculate handedness + tangent[3] = no.dot(sdir.cross(tdir)) < 0.0 ? -1.0 : 1.0; #endif } @@ -1261,7 +1281,8 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot ) { #ifdef GL_ARB_multitexture @@ -1455,14 +1476,14 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( } -void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertexarrays, +void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex( + const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, int mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor - ) + const MT_Vector4& rgbacolor) { #ifdef GL_ARB_multitexture bool recalc; @@ -1492,7 +1513,6 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex const KX_IndexArray & indexarray = (*indexarrays[vt]); numindices = indexarray.size(); const unsigned int enabled = polymat->GetEnabled(); - unsigned int unit; if (!numindices) continue; @@ -1544,72 +1564,27 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1645,18 +1620,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; @@ -1664,18 +1628,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; @@ -1683,35 +1636,15 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ - + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1748,49 +1681,19 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; } @@ -1820,51 +1723,21 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti_Ex(const vecVertexArray & vertex glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); vindex++; glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA())); if (!recalc) glNormal3fv(vertexarray[(indexarray[vindex])].getNormal()); - // ------------------------------ - for(unit =0; unit<enabled; unit++) { - if( vertexarray[(indexarray[vindex])].getFlag() & TV_2NDUV && - vertexarray[(indexarray[vindex])].getUnit() == unit ) - { - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV2()); - continue; - } - bgl::blMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, vertexarray[(indexarray[vindex])].getUV1()); - } - // ------------------------------ + TexCoord(vertexarray[(indexarray[vindex])],enabled ); 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 6b1925340b2..b00832b9738 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -89,13 +89,12 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer float m_focallength; bool m_setfocallength; int m_noOfScanlines; - TexCoGen m_texco[RAS_MAX]; - bool m_useTang; - bool InterlacedStereo() const; protected: int m_drawingmode; + TexCoGen m_texco[RAS_MAX]; + /** Stores the caching information for the last material activated. */ RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo; @@ -148,7 +147,8 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot ); virtual void IndexPrimitives_Ex( @@ -178,7 +178,8 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor); + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot); virtual void IndexPrimitivesMulti_Ex( const vecVertexArray& vertexarrays, @@ -284,9 +285,13 @@ public: 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; + void Tangent(const RAS_TexVert& v1, + const RAS_TexVert& v2, + const RAS_TexVert& v3, + const MT_Vector3 &no); + }; #endif //__RAS_OPENGLRASTERIZER diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index b6d8e74c2d5..4928627c065 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -54,8 +54,9 @@ using namespace bgl; -RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas) -:RAS_OpenGLRasterizer(canvas) +RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock) +: RAS_OpenGLRasterizer(canvas), + m_Lock(lock && RAS_EXT_support._EXT_compiled_vertex_array) { } @@ -65,8 +66,6 @@ RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() { } - - bool RAS_VAOpenGLRasterizer::Init(void) { @@ -138,7 +137,8 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor) + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot) { static const GLsizei vtxstride = sizeof(RAS_TexVert); GLenum drawmode; @@ -181,13 +181,13 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays { glColor3d(0,0,0); } + // use glDrawElements to draw each vertexarray for (vt=0;vt<vertexarrays.size();vt++) { vertexarray = &((*vertexarrays[vt]) [0]); const KX_IndexArray & indexarray = (*indexarrays[vt]); numindices = indexarray.size(); - // int numverts = vertexarrays[vt]->size(); if (!numindices) continue; @@ -196,14 +196,142 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); - //glLockArraysEXT(0,numverts); + + //if(m_Lock) + // local->Begin(vertexarrays[vt]->size()); + // here the actual drawing takes places glDrawElements(drawmode,numindices,GL_UNSIGNED_SHORT,&(indexarray[0])); - //glUnlockArraysEXT(); + + //if(m_Lock) + // local->End(); + + } } +void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot) +{ + static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; + switch (mode) + { + case 0: + { + drawmode = GL_TRIANGLES; + break; + } + case 2: + { + drawmode = GL_QUADS; + break; + } + case 1: //lines + { + } + default: + { + drawmode = GL_LINES; + break; + } + } + const RAS_TexVert* vertexarray; + unsigned int numindices, vt; + const unsigned int enabled = polymat->GetEnabled(); + + if (drawmode != GL_LINES) + { + if (useObjectColor) + { + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + } else + { + glColor4d(0,0,0,1.0); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + { + glColor3d(0,0,0); + } + + // use glDrawElements to draw each vertexarray + for (vt=0;vt<vertexarrays.size();vt++) + { + vertexarray = &((*vertexarrays[vt]) [0]); + const KX_IndexArray & indexarray = (*indexarrays[vt]); + numindices = indexarray.size(); + + if (!numindices) + continue; + + glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); + TexCoordPtr(vertexarray, enabled); + + //glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); + glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); + + //if(m_Lock) + // local->Begin(vertexarrays[vt]->size()); + + // here the actual drawing takes places + glDrawElements(drawmode,numindices,GL_UNSIGNED_SHORT,&(indexarray[0])); + + //if(m_Lock) + // local->End(); + } +} + +void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled) +{ +#ifdef GL_ARB_multitexture + if(bgl::RAS_EXT_support._ARB_multitexture) + { + for(int unit=0; unit<enabled; unit++) + { + bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+unit); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if( tv->getFlag() & TV_2NDUV && tv->getUnit() == unit ) { + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); + continue; + } + switch(m_texco[unit]) + { + case RAS_TEXCO_DISABLE: + case RAS_TEXCO_OBJECT: + case RAS_TEXCO_GEN: + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + break; + case RAS_TEXCO_ORCO: + case RAS_TEXCO_GLOB: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getLocalXYZ()); + break; + case RAS_TEXCO_UV1: + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); + break; + case RAS_TEXCO_NORM: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); + break; + case RAS_TEXTANGENT: + glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); + } + } + } +#endif +} + + void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) { if (enable) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index d0fd6006ab6..06a6fb4bb3a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -36,8 +36,11 @@ class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer { + void TexCoordPtr(const RAS_TexVert *tv, int unit); + bool m_Lock; + public: - RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas); + RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false); virtual ~RAS_VAOpenGLRasterizer(); virtual bool Init(); @@ -51,10 +54,23 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, - const MT_Vector4& rgbacolor); + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot); + + virtual void IndexPrimitivesMulti( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot); virtual void EnableTextures(bool enable); + //virtual bool QueryArrays(){return true;} + //virtual bool QueryLists(){return m_Lock;} }; |