Sorry to break the cvs-closed status, so if you really need to make a new 2.40 build...
authorErwin Coumans <blender@erwincoumans.com>
Fri, 6 Jan 2006 03:46:54 +0000 (03:46 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Fri, 6 Jan 2006 03:46:54 +0000 (03:46 +0000)
Armatures are back
Split screen
Double sided lightning
Ambient lighting
Alpha test
Material IPO support (one per object atm)
Blender materials
GLSL shaders - Python access
Up to three texture samplers from the material panel ( 2D & Cube map )
Python access to a second set of uv coordinates

See http://www.elysiun.com/forum/viewtopic.php?t=58057

69 files changed:
source/Makefile
source/blender/blenkernel/BKE_global.h
source/blender/src/header_info.c
source/blender/src/space.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_ArmatureObject.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_Material.cpp [new file with mode: 0644]
source/gameengine/Converter/BL_Material.h [new file with mode: 0644]
source/gameengine/Converter/BL_MeshDeformer.cpp
source/gameengine/Converter/BL_MeshDeformer.h
source/gameengine/Converter/BL_Shader.cpp [new file with mode: 0644]
source/gameengine/Converter/BL_Shader.h [new file with mode: 0644]
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/BL_Texture.cpp [new file with mode: 0644]
source/gameengine/Converter/BL_Texture.h [new file with mode: 0644]
source/gameengine/Converter/BlenderWorldInfo.cpp
source/gameengine/Converter/BlenderWorldInfo.h
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.h
source/gameengine/Converter/KX_IpoConvert.cpp
source/gameengine/Converter/KX_IpoConvert.h
source/gameengine/Converter/SConscript
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.h
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_BlenderMaterial.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_Camera.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_ISceneConverter.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_MaterialIpoController.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_MaterialIpoController.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_VertexProxy.cpp
source/gameengine/Ketsji/KX_VertexProxy.h
source/gameengine/Ketsji/KX_WorldInfo.h
source/gameengine/Ketsji/Makefile
source/gameengine/Ketsji/SConscript
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_CameraData.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/Rasterizer/RAS_TexVert.cpp
source/gameengine/Rasterizer/RAS_TexVert.h

index 732d7fd..f0d0323 100644 (file)
@@ -110,6 +110,8 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
+    COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
+    COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
     COMLIB += $(NAN_SOLID)/lib/libsolid.a
     COMLIB += $(NAN_SOLID)/lib/libsolid_broad.a 
     COMLIB += $(NAN_SOLID)/lib/libsolid_complex.a
index 6ecd362..c5afa9a 100644 (file)
@@ -192,6 +192,7 @@ typedef struct Global {
 #define G_FIle_PUBLISH                  (1 << 9)
 #define G_FILE_NO_UI                    (1 << 10)
 #define G_FILE_GAME_TO_IPO              (1 << 11)
+#define G_FILE_GAME_MAT                         (1 << 12)
 
 /* G.windowstate */
 #define G_WINDOWSTATE_USERDEF          0
index 8e6c04c..f5e3b5d 100644 (file)
@@ -1261,6 +1261,7 @@ static void do_info_gamemenu(void *arg, int event)
        case G_FILE_SHOW_DEBUG_PROPS:
        case G_FILE_AUTOPLAY:
        case G_FILE_GAME_TO_IPO:
+       case G_FILE_GAME_MAT:
                G.fileflags ^= event;
                break;
        default:
@@ -1295,7 +1296,12 @@ static uiBlock *info_gamemenu(void *arg_unused)
                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, "");
        }
        
-       
+       if(G.fileflags & G_FILE_GAME_MAT) {
+               uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Blender Materials",     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, "");
+       } else {
+               uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Blender Materials",   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_GAME_MAT, "");
+       }       
+
 
 
        if(G.fileflags & G_FILE_SHOW_FRAMERATE) {
@@ -1319,7 +1325,7 @@ static uiBlock *info_gamemenu(void *arg_unused)
        }
 
        uiBlockSetDirection(block, UI_DOWN);
-       uiTextBoundsBlock(block, 50);
+       uiTextBoundsBlock(block, 70);
        
        return block;
 }
index 3325d78..b1dbc61 100644 (file)
@@ -362,6 +362,9 @@ void space_set_commmandline_options(void) {
                a= (G.fileflags & G_FILE_GAME_TO_IPO);
                SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
 
+               a=(G.fileflags & G_FILE_GAME_MAT);
+               SYS_WriteCommandLineInt(syshandle, "blender_material", a);
+
 
        }
 }
index 2948c45..028dcbe 100644 (file)
@@ -48,6 +48,7 @@
 #include "KX_BlenderMouseDevice.h"
 #include "KX_BlenderRenderTools.h"
 #include "KX_BlenderSystem.h"
+#include "BL_Material.h"
 
 #include "KX_KetsjiEngine.h"
 #include "KX_BlenderSceneConverter.h"
@@ -103,7 +104,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
        strcpy (pathname, maggie->name);
        STR_String exitstring = "";
        BlendFileData *bfd= NULL;
-       
+
        bgl::InitExtensions(1);
        
        do
@@ -117,6 +118,21 @@ 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 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);
+                       int unitmax=0;
+                       glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax);
+                       bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX;
+                       //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl;
+               } else {
+                       bgl::max_texture_units = 0;
+               }
+               #endif
+
 
                // create the canvas, rasterizer and rendertools
                RAS_ICanvas* canvas = new KX_BlenderCanvas(area);
@@ -273,7 +289,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                        if (always_use_expand_framing)
                                sceneconverter->SetAlwaysUseExpandFraming(true);
                        
-                       
+                       if(usemat)
+                               sceneconverter->SetMaterials(true);
+                                       
                        KX_Scene* startscene = new KX_Scene(keyboarddevice,
                                mousedevice,
                                networkdevice,
@@ -400,7 +418,6 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                        delete canvas;
                        canvas = NULL;
                }
-               
                SND_DeviceManager::Unsubscribe();
        
        } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
index e35ec6f..a100c3a 100644 (file)
@@ -53,6 +53,8 @@
 
 #include "KX_BlenderPolyMaterial.h"
 #include "KX_PolygonMaterial.h"
+#include "KX_BlenderMaterial.h"
+
 #include "Value.h"
 
 #include "KX_BlenderGL.h" // for text printing
@@ -256,8 +258,16 @@ void       KX_BlenderRenderTools::RenderText(int mode,RAS_IPolyMaterial* polymat,float
                
        STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
        
-       KX_PolygonMaterial* blenderpoly = static_cast<KX_PolygonMaterial*>(polymat);
-       struct TFace* tface = blenderpoly->GetTFace();
+       const unsigned int flag = polymat->GetFlag();
+       struct TFace* tface = 0;
+
+       if(flag & RAS_BLENDERMAT) {
+               KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(polymat);
+               tface = bl_mat->GetTFace();
+       } else {
+               KX_PolygonMaterial* blenderpoly = static_cast<KX_PolygonMaterial*>(polymat);
+               tface = blenderpoly->GetTFace();
+       }
        
        BL_RenderText( mode,mytext,mytext.Length(),tface,v1,v2,v3,v4);
        
@@ -288,8 +298,8 @@ void KX_BlenderRenderTools::EnableOpenGLLights()
        glEnable(GL_LIGHTING);
        
        glEnable(GL_COLOR_MATERIAL);
-       glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
-       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, false);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
        if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
                glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
 
index f0c58f1..7497f10 100644 (file)
 #include <config.h>
 #endif
 
+
+BL_ArmatureObject::BL_ArmatureObject(
+                               void* sgReplicationInfo, 
+                               SG_Callbacks callbacks, 
+                               Object *armature )
+
+:      KX_GameObject(sgReplicationInfo,callbacks),
+       m_objArma(armature),
+       m_mrdPose(NULL),
+       m_lastframe(0.),
+       m_activeAct(NULL),
+       m_activePriority(999)
+{
+       m_armature = get_armature(m_objArma);
+       m_pose = m_objArma->pose;
+}
+
+
 CValue* BL_ArmatureObject::GetReplica()
 {
        BL_ArmatureObject* replica = new BL_ArmatureObject(*this);
@@ -78,10 +96,14 @@ BL_ArmatureObject::~BL_ArmatureObject()
 void BL_ArmatureObject::ApplyPose()
 {
        if (m_pose){
-               if (!m_mrdPose)
-                       copy_pose (&m_mrdPose, m_pose, 0);
-               else
-                       extract_pose_from_pose(m_mrdPose, m_pose);
+               // copy to armature object
+               extract_pose_from_pose(m_objArma->pose, m_pose);
+               
+               // is this needed anymore?
+               //if (!m_mrdPose)
+               //      copy_pose (&m_mrdPose, m_pose, 0);
+               //else
+               //      extract_pose_from_pose(m_mrdPose, m_pose);
        }
 }
 
@@ -136,14 +158,15 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose)
        /* If the caller supplies a null pose, create a new one. */
        /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
 
-       if (!m_mrdPose){
-               copy_pose (&m_mrdPose, m_pose, 0);
-       }
+       // is this needed anymore?
+       //if (!m_mrdPose){
+       //      copy_pose (&m_mrdPose, m_pose, 0);
+       //}
 
        if (!*pose)
-               copy_pose(pose, m_mrdPose, 0);
+               copy_pose(pose, m_objArma->pose, 0);
        else
-               extract_pose_from_pose(*pose, m_mrdPose);
+               extract_pose_from_pose(*pose, m_objArma->pose);
 
 }
 
@@ -171,7 +194,5 @@ bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) const
 
 float BL_ArmatureObject::GetBoneLength(Bone* bone) const
 {
-       return (MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
+       return (float)(MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
 }
-
-
index 7244d08..af0212d 100644 (file)
@@ -39,9 +39,9 @@
 
 struct bArmature;
 struct Bone;
-
 class BL_ActionActuator;
 class MT_Matrix4x4;
+struct Object;
 
 class BL_ArmatureObject : public KX_GameObject  
 {
@@ -50,30 +50,26 @@ public:
        short GetActivePriority();
        virtual void ProcessReplica(BL_ArmatureObject *replica);
        class BL_ActionActuator * GetActiveAction();
-       BL_ArmatureObject(void* sgReplicationInfo, SG_Callbacks callbacks,
-               bArmature *armature,
-               struct bPose *pose) :
-       KX_GameObject(sgReplicationInfo,callbacks),
-               m_armature(armature),
-               m_pose(pose),
-               m_mrdPose(NULL),
-               m_lastframe(0.),
-               m_activeAct(NULL),
-               m_activePriority(999)
-       {}
+       
+       BL_ArmatureObject(
+               void* sgReplicationInfo,
+               SG_Callbacks callbacks,
+               Object *armature
+       );
+       virtual ~BL_ArmatureObject();
 
-       virtual CValue*         GetReplica();
-       virtual                         ~BL_ArmatureObject();
-       void GetMRDPose(bPose **pose);
-       void    GetPose(struct bPose **pose);
+       virtual CValue* GetReplica();
+       void GetMRDPose(struct bPose **pose);
+       void GetPose(struct bPose **pose);
        void SetPose (struct bPose *pose);
        void ApplyPose();
        bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
        
        struct bArmature * GetArmature() { return m_armature; }
-       
        const struct bArmature * GetArmature() const { return m_armature; }
        
+       Object* GetArmatureObject() {return m_objArma;}
+
        /// Retrieve the pose matrix for the specified bone.
        /// Returns true on success.
        bool GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) const;
@@ -82,6 +78,7 @@ public:
        float GetBoneLength(Bone* bone) const;
 
 protected:
+       Object                          *m_objArma;
        struct bArmature        *m_armature;
        struct bPose            *m_pose;
        struct bPose            *m_mrdPose;
index fe0cf28..368fe6f 100644 (file)
@@ -83,6 +83,9 @@
 #include "RAS_TexVert.h"
 #include "RAS_BucketManager.h"
 #include "RAS_IRenderTools.h"
+#include "BL_Material.h"
+#include "KX_BlenderMaterial.h"
+#include "BL_Texture.h"
 
 #include "DNA_action_types.h"
 #include "BKE_main.h"
 /* This list includes only data type definitions */
 #include "DNA_object_types.h"
 #include "DNA_material_types.h"
+#include "DNA_texture_types.h"
 #include "DNA_image_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_group_types.h"
@@ -217,6 +221,339 @@ static void SetDefaultFaceType(Scene* scene)
        }
 }
 
+
+// --
+static void GetRGB(short type,
+       MFace* mface,
+       MCol* mmcol,
+       Material *mat,
+       TFace *tface,
+       unsigned int &c0, 
+       unsigned int &c1, 
+       unsigned int &c2, 
+       unsigned int &c3)
+{
+       unsigned int colour = 0xFFFFFFFFL;
+       switch(type)
+       {
+               case 0: // vertex colors?
+               {
+                       if(mmcol) {
+                               c0 = KX_Mcol2uint_new(mmcol[0]);
+                               c1 = KX_Mcol2uint_new(mmcol[1]);
+                               c2 = KX_Mcol2uint_new(mmcol[2]);
+                               if (mface->v4)
+                                       c3 = KX_Mcol2uint_new(mmcol[3]);
+                               mmcol += 4;
+                       }else // backup white
+                       {
+                               c0 = KX_rgbaint2uint_new(colour);
+                               c1 = KX_rgbaint2uint_new(colour);
+                               c2 = KX_rgbaint2uint_new(colour);       
+                               if (mface->v4)
+                                       c3 = KX_rgbaint2uint_new( colour );
+                       }
+               } break;
+               
+       
+               case 1: // material rgba
+               {
+                       if (mat) {
+                               union {
+                                       unsigned char cp[4];
+                                       unsigned int integer;
+                               } col_converter;
+                               col_converter.cp[3] = (unsigned char) (mat->r*255.0);
+                               col_converter.cp[2] = (unsigned char) (mat->g*255.0);
+                               col_converter.cp[1] = (unsigned char) (mat->b*255.0);
+                               col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
+                               colour = col_converter.integer;
+                       }
+                       c0 = KX_rgbaint2uint_new(colour);
+                       c1 = KX_rgbaint2uint_new(colour);
+                       c2 = KX_rgbaint2uint_new(colour);       
+                       if (mface->v4)
+                               c3 = KX_rgbaint2uint_new(colour);
+               } break;
+               
+               case 2: // vertex colors
+               {
+                       if(tface ) {
+                               c0 = KX_rgbaint2uint_new(tface->col[0]);
+                               c1 = KX_rgbaint2uint_new(tface->col[1]);
+                               c2 = KX_rgbaint2uint_new(tface->col[2]);
+                       
+                               if (mface->v4) {
+                                       c3 = KX_rgbaint2uint_new(tface->col[3]);
+                               }
+                       }else {
+                               c0 = KX_rgbaint2uint_new(colour);
+                               c1 = KX_rgbaint2uint_new(colour);
+                               c2 = KX_rgbaint2uint_new(colour);       
+                               if (mface->v4)
+                                       c3 = KX_rgbaint2uint_new( colour );
+                       }
+               } break;
+               
+               case 3: // white
+               {
+                       c0 = KX_rgbaint2uint_new(colour);
+                       c1 = KX_rgbaint2uint_new(colour);
+                       c2 = KX_rgbaint2uint_new(colour);       
+                       if (mface->v4)
+                               c3 = KX_rgbaint2uint_new(colour);
+               } break;
+       }
+}
+
+// ------------------------------------
+BL_Material* ConvertMaterial(  Mesh* mesh, Material *mat, TFace* tface,  MFace* mface, MCol* mmcol, int lightlayer, Object* blenderobj )
+{
+       BL_Material *material = new BL_Material();
+       //initBL_Material(material);
+       int numchan =   -1;
+       bool validmat   = (mat!=0);
+       bool using_facetexture = false;
+
+       short type = 0;
+       if( validmat )
+               type = 1; // material color 
+       else if(mesh->tface && tface)
+               type = 2; // vertex colors
+       
+       material->IdMode = DEFAULT_BLENDER;
+
+       // --------------------------------
+       if(validmat) {
+
+               // use vertex colors by explicitly setting
+               if(mat->mode &MA_VERTEXCOLP) 
+                       type = 2;
+
+               // use lighting?
+               material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
+               MTex *mttmp = 0;
+               numchan = getNumTexChannels(mat);
+               int valid_index = 0;
+               
+               bool facetex = ((mat->mode & MA_FACETEXTURE) &&  (mesh->tface && tface) );
+               
+               numchan = numchan>MAXTEX?MAXTEX:(numchan>=0&& facetex)?numchan+1:numchan;
+               
+               // foreach MTex
+               for(int i=0; i<numchan; i++) {
+                       // use face tex
+                       if(i==0 && facetex ) {
+                               Image*tmp = (Image*)(tface->tpage);
+                               if(tmp) {
+                                       material->img[i] = tmp;
+                                       material->texname[i] = material->img[i]->id.name;
+                                       material->flag[i] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
+                                       material->flag[i] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
+                                       material->ras_mode|= ( tface->transp  &(TF_ADD | TF_ALPHA))?TRANSP:0;
+                                       material->mapping[i].mapping |= ( (material->img[i]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
+                                       material->blend_mode[i] = BLEND_MUL;
+                                       i++;// skip to the next image
+                                       valid_index++;
+                               }
+                       }
+
+                       mttmp = getImageFromMaterial( mat, i );
+                       if( mttmp ) {
+                               if( mttmp->tex ) {
+                                       if( mttmp->tex->type == TEX_IMAGE ) {
+                                               material->mtexname[i] = mttmp->tex->id.name;
+                                               material->img[i] = mttmp->tex->ima;
+                                               if( material->img[i] ) {
+
+                                                       material->texname[i] = material->img[i]->id.name;
+                                                       material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
+                                                       // -----------------------
+                                                       if( mttmp->tex->imaflag &TEX_USEALPHA ) {
+                                                               material->flag[i]       |= USEALPHA;
+                                                               material->ras_mode      |= TRANSP;
+                                                       }
+                                                       // -----------------------
+                                                       else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
+                                                               material->flag[i]       |= CALCALPHA;
+                                                               material->ras_mode      |= TRANSP;
+                                                       }
+
+                                                       material->color_blend[i] = mttmp->colfac;
+                                                       material->flag[i] |= ( mttmp->mapto  & MAP_ALPHA                )?TEXALPHA:0;
+                                                       material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE    )?TEXNEG:0;
+
+                                               }
+                                       }
+                                       else if(mttmp->tex->type == TEX_ENVMAP) {
+                                               if( mttmp->tex->env->stype == ENV_LOAD ) {
+                                       
+                                                       material->mtexname[i]= mttmp->tex->id.name;
+                                                       material->cubemap[i] = mttmp->tex->env;
+                                                       if(material->cubemap[i]->ima) {
+                                                               material->texname[i] = material->cubemap[i]->ima->id.name;
+                                                               material->mapping[i].mapping |= USEENV;
+                                                       }
+                                                       else {
+                                                               // in the player, we need to split it our self
+                                                               material->cubemap[i]->ima = mttmp->tex->ima;
+                                                               if(material->cubemap[i]->ima) {
+                                                                       material->texname[i] = material->cubemap[i]->ima->id.name;
+                                                                       material->mapping[i].mapping |= USEENV;
+                                                               }
+                                                               //
+                                                       }
+                                               }
+                                       }
+                                       material->flag[i] |= (mat->ipo!=0)?HASIPO:0;
+                                       /// --------------------------------
+                                       // mapping methods
+                                       material->mapping[i].mapping |= ( mttmp->texco  & TEXCO_REFL    )?USEREFL:0;
+                                       
+                                       if(mttmp->texco & TEXCO_OBJECT) {
+                                               material->mapping[i].mapping |= USEOBJ;
+                                               if(mttmp->object)
+                                                       material->mapping[i].objconame = mttmp->object->id.name;
+                                       }
+                                       
+                                       material->mapping[i].scale[0] = mttmp->size[0];
+                                       material->mapping[i].scale[1] = mttmp->size[1];
+                                       material->mapping[i].scale[2] = mttmp->size[2];
+                                       material->mapping[i].offsets[0] = mttmp->ofs[0];
+                                       material->mapping[i].offsets[1] = mttmp->ofs[1];
+                                       material->mapping[i].offsets[2] = mttmp->ofs[2];
+
+                                       material->mapping[i].projplane[0] = mttmp->projx;
+                                       material->mapping[i].projplane[1] = mttmp->projy;
+                                       material->mapping[i].projplane[2] = mttmp->projz;
+                                       /// --------------------------------
+                                       
+                                       switch( mttmp->blendtype ) {
+                                       case MTEX_BLEND:
+                                               material->blend_mode[i] = BLEND_MIX;
+                                               break;
+                                       case MTEX_MUL:
+                                               material->blend_mode[i] = BLEND_MUL;
+                                               break;
+                                       case MTEX_ADD:
+                                               material->blend_mode[i] = BLEND_ADD;
+                                               break;
+                                       case MTEX_SUB:
+                                               material->blend_mode[i] = BLEND_SUB;
+                                               break;
+                                       case MTEX_SCREEN:
+                                               material->blend_mode[i] = BLEND_SCR;
+                                               break;
+                                       }
+                                       valid_index++;
+                               }
+                       }
+               }
+               // above one tex the switches here
+               // are not used
+               switch(valid_index) {
+               case 0:
+                       material->IdMode = DEFAULT_BLENDER;
+                       break;
+               case 1:
+                       material->IdMode = ONETEX;
+                       break;
+               default:
+                       material->IdMode = GREATERTHAN2;
+                       break;
+               }
+
+               material->num_enabled = valid_index;
+
+               material->speccolor[0]  = mat->specr;
+               material->speccolor[1]  = mat->specg;
+               material->speccolor[2]  = mat->specb;
+               material->hard                  = (float)mat->har/4.0f;
+               material->matcolor[0]   = mat->r;
+               material->matcolor[1]   = mat->g;
+               material->matcolor[2]   = mat->b;
+               material->matcolor[3]   = mat->alpha;
+               material->alpha                 = mat->alpha;
+               material->emit                  = mat->emit;
+               material->spec_f                = mat->spec;
+               material->ref                   = mat->ref;
+               material->amb                   = mat->amb;
+               material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0;
+       }
+       else {
+               int valid = 0;
+               // check for tface tex to fallback on
+               if( mesh->tface && tface ){
+                       material->img[0] = (Image*)(tface->tpage);
+                       // ------------------------
+                       if(material->img[0]) {
+                               material->texname[0] = material->img[0]->id.name;
+                               material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
+                               material->flag[0] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
+                               material->flag[0] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
+                               material->ras_mode|= ( tface->transp  & (TF_ADD|TF_ALPHA))?TRANSP:0;
+                               valid++;
+                       }
+               }
+               material->num_enabled   = valid;
+               material->IdMode                = TEXFACE;
+               material->speccolor[0]  = 1.f;
+               material->speccolor[1]  = 1.f;
+               material->speccolor[2]  = 1.f;
+               material->hard                  = 35.f;
+               material->matcolor[0]   = 0.5f;
+               material->matcolor[1]   = 0.5f;
+               material->matcolor[2]   = 0.5f;
+               material->spec_f                = 0.5f;
+               material->ref                   = 0.8f;
+       }
+       MT_Point2 uv[4];
+
+       if( mesh->tface &&  tface ) {
+
+               material->ras_mode |= !( 
+                       (tface->flag & TF_HIDE) ||
+                       (tface->mode & TF_INVISIBLE)
+                       )?POLY_VIS:0;
+
+               material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0;
+               material->transp = tface->transp;
+               
+               if(tface->transp)
+                       material->ras_mode |= TRANSP;
+
+               material->tile  = tface->tile;
+               material->mode  = tface->mode;
+                       
+               uv[0]   = MT_Point2(tface->uv[0]);
+               uv[1]   = MT_Point2(tface->uv[1]);
+               uv[2]   = MT_Point2(tface->uv[2]);
+
+               if (mface->v4) 
+                       uv[3]   = MT_Point2(tface->uv[3]);
+       } 
+       else {
+               // nothing at all
+               material->ras_mode |= (COLLIDER|POLY_VIS| (validmat?0:USE_LIGHT));
+               material->mode          = default_face_mode;    
+               material->transp        = TF_SOLID;
+               material->tile          = 0;
+       }
+       unsigned int rgb[4];
+       GetRGB(type,mface,mmcol,mat,tface,rgb[0],rgb[1],rgb[2], rgb[3]);
+       material->SetConversionRGB(rgb);
+       material->SetConversionUV(uv);
+
+       material->ras_mode |= (mface->v4==0)?TRIANGLE:0;
+       if(validmat)
+               material->matname       =(mat->id.name);
+
+       material->tface         = tface;
+       material->material      = mat;
+       return material;
+}
+
+
 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
 {
        RAS_MeshObject *meshobj;
@@ -283,127 +620,163 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                        }
                
                        {
-                               Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
-       
-                               STR_String imastr = 
-                                       ((mesh->tface && tface) ? 
-                                       (bima? (bima)->id.name : "" ) : "" );
-               
-                               char transp=0;
-                               short mode=0, tile=0;
-                               int     tilexrep=4,tileyrep = 4;
-                               
-                               if (bima)
-                               {
-                                       tilexrep = bima->xrep;
-                                       tileyrep = bima->yrep;
-                       
-                               }
-       
-                               Material* ma = give_current_material(blenderobj, 1 /* mface->mat_nr */);
-                               //const char* matnameptr = (ma ? ma->id.name : ""); /*unused*/
-                               
+                               Material* ma = 0;
                                bool polyvisible = true;
-                               if (mesh->tface && tface)
-                               {
-                                       // Use texface colors if available
-                                       //TF_DYNAMIC means the polygon is a collision face
-                                       collider = (tface->mode & TF_DYNAMIC != 0);
-                                       transp = tface->transp;
-                                       tile = tface->tile;
-                                       mode = tface->mode;
+                               RAS_IPolyMaterial* polymat = NULL;
+
+                               if(converter->GetMaterials()) 
+                               {       
+                                       if(mesh->totcol > 1)
+                                               ma = mesh->mat[mface->mat_nr];
+                                       else 
+                                               ma = give_current_material(blenderobj, 1);
+
+                                       BL_Material *bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj);
+                                       // set the index were dealing with
+                                       bl_mat->material_index =  (int)mface->mat_nr;
+
+                                       polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
+                                       collider = ((bl_mat->ras_mode & COLLIDER)!=0);
                                        
-                                       polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
+                                       polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
+                                       converter->RegisterBlenderMaterial(bl_mat);
                                        
-                                       uv0 = MT_Point2(tface->uv[0]);
-                                       uv1 = MT_Point2(tface->uv[1]);
-                                       uv2 = MT_Point2(tface->uv[2]);
-                                       rgb0 = KX_rgbaint2uint_new(tface->col[0]);
-                                       rgb1 = KX_rgbaint2uint_new(tface->col[1]);
-                                       rgb2 = KX_rgbaint2uint_new(tface->col[2]);
-       
-                                       if (mface->v4)
-                                       {
-                                               uv3 = MT_Point2(tface->uv[3]);
-                                               rgb3 = KX_rgbaint2uint_new(tface->col[3]);
-                                       } 
-                               } 
+                                       unsigned int rgb[4];
+                                       bl_mat->GetConversionRGB(rgb);
+                                       rgb0 = rgb[0];
+                                       rgb1 = rgb[1];
+                                       rgb2 = rgb[2];
+                                       rgb3 = rgb[3];
+                                       MT_Point2 uv[4];
+                                       bl_mat->GetConversionUV(uv);
+                                       uv0 = uv[0];
+                                       uv1 = uv[1];
+                                       uv2 = uv[2];
+                                       uv3 = uv[3];
+                                       // this is needed to free up memory afterwards
+                                       converter->RegisterPolyMaterial(polymat);
+                               }
                                else
                                {
-                                       //
-                                       if (mmcol)
+                                       ma = give_current_material(blenderobj, 1);
+
+                                       Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
+               
+                                       STR_String imastr = 
+                                               ((mesh->tface && tface) ? 
+                                               (bima? (bima)->id.name : "" ) : "" );
+                       
+                                       char transp=0;
+                                       short mode=0, tile=0;
+                                       int     tilexrep=4,tileyrep = 4;
+                                       
+                                       if (bima)
+                                       {
+                                               tilexrep = bima->xrep;
+                                               tileyrep = bima->yrep;
+                               
+                                       }
+
+                                       if (mesh->tface && tface)
                                        {
-                                               // Use vertex colours
-                                               rgb0 = KX_Mcol2uint_new(mmcol[0]);
-                                               rgb1 = KX_Mcol2uint_new(mmcol[1]);
-                                               rgb2 = KX_Mcol2uint_new(mmcol[2]);
+                                               // Use texface colors if available
+                                               //TF_DYNAMIC means the polygon is a collision face
+                                               collider = ((tface->mode & TF_DYNAMIC) != 0);
+                                               transp = tface->transp;
+                                               tile = tface->tile;
+                                               mode = tface->mode;
                                                
+                                               polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
                                                
+                                               uv0 = MT_Point2(tface->uv[0]);
+                                               uv1 = MT_Point2(tface->uv[1]);
+                                               uv2 = MT_Point2(tface->uv[2]);
+                                               rgb0 = KX_rgbaint2uint_new(tface->col[0]);
+                                               rgb1 = KX_rgbaint2uint_new(tface->col[1]);
+                                               rgb2 = KX_rgbaint2uint_new(tface->col[2]);
+               
                                                if (mface->v4)
                                                {
-                                                       rgb3 = KX_Mcol2uint_new(mmcol[3]);
-                                                       
-                                               }
-                                       
-                                               mmcol += 4;
-                                       }
+                                                       uv3 = MT_Point2(tface->uv[3]);
+                                                       rgb3 = KX_rgbaint2uint_new(tface->col[3]);
+                                               } 
+                                       } 
                                        else
                                        {
-                                               // If there are no vertex colors OR texfaces,
-                                               // Initialize face to white and set COLLSION true and everything else FALSE
-                                               unsigned int colour = 0xFFFFFFFFL;
-                                               mode = default_face_mode;       
-                                               transp = TF_SOLID;
-                                               tile = 0;
-                                               if (ma)
+                                               //
+                                               if (mmcol)
                                                {
-                                                       // If we have a material, take the default colour from the material.
-                                                       union
+                                                       // Use vertex colours
+                                                       rgb0 = KX_Mcol2uint_new(mmcol[0]);
+                                                       rgb1 = KX_Mcol2uint_new(mmcol[1]);
+                                                       rgb2 = KX_Mcol2uint_new(mmcol[2]);
+                                                       
+                                                       
+                                                       if (mface->v4)
                                                        {
-                                                               unsigned char cp[4];
-                                                               unsigned int integer;
-                                                       } col_converter;
+                                                               rgb3 = KX_Mcol2uint_new(mmcol[3]);
+                                                               
+                                                       }
+                                               
+                                                       mmcol += 4;
+                                               }
+                                               else
+                                               {
+                                                       // If there are no vertex colors OR texfaces,
+                                                       // Initialize face to white and set COLLSION true and everything else FALSE
+                                                       unsigned int colour = 0xFFFFFFFFL;
+                                                       mode = default_face_mode;       
+                                                       transp = TF_SOLID;
+                                                       tile = 0;
+                                                       if (ma)
+                                                       {
+                                                               // If we have a material, take the default colour from the material.
+                                                               union
+                                                               {
+                                                                       unsigned char cp[4];
+                                                                       unsigned int integer;
+                                                               } col_converter;
+                                                               
+                                                               col_converter.cp[3] = (unsigned char) (ma->r*255.0);
+                                                               col_converter.cp[2] = (unsigned char) (ma->g*255.0);
+                                                               col_converter.cp[1] = (unsigned char) (ma->b*255.0);
+                                                               col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
+                                                               
+                                                               colour = col_converter.integer;
+                                                       }
                                                        
-                                                       col_converter.cp[3] = (unsigned char) (ma->r*255.0);
-                                                       col_converter.cp[2] = (unsigned char) (ma->g*255.0);
-                                                       col_converter.cp[1] = (unsigned char) (ma->b*255.0);
-                                                       col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
+                                                       rgb0 = KX_rgbaint2uint_new(colour);
+                                                       rgb1 = KX_rgbaint2uint_new(colour);
+                                                       rgb2 = KX_rgbaint2uint_new(colour);     
                                                        
-                                                       colour = col_converter.integer;
+                                                       if (mface->v4)
+                                                               rgb3 = KX_rgbaint2uint_new(colour);
                                                }
-                                               
-                                               rgb0 = KX_rgbaint2uint_new(colour);
-                                               rgb1 = KX_rgbaint2uint_new(colour);
-                                               rgb2 = KX_rgbaint2uint_new(colour);     
-                                               
-                                               if (mface->v4)
-                                                       rgb3 = KX_rgbaint2uint_new(colour);
                                        }
-                               }
+                                               
                                        
-                               
-                               bool istriangle = (mface->v4==0);
-                               bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
-                               
-                               RAS_IPolyMaterial* polymat = new KX_PolygonMaterial(imastr, ma,
-                                       tile, tilexrep, tileyrep, 
-                                       mode, transp, zsort, lightlayer, istriangle, blenderobj, tface);
-       
-                               if (ma)
-                               {
-                                       polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
-                                       polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
-                                       polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+                                       bool istriangle = (mface->v4==0);
+                                       bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
+                                       
+                                       polymat = new KX_PolygonMaterial(imastr, ma,
+                                               tile, tilexrep, tileyrep, 
+                                               mode, transp, zsort, lightlayer, istriangle, blenderobj, tface);
+               
+                                       if (ma)
+                                       {
+                                               polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+                                               polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
+                                               polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
 
-                               } else
-                               {
-                                       polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
-                                       polymat->m_shininess = 35.0;
-                               }
+                                       } else
+                                       {
+                                               polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
+                                               polymat->m_shininess = 35.0;
+                                       }
+                                       // this is needed to free up memory afterwards
+                                       converter->RegisterPolyMaterial(polymat);
 
-                       
-                               // this is needed to free up memory afterwards
-                               converter->RegisterPolyMaterial(polymat);
+                               }
        
                                RAS_MaterialBucket* bucket = scene->FindBucket(polymat);
                                                         
@@ -466,7 +839,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                        tface++;
        }
        meshobj->UpdateMaterialList();
-       
+
+
+
+       // -----------------------------------
+       // pre calculate texture generation
+       for(int matid=0; matid<meshobj->NumMaterials(); matid++)
+               meshobj->GetMaterialBucket(matid)->GetPolyMaterial()->OnConstruction();
+       // -----------------------------------
+
+
        return meshobj;
 }
 
@@ -961,11 +1343,11 @@ static KX_GameObject *gameobject_from_blenderobject(
        
                //      If this is a skin object, make Skin Controller
                if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
-                       BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj,ob->parent);                               
+                       BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj );                         
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
                }
                else if (((Mesh*)ob->data)->dvert){
-                       BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj,ob->parent);
+                       BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj );
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
                }
                
@@ -980,10 +1362,11 @@ static KX_GameObject *gameobject_from_blenderobject(
        
        case OB_ARMATURE:
        {
-               gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
-                       get_armature(ob),
-                       ob->pose);
-       
+               gameobj = new BL_ArmatureObject(
+                       kxscene,
+                       KX_Scene::m_callbacks,
+                       ob // handle
+               );
                /* Get the current pose from the armature object and apply it as the rest pose */
                break;
        }
@@ -1018,6 +1401,7 @@ static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scen
        return (Scene*) maggie->scene.first;
 }
 
+
 // convert blender objects into ketsji gameobjects
 void BL_ConvertBlenderObjects(struct Main* maggie,
                                                          const STR_String& scenename,
@@ -1103,7 +1487,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        {
                logicmgr->RegisterActionName(curAct->id.name, curAct);
        }
-       
+
        SetDefaultFaceType(blenderscene);
        
        Base *base = static_cast<Base*>(blenderscene->base.first);
@@ -1141,6 +1525,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                        gameobj->NodeUpdateGS(0,true);
                        
                        BL_ConvertIpos(blenderobject,gameobj,converter);
+                       // TODO: expand to multiple ipos per mesh
+                       Material *mat = give_current_material(blenderobject, 1);
+                       if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);        
        
                        bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
        
diff --git a/source/gameengine/Converter/BL_Material.cpp b/source/gameengine/Converter/BL_Material.cpp
new file mode 100644 (file)
index 0000000..fd4f0f1
--- /dev/null
@@ -0,0 +1,131 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include <iostream>
+
+#include "BL_Material.h"
+#include "MT_assert.h"
+
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+MTex* getImageFromMaterial(Material *mat, int index)
+{
+       if(!mat) return 0;
+       
+       if(!(index >=0 && index <=10) ) return 0;
+       
+       MTex *m = mat->mtex[index];
+       return m?m:0;
+}
+
+int getNumTexChannels( Material *mat )
+{
+       int count = -1;
+       if(!mat) return -1;
+
+       for(count =0; (count < 10) && mat->mtex[count] != 0; count++) {}
+       return count;
+}
+
+BL_Material::BL_Material()
+{
+       rgb[0] = 0;
+       rgb[1] = 0;
+       rgb[2] = 0;
+       rgb[3] = 0;
+       IdMode = 0;
+       ras_mode = 0;
+       tile = 0;
+       matname = "NoMaterial";
+       matcolor[0] = 0.5f;
+       matcolor[1] = 0.5f;
+       matcolor[2] = 0.5f;
+       matcolor[3] = 0.5f;
+       speccolor[0] = 1.f;
+       speccolor[1] = 1.f;
+       speccolor[2] = 1.f;
+       transp = 0;
+       hard = 50.f;
+       spec_f = 0.5f;
+       alpha = 1.f;
+       emit = 0.f;
+       mode = 0;
+       material = 0;
+       tface = 0;
+       material_index = 0;
+       amb=0.5f;
+       num_enabled = 0;
+
+       int i;
+       for(i=0; i<4; i++)
+               uv[i] = MT_Point2(0.f,1.f);
+
+       for(i=0; i<MAXTEX; i++) // :(
+       {
+               mapping[i].mapping = 0;
+               mapping[i].offsets[0] = 0.f;
+               mapping[i].offsets[1] = 0.f;
+               mapping[i].offsets[2] = 0.f;
+               mapping[i].scale[0]   = 1.f;
+               mapping[i].scale[1]   = 1.f;
+               mapping[i].scale[2]   = 1.f;
+               mapping[i].projplane[0] = PROJX;
+               mapping[i].projplane[1] = PROJY;
+               mapping[i].projplane[2] = PROJZ;
+               mapping[i].objconame = "";
+               mtexname[i] = "NULL";
+               imageId[i]="NULL";
+               flag[i] = 0;
+               texname[i] = "NULL";
+               tilexrep[i] = 1;
+               tileyrep[i] = 1;
+               color_blend[i] = 1.f;
+               blend_mode[i]   = 0;
+               img[i] = 0;
+               cubemap[i] = 0;
+       }
+}
+
+void BL_Material::SetConversionRGB(unsigned int *nrgb) {
+       rgb[0]=*nrgb++;
+       rgb[1]=*nrgb++;
+       rgb[2]=*nrgb++;
+       rgb[3]=*nrgb;
+}
+
+void BL_Material::GetConversionRGB(unsigned int *nrgb) {
+       *nrgb++ = rgb[0];
+       *nrgb++ = rgb[1];
+       *nrgb++ = rgb[2];
+       *nrgb   = rgb[3];
+}
+
+void BL_Material::SetConversionUV(MT_Point2 *nuv) {
+       uv[0] = *nuv++;
+       uv[1] = *nuv++;
+       uv[2] = *nuv++;
+       uv[3] = *nuv;
+}
+
+void BL_Material::GetConversionUV(MT_Point2 *nuv){
+       *nuv++ = uv[0];
+       *nuv++ = uv[1];
+       *nuv++ = uv[2];
+       *nuv   = uv[3];
+}
+
+
diff --git a/source/gameengine/Converter/BL_Material.h b/source/gameengine/Converter/BL_Material.h
new file mode 100644 (file)
index 0000000..a55756a
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef __BL_MATERIAL_H__
+#define __BL_MATERIAL_H__
+
+#include "STR_String.h"
+#include "MT_Point2.h"
+
+// --
+struct MTex;
+struct Material;
+struct Image;
+struct TFace;
+struct MTex;
+struct Material;
+struct EnvMap;
+// --
+
+/** max units
+       this will default to users available units
+       to build with more available, just increment this value
+       although the more you add the slower the search time will be.
+       we will go for three, which should be enough
+*/
+#define MAXTEX                 3//match in RAS_TexVert
+
+// different mapping modes
+class BL_Mapping
+{
+public:
+       int mapping;
+       float scale[3];
+       float offsets[3];
+       int projplane[3];
+       STR_String objconame;
+};
+
+// base material struct
+class BL_Material
+{
+private:
+       unsigned int rgb[4];
+       MT_Point2 uv[4];
+public:
+       // -----------------------------------
+       BL_Material();
+
+       int IdMode;
+       unsigned int ras_mode;
+
+       STR_String texname[MAXTEX];
+       unsigned int flag[MAXTEX];
+       int tile,tilexrep[MAXTEX],tileyrep[MAXTEX];
+       STR_String matname;
+       STR_String mtexname[MAXTEX];
+
+       float matcolor[4];
+       float speccolor[3];
+       short transp, pad;
+
+       float hard, spec_f;
+       float alpha, emit, color_blend[MAXTEX], ref;
+       float amb;
+
+       int blend_mode[MAXTEX];
+
+       int      mode;
+       int num_enabled;
+       
+       int material_index;
+
+       BL_Mapping      mapping[MAXTEX];
+       STR_String      imageId[MAXTEX];
+
+
+       Material*                       material;
+       TFace*                          tface;
+       Image*                          img[MAXTEX];
+       EnvMap*                         cubemap[MAXTEX];
+       
+       void SetConversionRGB(unsigned int *rgb);
+       void GetConversionRGB(unsigned int *rgb);
+
+       void SetConversionUV(MT_Point2 *uv);
+       void GetConversionUV(MT_Point2 *uv);
+
+};
+
+// BL_Material::IdMode
+enum BL_IdMode {
+       DEFAULT_BLENDER=-1,
+       TEXFACE,
+       ONETEX,
+       TWOTEX,
+       GREATERTHAN2
+};
+
+// BL_Material::blend_mode[index]
+enum BL_BlendMode
+{
+       BLEND_MIX=1,
+       BLEND_ADD,
+       BLEND_SUB,
+       BLEND_MUL,
+       BLEND_SCR
+};
+
+// -------------------------------------
+// BL_Material::flag[index]
+enum BL_flag
+{
+       MIPMAP=1,               // set to use mipmaps
+       CALCALPHA=2,    // additive
+       USEALPHA=4,             // use actual alpha channel
+       TEXALPHA=8,             // use alpha combiner functions
+       TEXNEG=16,              // negate blending
+       HASIPO=32
+};
+
+// BL_Material::ras_mode
+enum BL_ras_mode
+{
+       POLY_VIS=1,
+       COLLIDER=2,
+       ZSORT=4,
+       TRANSP=8,
+       TRIANGLE=16,
+       USE_LIGHT=32
+};
+
+// -------------------------------------
+// BL_Material::mapping[index]::mapping
+enum BL_MappingFlag
+{
+       USEREFL=1,
+       USEENV=2,
+       USEOBJ=4
+};
+
+// BL_Material::BL_Mapping::projplane
+enum BL_MappingProj
+{
+       PROJN=0,
+       PROJX,
+       PROJY,
+       PROJZ
+};
+
+// ------------------------------------
+//extern void initBL_Material(BL_Material* mat);
+extern MTex* getImageFromMaterial(Material *mat, int index);
+extern int  getNumTexChannels( Material *mat );
+// ------------------------------------
+
+#endif
+
+
index 7a469c6..4555e81 100644 (file)
@@ -128,9 +128,7 @@ void BL_MeshDeformer::RecalcNormals()
                        m_transnors[mf->v3]+=MT_Point3(fnor);
                        if (mf->v4)
                                m_transnors[mf->v4]+=MT_Point3(fnor);
-
                }
-               
        }
        
        for (v =0; v<m_bmesh->totvert; v++){
@@ -154,7 +152,7 @@ void BL_MeshDeformer::VerifyStorage()
                        delete []m_transnors;
                
                m_transnors =new MT_Point3[m_bmesh->totvert+m_bmesh->totface];
-               m_transverts=new MT_Point3[m_bmesh->totvert];
+               m_transverts=new float[(sizeof(*m_transverts)*m_bmesh->totvert)][3];
                m_tvtot = m_bmesh->totvert;
        }
 }
index c9030ce..adeffd6 100644 (file)
@@ -48,14 +48,13 @@ public:
        void VerifyStorage();
        void RecalcNormals();
        virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){};
-       BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj,struct Object* armatureObj):
+       BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ):
                m_pMeshObject(meshobj),
                m_bmesh((struct Mesh*)(obj->data)),
+               m_objMesh(obj),
                m_transnors(NULL),
                m_transverts(NULL),
-               m_tvtot(0),
-               m_blenderMeshObject(obj),
-               m_blenderArmatureObj(armatureObj)
+               m_tvtot(0)
        {};
        virtual ~BL_MeshDeformer();
        virtual void SetSimulatedTime(double time){};
@@ -64,14 +63,17 @@ public:
        virtual RAS_Deformer*   GetReplica(){return NULL;};
        //      virtual void InitDeform(double time){};
 protected:
-       class BL_SkinMeshObject *m_pMeshObject;
-       struct Mesh *m_bmesh;
-       MT_Point3 *m_transnors;
-       MT_Point3                               *m_transverts;
-       int                                             m_tvtot;
-       Object* m_blenderMeshObject;
-       Object* m_blenderArmatureObj;
-
+       class BL_SkinMeshObject*        m_pMeshObject;
+       struct Mesh*                            m_bmesh;
+       MT_Point3*                                      m_transnors;
+       
+       //MT_Point3*                            m_transverts;
+       // this is so m_transverts doesn't need to be converted
+       // before deformation
+       float                                           (*m_transverts)[3];
+       struct Object*                          m_objMesh; 
+       // --
+       int                                                     m_tvtot;
 };
 
 #endif
diff --git a/source/gameengine/Converter/BL_Shader.cpp b/source/gameengine/Converter/BL_Shader.cpp
new file mode 100644 (file)
index 0000000..c957241
--- /dev/null
@@ -0,0 +1,907 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include <iostream>
+#include "BL_Shader.h"
+#include "BL_Material.h"
+
+#include "MT_assert.h"
+#include "MT_Matrix4x4.h"
+#include "MT_Matrix3x3.h"
+#include "KX_PyMath.h"
+
+#include "RAS_GLExtensionManager.h"
+
+using namespace bgl;
+#define spit(x) std::cout << x << std::endl;
+
+
+BL_Shader::BL_Shader(int n, PyTypeObject *T)
+:      PyObjectPlus(T),
+       mShader(0),
+       mVert(0),
+       mFrag(0),
+       mPass(1),
+       vertProg(""),
+       fragProg(""),
+       mOk(0),
+       mUse(0)
+{
+       // if !RAS_EXT_support._ARB_shader_objects this class will not be used
+
+       mBlending.src   = -1;
+       mBlending.dest  = -1;
+       mBlending.const_color[0] = 0.0;
+       mBlending.const_color[1] = 0.0;
+       mBlending.const_color[2] = 0.0;
+       mBlending.const_color[3] = 1.0;
+
+       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].glTexture =0;
+       }
+}
+
+BL_Shader::~BL_Shader()
+{
+#ifdef GL_ARB_shader_objects
+       if( mShader ) {
+               glDeleteObjectARB(mShader);
+               mShader = 0;
+       }
+       if( mFrag ) {
+               glDeleteObjectARB(mFrag);
+               mFrag = 0;
+       }
+       if( mVert ) {
+               glDeleteObjectARB(mVert);
+               mVert           = 0;
+       }
+
+       vertProg        = 0;
+       fragProg        = 0;
+       mOk                     = 0;
+
+       glUseProgramObjectARB(0);
+#endif//GL_ARB_shader_objects
+}
+
+
+bool BL_Shader::LinkProgram()
+{
+#ifdef GL_ARB_shader_objects
+       if(!vertProg || !fragProg ) return false;
+
+       int vertstat,fragstat,progstat;
+       
+       // vertex prog
+       unsigned int vert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+       glShaderSourceARB(vert, 1, (const char**) &vertProg, 0);
+       glCompileShaderARB(vert);
+       glGetObjectParameterivARB(vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &vertstat);
+       // errors if any
+       printInfo(vert);
+       
+       // fragment prog
+       unsigned int frag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+       glShaderSourceARB(frag, 1,(const char**) &fragProg, 0);
+       glCompileShaderARB(frag);
+       glGetObjectParameterivARB(frag, GL_OBJECT_INFO_LOG_LENGTH_ARB, &fragstat);
+       // errors if any
+       printInfo(frag);
+       
+       if(!vertstat || !fragstat) return false;
+
+       // main prog
+       unsigned int prog = glCreateProgramObjectARB();
+       glAttachObjectARB(prog,vert);
+       glAttachObjectARB(prog,frag);
+
+       glLinkProgramARB(prog);
+       glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &progstat);
+       // info on how it compiled &| linked
+       printInfo(prog);
+
+       if(!progstat)
+               return false;
+
+       // assign
+       mShader = prog;
+       mVert   = vert;
+       mFrag   = frag;
+       mOk             = 1;
+       return true;
+#else
+       return false;
+#endif//GL_ARB_shader_objects
+}
+
+void BL_Shader::printInfo(unsigned int pr)
+{
+#ifdef GL_ARB_shader_objects
+       int length=0;
+       glGetObjectParameterivARB(pr, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
+
+       if(length > 1)
+       {
+               GLcharARB*logger = (GLcharARB*)malloc(sizeof(GLcharARB)*length);
+               int chars=0;
+               
+               glGetInfoLogARB(pr, length, &chars, logger);
+               if(chars>0)
+                       std::cout << (logger) << std::endl;
+
+               if(logger)
+                       free(logger);
+       }
+#endif//GL_ARB_shader_objects
+}
+
+char *BL_Shader::GetVertPtr()
+{
+       return vertProg?vertProg:0;
+}
+
+char *BL_Shader::GetFragPtr()
+{
+       return fragProg?fragProg:0;
+}
+
+void BL_Shader::SetVertPtr( char *vert )
+{
+       vertProg = vert;
+}
+
+void BL_Shader::SetFragPtr( char *frag )
+{
+       fragProg = frag;
+}
+
+unsigned int BL_Shader::GetProg()
+{ 
+       return mShader;
+}
+
+unsigned int BL_Shader::GetVertexShader()
+{ 
+       return mVert;  
+}
+
+unsigned int BL_Shader::GetFragmentShader()
+{ 
+       return mFrag;  
+}
+
+const uSampler* BL_Shader::getSampler(int i)
+{
+       MT_assert(i<=MAXTEX);
+       return &mSampler[i];
+}
+
+const uBlending *BL_Shader::getBlending( int pass )
+{
+       return &mBlending;
+}
+
+const bool BL_Shader::Ok()const
+{
+       return (mShader !=0 && mOk && mUse);
+}
+
+
+void BL_Shader::InitializeSampler(
+       int type,
+       int unit,
+       int pass,
+       unsigned int texture)
+{
+       MT_assert(unit<=MAXTEX);
+       mSampler[unit].glTexture = texture;
+       mSampler[unit].loc =-1;
+       mSampler[unit].pass=0;
+       mSampler[unit].type=type;
+       mSampler[unit].unit=unit;
+}
+
+PyObject* BL_Shader::_getattr(const STR_String& attr)
+{
+       _getattr_up(PyObjectPlus);
+}
+
+
+PyMethodDef BL_Shader::Methods[] = 
+{
+       // creation
+       KX_PYMETHODTABLE( BL_Shader, setSource ),
+       KX_PYMETHODTABLE( BL_Shader, delSource ),
+       KX_PYMETHODTABLE( BL_Shader, getVertexProg ),
+       KX_PYMETHODTABLE( BL_Shader, getFragmentProg ),
+       KX_PYMETHODTABLE( BL_Shader, setNumberOfPasses ),
+       KX_PYMETHODTABLE( BL_Shader, validate),
+       /// access functions
+       KX_PYMETHODTABLE( BL_Shader, isValid),
+       KX_PYMETHODTABLE( BL_Shader, setUniform1f ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform2f ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform3f ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform4f ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform1i ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform2i ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform3i ),
+       KX_PYMETHODTABLE( BL_Shader, setUniform4i ),
+
+       KX_PYMETHODTABLE( BL_Shader, setUniformfv ),
+       KX_PYMETHODTABLE( BL_Shader, setUniformiv ),
+
+       KX_PYMETHODTABLE( BL_Shader, setSampler  ),
+       KX_PYMETHODTABLE( BL_Shader, setUniformMatrix4 ),
+       KX_PYMETHODTABLE( BL_Shader, setUniformMatrix3 ),
+       // KX_PYMETHODTABLE( BL_Shader, setBlending ),
+
+       {NULL,NULL} //Sentinel
+};
+
+
+PyTypeObject BL_Shader::Type = {
+       PyObject_HEAD_INIT(&PyType_Type)
+               0,
+               "BL_Shader",
+               sizeof(BL_Shader),
+               0,
+               PyDestructor,
+               0,
+               __getattr,
+               __setattr,
+               0,
+               __repr,
+               0
+};
+
+
+PyParentObject BL_Shader::Parents[] = {
+       &PyObjectPlus::Type,
+       &BL_Shader::Type,
+       NULL
+};
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" )
+{
+#ifdef GL_ARB_shader_objects
+       if(mShader !=0 && mOk  )
+       {
+               // already set...
+               Py_Return;
+       }
+
+       char *v,*f;
+       int apply=0;
+       if( PyArg_ParseTuple(args, "ssi", &v, &f, &apply) )
+       {
+               vertProg = v;
+               fragProg = f;
+               if( LinkProgram() )
+               {
+                       glUseProgramObjectARB( mShader );
+                       mUse = apply!=0;
+                       Py_Return;
+               }
+               else
+               {
+                       vertProg = 0;
+                       fragProg = 0;
+                       mUse = 0;
+                       glUseProgramObjectARB( 0 );
+               }
+       }
+       return NULL;
+#else
+       Py_Return;
+#endif
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
+{
+#ifdef GL_ARB_shader_objects
+       glDeleteObjectARB(mShader);
+       glDeleteObjectARB(mFrag);
+       glDeleteObjectARB(mVert);
+       mShader         = 0;
+       mFrag           = 0;
+       mVert           = 0;
+       vertProg        = 0;
+       fragProg        = 0;
+       mOk                     = 0;
+       mUse            = 0;
+       glUseProgramObjectARB(0);
+#endif
+       Py_Return;
+
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" )
+{
+       return PyInt_FromLong( ( mShader !=0 &&  mOk ) );
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" )
+{
+       return PyString_FromString(vertProg?vertProg:"");
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" )
+{
+       return PyString_FromString(fragProg?fragProg:"");
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
+{
+#ifdef GL_ARB_shader_objects
+       if(mShader==0)
+       {
+               PyErr_Format(PyExc_TypeError, "invalid shader object");
+               return NULL;
+       }
+
+       int stat = 0;
+       glValidateProgramARB(mShader);
+       glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB, &stat);
+       printInfo(mShader);
+
+       return PyInt_FromLong((stat!=0));
+#else
+       Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setSampler, "setSampler(name, index)" )
+{
+#ifdef GL_ARB_shader_objects
+       char *uniform="";
+       int index=-1;
+       if(PyArg_ParseTuple(args, "si", &uniform, &index)) 
+       {
+               if(mShader==0)
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader, uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       if(index <= MAXTEX)
+                       {
+                               mSampler[index].loc = loc;
+                       }else
+                       {
+                               spit("Invalid texture sample index: " << index);
+                       }
+                       Py_Return;
+               }
+       }
+       return NULL;
+#else
+       Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )" )
+{
+       int pass = 1;
+       if(!PyArg_ParseTuple(args, "i", &pass))
+               return NULL;
+
+       mPass = pass;
+       Py_Return;
+}
+
+/// access functions
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
+{
+#ifdef GL_ARB_shader_objects
+       char *uniform="";
+       float value=0;
+       if(PyArg_ParseTuple(args, "sf", &uniform, &value ))
+       {
+               if( mShader==0 )
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader, uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB( mShader );
+                       glUniform1fARB( loc, value );
+                       Py_Return;
+               }
+
+       }
+       return NULL;
+#else
+       Py_Return;
+#endif
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
+{
+#ifdef GL_ARB_shader_objects
+       char *uniform="";
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB( mShader );
+                       glUniform2fARB(loc, array[0],array[1] );
+                       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
+       char *uniform="";
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB(mShader);
+                       glUniform3fARB(loc, array[0],array[1],array[2]);
+                       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
+       char *uniform="";
+       float array[4]={0,0,0,0};
+       if(PyArg_ParseTuple(args, "sffff", &uniform, &array[0],&array[1],&array[2], &array[3]))
+       {
+               if(mShader==0)
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB(mShader);
+                       glUniform4fARB(loc, array[0],array[1],array[2], array[3]);
+                       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
+       char *uniform="";
+       int value=0;
+       if(PyArg_ParseTuple(args, "si", &uniform, &value ))
+       {
+               if( mShader==0 )
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader, uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB( mShader );
+                       glUniform1iARB( loc, value );
+                       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
+       char *uniform="";
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB( mShader );
+                       glUniform2iARB(loc, array[0],array[1] );
+                       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
+       char *uniform="";
+       int array[3]={0,0,0};
+       if(PyArg_ParseTuple(args, "siii", &uniform, &array[0],&array[1],&array[2]))
+       {
+               if(mShader==0)
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB(mShader);
+                       glUniform3iARB(loc, array[0],array[1],array[2]);
+                       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
+       char *uniform="";
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       glUseProgramObjectARB(mShader);
+                       glUniform4iARB(loc, array[0],array[1],array[2], array[3]);
+                       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
+       char*uniform = "";
+       PyObject *listPtr =0;
+       float array_data[4] = {0.f,0.f,0.f,0.f};
+
+       if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+       {
+               if(mShader==0)
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       if(PySequence_Check(listPtr))
+                       {
+                               unsigned int list_size = PySequence_Size(listPtr);
+                               
+                               for(unsigned int i=0; (i<list_size && i<=4); i++)
+                               {
+                                       PyObject *item = PySequence_GetItem(listPtr, i);
+                                       array_data[i] = (float)PyFloat_AsDouble(item);
+                                       Py_DECREF(item);
+                               }
+                               switch(list_size)
+                               {
+                               case 2:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform2fARB(loc, array_data[0],array_data[1]);
+                                               Py_Return;
+                                       } break;
+                               case 3:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform3fARB(loc, array_data[0],array_data[1], array_data[2]);
+                                               Py_Return;
+                                       }break;
+                               case 4:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform4fARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
+                                               Py_Return;
+                                       }break;
+                               default:
+                                       {
+                                               PyErr_Format(PyExc_TypeError, "Invalid list size");
+                                               return NULL;
+                                       }break;
+                               }
+                       }
+               }
+       }
+       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
+       char*uniform = "";
+       PyObject *listPtr =0;
+       int array_data[4] = {0,0,0,0};
+
+       if(PyArg_ParseTuple(args, "sO", &uniform, &listPtr))
+       {
+               if(mShader==0)
+               {
+                       PyErr_Format(PyExc_ValueError, "invalid shader object");
+                       return NULL;
+               }
+               int loc= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       if(PySequence_Check(listPtr))
+                       {
+                               unsigned int list_size = PySequence_Size(listPtr);
+                               
+                               for(unsigned int i=0; (i<list_size && i<=4); i++)
+                               {
+                                       PyObject *item = PySequence_GetItem(listPtr, i);
+                                       array_data[i] = PyInt_AsLong(item);
+                                       Py_DECREF(item);
+                               }
+                               switch(list_size)
+                               {
+                               case 2:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform2iARB(loc, array_data[0],array_data[1]);
+                                               Py_Return;
+                                       } break;
+                               case 3:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform3iARB(loc, array_data[0],array_data[1], array_data[2]);
+                                               Py_Return;
+                                       }break;
+                               case 4:
+                                       {
+                                               glUseProgramObjectARB(mShader);
+                                               glUniform4iARB(loc, array_data[0],array_data[1], array_data[2], array_data[3]);
+                                               Py_Return;
+                                       }break;
+                               default:
+                                       {
+                                               PyErr_Format(PyExc_TypeError, "Invalid list size");
+                                               return NULL;
+                                       }break;
+                               }
+                       }
+               }
+       }
+       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
+       float matr[16] = {
+               1,0,0,0,
+               0,1,0,0,
+               0,0,1,0,
+               0,0,0,1
+       };
+
+       char *uniform="";
+       PyObject *matrix=0;
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       if (PyObject_IsMT_Matrix(matrix, 4))
+                       {
+                               MT_Matrix4x4 mat;
+                               if (PyMatTo(matrix, mat))
+                               {
+                                       mat.getValue(matr);
+                                       glUseProgramObjectARB(mShader);
+                                       glUniformMatrix4fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
+                                       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
+       float matr[9] = {
+               1,0,0,
+               0,1,0,
+               0,0,1,
+       };
+
+       char *uniform="";
+       PyObject *matrix=0;
+       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= glGetUniformLocationARB(mShader , uniform);
+               if( loc==-1 )
+               {
+                       spit("Invalid uniform value: " << uniform << ".");
+                       Py_Return;
+               }else
+               {
+                       if (PyObject_IsMT_Matrix(matrix, 3))
+                       {
+                               MT_Matrix3x3 mat;
+                               if (PyMatTo(matrix, mat))
+                               {
+                                       mat.getValue(matr);
+                                       glUseProgramObjectARB(mShader);
+                                       glUniformMatrix3fvARB(loc, 1, (transp!=0)?GL_TRUE:GL_FALSE, matr);
+                                       Py_Return;
+                               }
+                       }
+               }
+       }
+       return NULL;
+#else
+       Py_Return;
+#endif//GL_ARB_shader_objects
+}
+
+
+KX_PYMETHODDEF_DOC( BL_Shader, setBlending, "setBlending(src, dest)" )
+{
+       int src, dest;
+       if(PyArg_ParseTuple(args, "ii", &src, &dest))
+       {
+               mBlending.src = src;
+               mBlending.dest = dest;
+               Py_Return;
+       }
+       return NULL;
+}
diff --git a/source/gameengine/Converter/BL_Shader.h b/source/gameengine/Converter/BL_Shader.h
new file mode 100644 (file)
index 0000000..19e0cb8
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef __BL_SHADER_H__
+#define __BL_SHADER_H__
+
+#include "PyObjectPlus.h"
+#include "BL_Material.h"
+
+// -----------------------------------
+// user state management
+typedef struct uSampler
+{
+       unsigned int    type;
+       int                             pass;
+       int                             unit;
+       int                             loc;
+       unsigned int    glTexture;
+}uSampler;
+
+#define SAMP_2D                1
+#define SAMP_CUBE      2
+
+
+// -----------------------------------
+typedef struct uBlending
+{
+       unsigned int pass;
+       int src;        // GL_ blend func values
+       int dest;
+       float const_color[4];
+}uBlending;
+// -----------------------------------
+
+// ----------------
+class BL_Shader : public PyObjectPlus
+{
+       Py_Header;
+private:
+       unsigned int    mShader, 
+                                       mVert,
+                                       mFrag;
+       int                             mPass;
+       bool                    mOk;
+       bool                    mUse;
+       uSampler                mSampler[MAXTEX];
+       uBlending               mBlending;
+       char*                   vertProg;
+       char*                   fragProg;
+       bool                    LinkProgram();
+       void                    printInfo(unsigned int pr);
+
+public:
+       BL_Shader(int n, PyTypeObject *T=&Type);
+       virtual ~BL_Shader();
+
+       char*           GetVertPtr();
+       char*           GetFragPtr();
+       void            SetVertPtr( char *vert );
+       void            SetFragPtr( char *frag );
+       
+       // ---
+       int getNumPass()        {return mPass;}
+       bool use()                      {return mUse;}
+
+       // ---
+       // access
+       const uSampler*         getSampler(int i);
+       const uBlending*        getBlending( int pass );
+       const bool                      Ok()const;
+
+       unsigned int            GetProg();
+       unsigned int            GetVertexShader();
+       unsigned int            GetFragmentShader();
+       
+       void InitializeSampler(
+               int type,
+               int unit,
+               int pass,
+               unsigned int texture
+       );
+
+       // -----------------------------------
+       // python interface
+       virtual PyObject* _getattr(const STR_String& attr);
+
+       KX_PYMETHOD_DOC( BL_Shader, setSource );
+       KX_PYMETHOD_DOC( BL_Shader, delSource );
+       KX_PYMETHOD_DOC( BL_Shader, getVertexProg );
+       KX_PYMETHOD_DOC( BL_Shader, getFragmentProg );
+       KX_PYMETHOD_DOC( BL_Shader, setNumberOfPasses );
+
+       // -----------------------------------
+       KX_PYMETHOD_DOC( BL_Shader, isValid);
+       KX_PYMETHOD_DOC( BL_Shader, validate);
+       KX_PYMETHOD_DOC( BL_Shader, setUniform4f );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform3f );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform2f );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform1f );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform4i );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform3i );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform2i );
+       KX_PYMETHOD_DOC( BL_Shader, setUniform1i );
+
+       KX_PYMETHOD_DOC( BL_Shader, setUniformfv );
+       KX_PYMETHOD_DOC( BL_Shader, setUniformiv );
+
+       KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix4 );
+       KX_PYMETHOD_DOC( BL_Shader, setUniformMatrix3 );
+
+       // these come from within the material buttons
+       // sampler2d/samplerCube work
+       KX_PYMETHOD_DOC( BL_Shader, setSampler);
+       // user blending funcs
+       KX_PYMETHOD_DOC( BL_Shader, setBlending );
+};
+
+
+
+#endif//__BL_SHADER_H__
index 01997e8..dc35221 100644 (file)
 #include "BKE_action.h"
 #include "MT_Point3.h"
 
+extern "C"{
+       #include "BKE_lattice.h"
+}
+ #include "BKE_utildefines.h"
+
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
@@ -57,6 +62,8 @@
 
 BL_SkinDeformer::~BL_SkinDeformer()
 {
+       if(m_releaseobject && m_armobj)
+               m_armobj->Release();
 };
 
 /* XXX note, this __NLA_OLDDEFORM define seems to be obsolete */
@@ -147,11 +154,8 @@ void BL_SkinDeformer::ProcessReplica()
 
 //void where_is_pose (Object *ob);
 //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); 
-extern "C" void armature_deform_verts(struct Object *armOb, struct Object *target, float (*vertexCos)[3], int numVerts, int deformflag);
-
 void BL_SkinDeformer::Update(void)
 {
-
        /* See if the armature has been updated for this frame */
        if (m_lastUpdate!=m_armobj->GetLastFrame()){    
                
@@ -161,32 +165,28 @@ void BL_SkinDeformer::Update(void)
                /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
                /* but it requires the blender object pointer... */
                //void where_is_pose (Object *ob);
-               where_is_pose (m_blenderArmatureObj);
+//             where_is_pose (m_blenderArmatureObj);
                
                /* store verts locally */
-               for (int v =0; v<m_bmesh->totvert; v++){
+//             for (int v =0; v<m_bmesh->totvert; v++){
                        /* XXX note, dunno about this line */
-                       m_transverts[v]=MT_Point3(m_bmesh->mvert[v].co);
-               }
+//                     m_transverts[v]=MT_Point3(m_bmesh->mvert[v].co);
+//             }
                
-               float   test[1000][3];
+//             float   test[1000][3];
 
-               armature_deform_verts(m_blenderArmatureObj,m_blenderMeshObject,test,m_bmesh->totvert,ARM_DEF_VGROUP);
+//             armature_deform_verts(m_blenderArmatureObj,m_blenderMeshObject,test,m_bmesh->totvert,ARM_DEF_VGROUP);
 
 
-               /* XXX note: now use this call instead */
-//             void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag) 
-               //              - armOb = armature object
-               //              - target = Mesh
-               //              - vertexCos[3] = array of numVerts float vectors (3 floats)
-               //              - set deformflag to ARM_DEF_VGROUP
-               //              example (after having filled the m_transverts array):
-               //              armature_deform_verts(m_armobj, m_meshobj, m_transverts, m_bmesh->totvert, ARM_DEF_VGROUP);
-               
+               Object* par_arma = m_armobj->GetArmatureObject();
+               where_is_pose( par_arma ); 
+               /* store verts locally */
                VerifyStorage();
-                       
+               for (int v =0; v<m_bmesh->totvert; v++)
+                       VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
+
+               armature_deform_verts( par_arma, m_objMesh,m_transverts, m_bmesh->totvert, ARM_DEF_VGROUP );
                RecalcNormals();
-               
 
                /* Update the current frame */
                m_lastUpdate=m_armobj->GetLastFrame();
@@ -194,16 +194,9 @@ void BL_SkinDeformer::Update(void)
 }
 
 /* XXX note: I propose to drop this function */
-
 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
 {
-//     m_armobj = armobj;
-
-//     for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next) {
-
-/*             dg->data no longer exists needs update
-                       dg->data = (void*)get_named_bone(m_armobj->GetArmature(), dg->name); */
-//     }
-               
-//             GB_validate_defgroups(m_bmesh, m_defbase);
+       // --
+       // only used to set the object now
+       m_armobj = armobj;
 }
index 49c6929..74adc6c 100644 (file)
@@ -64,37 +64,31 @@ public:
        }
        void SetArmature (class BL_ArmatureObject *armobj);
 
-       BL_SkinDeformer(        struct Object *bmeshobj, 
-                                               class BL_SkinMeshObject *mesh,struct Object* blenderArmatureObj)
-                                               :BL_MeshDeformer(bmeshobj, mesh,blenderArmatureObj),
-                                               m_armobj(NULL),
+       BL_SkinDeformer(struct Object *bmeshobj, 
+                                       class BL_SkinMeshObject *mesh,
+                                       BL_ArmatureObject* arma = NULL)
+                                       :       //
+                                               BL_MeshDeformer(bmeshobj, mesh),
+                                               m_armobj(arma),
                                                m_lastUpdate(-1),
-                                               m_defbase(&bmeshobj->defbase)
+                                               m_defbase(&bmeshobj->defbase),
+                                               m_releaseobject(false)
        {
-               /* Build all precalculatable matrices for bones */
-/* XXX note: obsolete */
-//             GB_build_mats(bmeshobj->parent->obmat, bmeshobj->obmat, m_premat, m_postmat);
-//             GB_validate_defgroups((Mesh*)bmeshobj->data, m_defbase);
-               // Validate bone data in bDeformGroups
-/*
-               for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
-                       dg->data = (void*)get_named_bone(barm, dg->name);
-*/
        };
 
        /* this second constructor is needed for making a mesh deformable on the fly. */
-
-       BL_SkinDeformer(        struct Object *bmeshobj_old,
-                                               struct Object *bmeshobj_new,
-                                               class BL_SkinMeshObject *mesh,struct Object *bArmatureObj)
-                                               :BL_MeshDeformer(bmeshobj_old, mesh,bArmatureObj),
-                                               m_armobj(NULL),
+       BL_SkinDeformer(struct Object *bmeshobj_old,
+                                       struct Object *bmeshobj_new,
+                                       class BL_SkinMeshObject *mesh,
+                                       bool release_object,
+                                       BL_ArmatureObject* arma = NULL)
+                                       :       //
+                                               BL_MeshDeformer(bmeshobj_old, mesh),
+                                               m_armobj(arma),
                                                m_lastUpdate(-1),
-                                               m_defbase(&bmeshobj_old->defbase)
+                                               m_defbase(&bmeshobj_old->defbase),
+                                               m_releaseobject(release_object)
        {
-/* XXX note: obsolete */
-//             GB_build_mats(bmeshobj_new->parent->obmat, bmeshobj_new->obmat, m_premat, m_postmat);
-//             GB_validate_defgroups((Mesh*)bmeshobj_old->data, m_defbase);
        };
 
        virtual void ProcessReplica();
@@ -104,13 +98,12 @@ public:
        bool Apply (class RAS_IPolyMaterial *polymat);
 
 protected:
-       BL_ArmatureObject               *m_armobj;                      //      Our parent object
-/* XXX note obsolete */
-//     float                                   m_premat[4][4];
-//     float                                   m_postmat[4][4];
+       BL_ArmatureObject*              m_armobj;       //      Our parent object
        float                                   m_time;
        double                                  m_lastUpdate;
-       ListBase                                *m_defbase;
+       ListBase*                               m_defbase;
+       bool                                    m_releaseobject;
+
 };
 
 #endif
diff --git a/source/gameengine/Converter/BL_Texture.cpp b/source/gameengine/Converter/BL_Texture.cpp
new file mode 100644 (file)
index 0000000..dec76ac
--- /dev/null
@@ -0,0 +1,387 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include <iostream>
+
+#include "BL_Material.h"
+#include "BL_Texture.h"
+#include "MT_assert.h"
+
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+#include "IMB_imbuf_types.h"
+#include "BKE_image.h"
+//#include "IMB_imbuf.h"
+#include "BLI_blenlib.h"
+
+#include "RAS_GLExtensionManager.h"
+using namespace bgl;
+
+#define spit(x) std::cout << x << std::endl;
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+       // envmaps
+       #include "IMB_imbuf.h"
+       void my_envmap_split_ima(EnvMap *env);
+       void my_free_envmapdata(EnvMap *env);
+}
+
+// (n&(n-1)) zeros the least significant bit of n 
+static int is_pow2(int num) {
+       return ((num)&(num-1))==0;
+}
+static int smaller_pow2(int num) {
+       while (!is_pow2(num))
+               num= num&(num-1);
+       return num;     
+}
+
+
+
+BL_Texture::BL_Texture()
+:      mTexture(0),
+       mError(0),
+       mOk(0),
+       mNeedsDeleted(0),
+       mType(0),
+       mName("")
+{
+       // --
+}
+
+BL_Texture::~BL_Texture()
+{
+       // --
+}
+
+void BL_Texture::DeleteTex()
+{
+       if( mNeedsDeleted ) {
+               glDeleteTextures(1, (GLuint*)&(*mTexture));
+               mNeedsDeleted = 0;
+               mOk = 0;
+       }
+}
+
+
+bool BL_Texture::InitFromImage( Image *img, bool mipmap)
+{
+       if(!img || img->ok==0 ) {
+               mError = true;
+               mOk = false;
+               return mOk;
+       }
+       if( img->ibuf==0 ) {
+               load_image(img, IB_rect, "", 0);
+               if(img->ibuf==0) {
+                       img->ok = 0;
+                       mError = true;
+                       mOk = false;
+                       return mOk;
+               } 
+       }
+       mTexture = &img->bindcode;
+       mName = img->id.name;
+       mType = BL_TEX2D;
+       
+       // smoke em if we got em
+       if (*mTexture != 0) {
+               glBindTexture(GL_TEXTURE_2D, *mTexture );
+               Validate();
+               return mOk;
+       }
+       glGenTextures(1, (GLuint*)mTexture);
+       InitGLTex(img->ibuf->rect, img->ibuf->x, img->ibuf->y, mipmap);
+       Validate();
+       return mOk;
+}
+
+void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
+{
+       if (!is_pow2(x) || !is_pow2(y) ) {
+               InitNonPow2Tex(pix, x,y,mipmap);
+               return;
+       }
+
+       glBindTexture(GL_TEXTURE_2D, *mTexture );
+       if( mipmap ) {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+       } 
+       else {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+       }
+
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+
+void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
+{
+       int nx= smaller_pow2(x);
+       int ny= smaller_pow2(y);
+
+       unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
+       
+       gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
+       glBindTexture(GL_TEXTURE_2D, *mTexture );
+
+       if( mipmap ) {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+       }
+       else {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+       }
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+       free(newPixels);
+}
+
+
+bool BL_Texture::InitCubeMap( EnvMap *cubemap )
+{
+#ifdef GL_ARB_texture_cube_map
+       if(!RAS_EXT_support._ARB_texture_cube_map) {
+               spit("cubemaps not supported");
+               mError = true;
+               mOk = false;
+               return mOk;
+       }
+       
+       else if(!cubemap || cubemap->ima->ok==0 ) {
+               mError = true;
+               mOk = false;
+               return mOk;
+       }
+
+       if( cubemap->ima->ibuf==0 )  {
+               load_image(cubemap->ima, IB_rect, "", 0);
+               if(cubemap->ima->ibuf==0) {
+                       cubemap->ima->ok = 0;
+                       mError = true;
+                       mOk = false;
+                       return mOk;
+               }
+       }
+
+       EnvMap *CubeMap = cubemap;
+       mNeedsDeleted = 1;
+       mBlankTexture = 0;
+       mType = BL_TEXCUBE;
+       mTexture = &mBlankTexture;
+       mName = CubeMap->ima->id.name;
+
+       glGenTextures(1, (GLuint*)(mTexture));
+       glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *mTexture );
+       bool needs_split = false;
+
+       if(!CubeMap->cube[0]) needs_split = true; 
+
+       if(needs_split){
+               // split it
+               my_envmap_split_ima(CubeMap);
+       }
+
+       int x = cubemap->ima->ibuf->x;
+       int y = cubemap->ima->ibuf->y;
+       unsigned int *data= (unsigned int *)malloc(x*y*sizeof(unsigned int));
+
+       // -----------------------------------
+       x       = CubeMap->cube[0]->ibuf->x;
+       y       = CubeMap->cube[0]->ibuf->y;
+
+       // check the first image, and assume the rest
+       if (!is_pow2(x) || !is_pow2(y))
+       {
+               spit("invalid envmap size please render with CubeRes @ power of two");
+               free(data);
+               data = 0;
+               mError = true;
+               mOk = false;
+               return mOk;
+       }
+       memcpy(data, CubeMap->cube[0]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       // -----------------------------------
+       x       = CubeMap->cube[1]->ibuf->x;
+       y       = CubeMap->cube[1]->ibuf->y;
+       memcpy(data, CubeMap->cube[1]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       // -----------------------------------
+       x       = CubeMap->cube[2]->ibuf->x;
+       y       = CubeMap->cube[2]->ibuf->y;
+       memcpy(data, CubeMap->cube[2]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       // -----------------------------------
+       x       = CubeMap->cube[3]->ibuf->x;
+       y       = CubeMap->cube[3]->ibuf->y;
+       memcpy(data, CubeMap->cube[3]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       // -----------------------------------
+       x       = CubeMap->cube[4]->ibuf->x;
+       y       = CubeMap->cube[4]->ibuf->y;
+       memcpy(data, CubeMap->cube[4]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       // -----------------------------------
+       x       = CubeMap->cube[5]->ibuf->x;
+       y       = CubeMap->cube[5]->ibuf->y;
+       memcpy(data, CubeMap->cube[5]->ibuf->rect, (x*y*sizeof(unsigned int)));
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+       glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+       glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+       glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S,     GL_REPEAT );
+       glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T,     GL_REPEAT );
+
+       if(data) {
+               free(data);
+               data = 0;
+       }
+       
+       if(needs_split) {
+               // okay we allocated, swap back to orig and free used
+               cubemap->ima = CubeMap->ima;
+               my_free_envmapdata(CubeMap);
+       }
+       mOk = IsValid();
+       return mOk;
+
+#else
+
+       mError = true;
+       mOk = false;
+       return mOk;
+
+#endif//GL_ARB_texture_cube_map
+}
+
+
+STR_String BL_Texture::GetName() const
+{
+       return mName;
+}
+
+
+bool BL_Texture::IsValid()
+{
+       return (mTexture && *mTexture!= 0)?glIsTexture(*mTexture)!=0:false;
+}
+
+
+void BL_Texture::Validate()
+{
+       mOk = IsValid();
+}
+
+
+bool BL_Texture::Ok()
+{
+       return  ( mTexture?((!mError || mOk ) && *mTexture!= 0):0 ); 
+}
+
+
+unsigned int BL_Texture::GetTextureType() const
+{
+       return mType;
+}
+
+
+BL_Texture::operator const unsigned int () const
+{
+       return mTexture? *mTexture:0;
+}
+
+bool BL_Texture::SetGLTex(unsigned int tex)
+{
+       return false;
+}
+
+extern "C" {
+
+void my_envmap_split_ima(EnvMap *env)
+{
+       ImBuf *ibuf;
+       Image *ima;
+       int dx, part;
+       
+       my_free_envmapdata(env);        
+       
+       dx= env->ima->ibuf->y;
+       dx/= 2;
+       if(3*dx != env->ima->ibuf->x) {
+               printf("Incorrect envmap size\n");
+               env->ok= 0;
+               env->ima->ok= 0;
+       }
+       else {
+               for(part=0; part<6; part++) {
+                       ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
+                       ima= (Image*)MEM_callocN(sizeof(Image), "image");
+                       ima->ibuf= ibuf;
+                       ima->ok= 1;
+                       env->cube[part]= ima;
+               }
+               IMB_rectop(env->cube[0]->ibuf, env->ima->ibuf, 
+                       0, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
+               IMB_rectop(env->cube[1]->ibuf, env->ima->ibuf, 
+                       0, 0, dx, 0, dx, dx, IMB_rectcpy, 0);
+               IMB_rectop(env->cube[2]->ibuf, env->ima->ibuf, 
+                       0, 0, 2*dx, 0, dx, dx, IMB_rectcpy, 0);
+               IMB_rectop(env->cube[3]->ibuf, env->ima->ibuf, 
+                       0, 0, 0, dx, dx, dx, IMB_rectcpy, 0);
+               IMB_rectop(env->cube[4]->ibuf, env->ima->ibuf, 
+                       0, 0, dx, dx, dx, dx, IMB_rectcpy, 0);
+               IMB_rectop(env->cube[5]->ibuf, env->ima->ibuf, 
+                       0, 0, 2*dx, dx, dx, dx, IMB_rectcpy, 0);
+               env->ok= 2;
+       }
+}
+
+
+void my_free_envmapdata(EnvMap *env)
+{
+       Image *ima;
+       unsigned int a, part;
+       
+       for(part=0; part<6; part++) {
+               ima= env->cube[part];
+               if(ima) {
+                       if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
+
+                       for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
+                               if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
+                       }
+                       MEM_freeN(ima);
+                       env->cube[part]= 0;
+               }
+       }
+       env->ok= 0;
+}
+
+
+}
+
+unsigned int BL_Texture::mBlankTexture = 0;
+
diff --git a/source/gameengine/Converter/BL_Texture.h b/source/gameengine/Converter/BL_Texture.h
new file mode 100644 (file)
index 0000000..51bf727
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __BL_TEXTURE_H__
+#define __BL_TEXTURE_H__
+#include <vector>
+// --
+struct Image;
+struct EnvMap;
+// --
+#include "STR_String.h"
+
+class BL_Texture
+{
+private:
+       // -----------------------------------
+       unsigned int*           mTexture;
+       bool                            mError;
+       bool                            mOk;
+       bool                            mNeedsDeleted;
+       unsigned int            mType;
+       STR_String                      mName;
+       static unsigned int mBlankTexture;
+       std::vector<EnvMap*>mCubeMem;
+       // -----------------------------------
+       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();
+
+       STR_String GetName() const;
+
+       unsigned int GetTextureType() const;
+       void    DeleteTex();
+       bool    InitFromImage( Image *img, bool mipmap);
+       bool    InitCubeMap( EnvMap *cubemap );
+       // 
+       bool    SetGLTex(unsigned int tex);
+
+       void    PopCubeMap();
+       bool    IsValid();
+       void    Validate();
+};
+
+enum TexType{
+       BL_TEX2D        = 1,
+       BL_TEXCUBE      = 2
+};
+
+
+#endif//__BL_TEXTURE_H__
index b388af9..eb03a3c 100644 (file)
@@ -95,6 +95,10 @@ BlenderWorldInfo::BlenderWorldInfo(struct World* blenderworld)
                m_backgroundred = blenderworld->horr;
                m_backgroundgreen = blenderworld->horg;
                m_backgroundblue = blenderworld->horb;
+               
+               m_ambientred = blenderworld->ambr;
+               m_ambientgreen = blenderworld->ambg;
+               m_ambientblue = blenderworld->ambb;
        }
        else
        {
@@ -144,6 +148,20 @@ float BlenderWorldInfo::getBackColorBlue()
 }  
 
 
+float BlenderWorldInfo::getAmbientColorRed()
+{
+       return m_ambientred;
+}
+
+float BlenderWorldInfo::getAmbientColorGreen()
+{
+       return m_ambientgreen;
+}
+
+float BlenderWorldInfo::getAmbientColorBlue()
+{
+       return m_ambientblue;
+}
 
 float BlenderWorldInfo::getMistStart()
 {
index 059942e..35e47bb 100644 (file)
@@ -48,7 +48,11 @@ class BlenderWorldInfo : public KX_WorldInfo
        float                   m_mistred;
        float                   m_mistgreen;
        float                   m_mistblue;
-       
+
+       float                   m_ambientred;
+       float                   m_ambientgreen;
+       float                   m_ambientblue;
+
 public:
        BlenderWorldInfo(struct World* blenderworld);
        ~BlenderWorldInfo();
@@ -58,6 +62,10 @@ public:
     float      getBackColorRed();
     float      getBackColorGreen();
     float      getBackColorBlue();
+       
+       float   getAmbientColorRed();
+       float   getAmbientColorGreen();
+       float   getAmbientColorBlue();
 
     float      getMistStart();
     float      getMistDistance();
index 34b9b06..28af414 100644 (file)
@@ -42,6 +42,7 @@
 #include "PHY_IPhysicsEnvironment.h"
 #include "KX_KetsjiEngine.h"
 #include "KX_IPhysicsController.h"
+#include "BL_Material.h"
 
 #include "DummyPhysicsEnvironment.h"
 
@@ -98,7 +99,8 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter(
                                                        : m_maggie(maggie),
                                                        m_sipo(sipo),
                                                        m_ketsjiEngine(engine),
-                                                       m_alwaysUseExpandFraming(false)
+                                                       m_alwaysUseExpandFraming(false),
+                                                       m_usemat(false)
 {
        m_newfilename = "";
 }
@@ -129,7 +131,15 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
                delete (*itp);
                itp++;
        }
-       
+
+       // delete after RAS_IPolyMaterial
+       vector<BL_Material *>::iterator itmat = m_materials.begin();
+       while (itmat != m_materials.end()) {
+               delete (*itmat);
+               itmat++;
+       }       
+
+
        vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin();
        while (itm != m_meshobjects.end()) {
                delete (*itm);
@@ -345,6 +355,24 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
 }
 
 
+// use blender materials
+void KX_BlenderSceneConverter::SetMaterials(bool val)
+{
+       m_usemat = val;
+}
+
+bool KX_BlenderSceneConverter::GetMaterials()
+{
+       return m_usemat;
+}
+
+
+void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
+{
+       m_materials.push_back(mat);
+}
+
+
 
 void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
        bool to_what)
index bdaa844..db2090a 100644 (file)
@@ -44,6 +44,7 @@ class SCA_IController;
 class RAS_MeshObject;
 class RAS_IPolyMaterial;
 class BL_InterpolatorList;
+class BL_Material;
 struct IpoCurve;
 struct Main;
 struct SpaceIpo;
@@ -53,6 +54,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
        vector<KX_WorldInfo*>   m_worldinfos;
        vector<RAS_IPolyMaterial*> m_polymaterials;
        vector<RAS_MeshObject*> m_meshobjects;
+       vector<BL_Material *>   m_materials;
 
        GEN_Map<CHashedPtr,struct Object*> m_map_gameobject_to_blender;
        GEN_Map<CHashedPtr,KX_GameObject*> m_map_blender_to_gameobject;
@@ -71,7 +73,8 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
        STR_String                              m_newfilename;
        class KX_KetsjiEngine*  m_ketsjiEngine;
        bool                                    m_alwaysUseExpandFraming;
-       
+       bool                                    m_usemat;
+
        void localDel_ipoCurve ( IpoCurve * icu ,struct SpaceIpo*       sipo);
        struct Ipo* findIpoForName(char* objName);
 
@@ -113,6 +116,8 @@ public:
 //     DT_ShapeHandle FindSumoShape(RAS_MeshObject *for_gamemesh);
 
        void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+
+       void RegisterBlenderMaterial(BL_Material *mat);
        
        void RegisterInterpolatorList(BL_InterpolatorList *ipoList, struct Ipo *for_ipo);
        BL_InterpolatorList *FindInterpolatorList(struct Ipo *for_ipo);
@@ -131,7 +136,9 @@ public:
        virtual void    WritePhysicsObjectToAnimationIpo(int frameNumber);
        virtual void    TestHandlesPhysicsObjectToAnimationIpo();
 
-
+       // use blender materials
+       virtual void SetMaterials(bool val);
+       virtual bool GetMaterials();
 
 };
 
index 56eda51..defcdff 100644 (file)
@@ -59,6 +59,7 @@
 #include "DNA_lamp_types.h"
 #include "DNA_world_types.h"
 #include "DNA_camera_types.h"
+#include "DNA_material_types.h"
 /* end of blender include block */
 
 #include "KX_IPO_SGController.h"
@@ -66,6 +67,7 @@
 #include "KX_CameraIpoSGController.h"
 #include "KX_WorldIpoController.h"
 #include "KX_ObColorIpoSGController.h"
+#include "KX_MaterialIpoController.h"
 
 #include "SG_Node.h"
 
@@ -561,3 +563,195 @@ void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *co
        }
 }
 
+
+void BL_ConvertMaterialIpos(
+       Material* blendermaterial, 
+       KX_GameObject* gameobj,  
+       KX_BlenderSceneConverter *converter
+       )
+{
+       if (blendermaterial->ipo) {
+       
+               KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController();
+               gameobj->GetSGNode()->AddSGController(ipocontr);
+               ipocontr->SetObject(gameobj->GetSGNode());
+               
+               BL_InterpolatorList *ipoList= GetIpoList(blendermaterial->ipo, converter);
+
+
+               ipocontr->m_rgba[0]     = blendermaterial->r;
+               ipocontr->m_rgba[1]     = blendermaterial->g;
+               ipocontr->m_rgba[2]     = blendermaterial->b;
+               ipocontr->m_rgba[3]     = blendermaterial->alpha;
+
+               ipocontr->m_specrgb[0]  = blendermaterial->specr;
+               ipocontr->m_specrgb[1]  = blendermaterial->specg;
+               ipocontr->m_specrgb[2]  = blendermaterial->specb;
+               
+               ipocontr->m_hard                = blendermaterial->har;
+               ipocontr->m_spec                = blendermaterial->spec;
+               ipocontr->m_ref                 = blendermaterial->ref;
+               ipocontr->m_emit                = blendermaterial->emit;
+               ipocontr->m_alpha               = blendermaterial->alpha;
+               KX_IScalarInterpolator *ipo;
+               
+               // --
+               ipo = ipoList->GetScalarInterpolator(MA_COL_R);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_rgba[0],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               ipo = ipoList->GetScalarInterpolator(MA_COL_G);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_rgba[1],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               ipo = ipoList->GetScalarInterpolator(MA_COL_B);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_rgba[2],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               ipo = ipoList->GetScalarInterpolator(MA_ALPHA);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_rgba[3],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               // --
+
+               ipo = ipoList->GetScalarInterpolator(MA_SPEC_R );
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_specrgb[0],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               ipo = ipoList->GetScalarInterpolator(MA_SPEC_G);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_specrgb[1],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               ipo = ipoList->GetScalarInterpolator(MA_SPEC_B);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_specrgb[2],
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+                       
+               // --
+               ipo = ipoList->GetScalarInterpolator(MA_HARD);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_hard,
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+
+               ipo = ipoList->GetScalarInterpolator(MA_SPEC);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_spec,
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+               
+               
+               ipo = ipoList->GetScalarInterpolator(MA_REF);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_ref,
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }       
+               
+               ipo = ipoList->GetScalarInterpolator(MA_EMIT);
+               if (ipo) {
+                       if (!ipocontr) {
+                               ipocontr = new KX_MaterialIpoController();
+                               gameobj->GetSGNode()->AddSGController(ipocontr);
+                               ipocontr->SetObject(gameobj->GetSGNode());
+                       }
+                       KX_IInterpolator *interpolator =
+                       new KX_ScalarInterpolator(
+                               &ipocontr->m_emit,
+                               ipo);
+                       ipocontr->AddInterpolator(interpolator);
+               }
+       }               
+}
+
index e04f33f..e901ae9 100644 (file)
@@ -49,6 +49,10 @@ void BL_ConvertCameraIpos(struct Camera* blendercamera,
        class KX_GameObject* cameraobj, 
        class KX_BlenderSceneConverter *converter);
 
+void BL_ConvertMaterialIpos(struct Material* blendermaterial,
+       class KX_GameObject* materialobj, 
+       class KX_BlenderSceneConverter *converter);
+
 
 #endif //__KX_IPOCONVERT_H
 
index 00908de..40c51da 100755 (executable)
@@ -18,7 +18,10 @@ source_files = ['KX_IpoConvert.cpp',
                 'BL_DeformableGameObject.cpp',
                 'BL_BlenderDataConversion.cpp',
                 'BL_ArmatureObject.cpp',
-                'BL_ActionActuator.cpp'
+                'BL_ActionActuator.cpp',
+                'BL_Material.cpp',
+                'BL_Texture.cpp',
+                'BL_Shader.cpp'
                 ]
 
 kx_converter_env.Append (CPPPATH = ['.',
index bb9ad81..48898df 100644 (file)
@@ -14,7 +14,6 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  */
-
 #include "Value.h"
 #include "FloatValue.h"
 #include "IntValue.h"
@@ -497,9 +496,6 @@ double*             CValue::GetVector3(bool bGetTransformedVec)
 /*---------------------------------------------------------------------------------------------------------------------
        Reference Counting
 ---------------------------------------------------------------------------------------------------------------------*/
-
-
-
 //
 // Add a reference to this value
 //
index d49c8de..ccb9c34 100644 (file)
@@ -184,6 +184,7 @@ public:
 
 
 
+
 #ifndef NO_EXP_PYTHON_EMBEDDING
 #include "PyObjectPlus.h"
 #include "object.h"
@@ -339,7 +340,7 @@ protected:
        virtual void            DisableRefCount();                                                                              // Disable reference counting for this value
        virtual void            AddDataToReplica(CValue* replica);                                              
        virtual                         ~CValue();
-private:                                                                                                                                               
+private:
        // Member variables                                                                                                                     
        std::map<STR_String,CValue*>*           m_pNamedPropertyArray;                                                                  // Properties for user/game etc
        ValueFlags                      m_ValFlags;                                                                                             // Frequently used flags in a bitfield (low memoryusage)
index 2be5af0..b1d210f 100644 (file)
@@ -28,6 +28,7 @@
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
+#include <iostream>
 
 #include "SCA_IObject.h"
 #include "SCA_ISensor.h"
@@ -40,7 +41,6 @@
 #include <config.h>
 #endif
 
-
 MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
 
 SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
index 262f458..8b79703 100644 (file)
@@ -60,7 +60,6 @@ SCA_LogicManager::~SCA_LogicManager()
                        (*gameobjptr)->Release();
 
        }
-
        /*for (int i=0;i<m_sensorcontrollermap.size();i++)
        {
                vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
@@ -175,7 +174,6 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
 
 void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
 {
-
        m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
        // take care that no controller can use this actuator again !
 
index 6e1ddd6..2eee212 100644 (file)
@@ -96,8 +96,6 @@ public:
 
 };
 
-
-
 class SCA_LogicManager
 {
        vector<class SCA_EventManager*>         m_eventmanagers;
@@ -117,7 +115,6 @@ class SCA_LogicManager
        GEN_Map<CHashedPtr,void*>                       m_map_gameobj_to_blendobj;
 
        vector<SmartActuatorPtr>                        m_removedActuators;
-
 public:
        SCA_LogicManager();
        virtual ~SCA_LogicManager();
index 01afd16..a5360d9 100644 (file)
@@ -144,8 +144,7 @@ PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self,
 #if 0
 static char* sPyAddActiveActuator__doc__;
 #endif
-       
-  
+
 PyObject* SCA_PythonController::sPyAddActiveActuator(
          
                PyObject* self, 
@@ -156,18 +155,27 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(
        PyObject* ob1;
        int activate;
        if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate))
-       {
                return NULL;
-               
-       }
+
        // for safety, todo: only allow for registered actuators (pointertable)
        // we don't want to crash gameengine/blender by python scripts
+       std::vector<SCA_IActuator*> lacts =  m_sCurrentController->GetLinkedActuators();
        
-       CValue* ac = (CValue*)ob1;
-       CValue* boolval = new CBoolValue(activate!=0);
-       m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)ac,boolval);
-       boolval->Release();
-       
+       std::vector<SCA_IActuator*>::iterator it;
+       bool found = false;
+       CValue* act = (CValue*)ob1;
+
+       for(it = lacts.begin(); it!= lacts.end(); it++) {
+               if( static_cast<SCA_IActuator*>(act) == (*it) ) {
+                       found=true;
+                       break;
+               }
+       }
+       if(found){
+               CValue* boolval = new CBoolValue(activate!=0);
+               m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval);
+               boolval->Release();
+       }
        Py_INCREF(Py_None);
        return Py_None;
 }
@@ -268,12 +276,24 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
                );
        PyDict_Clear(excdict);
        Py_DECREF(excdict);*/
-       
+
+// FIXME:: still happining, will try to fix. snailrose...
+       PyObject *excdict= PyDict_Copy(m_pythondictionary);
+       PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
+               excdict, 
+               excdict
+               );
+       PyDict_Clear(excdict);
+       Py_DECREF(excdict);
+
+
+#if 0
        PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
                m_pythondictionary, 
                m_pythondictionary
                );
-       
+#endif
+
        if (resultobj)
        {
                Py_DECREF(resultobj);
index b1c4a4d..c532477 100644 (file)
@@ -62,6 +62,8 @@ extern "C"
 #endif  // __cplusplus
 #include "BLI_blenlib.h"
 #include "BLO_readfile.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
 #ifdef __cplusplus
 }
 #endif // __cplusplus
@@ -82,6 +84,7 @@ extern "C"
 #include "RAS_GLExtensionManager.h"
 #include "KX_PythonInit.h"
 #include "KX_PyConstraintBinding.h"
+#include "BL_Material.h" // MAXTEX
 
 #include "KX_BlenderSceneConverter.h"
 #include "NG_LoopBackNetworkDeviceInterface.h"
@@ -126,7 +129,8 @@ GPG_Application::GPG_Application(GHOST_ISystem* system, struct Main* maggie, STR
          m_rasterizer(0), 
          m_sceneconverter(0),
          m_networkdevice(0), 
-         m_audiodevice(0)
+         m_audiodevice(0),
+         m_blendermat(0)
 {
        fSystem = system;
 }
@@ -147,6 +151,7 @@ bool GPG_Application::SetGameEngineData(struct Main* maggie, STR_String startSce
 
        if (maggie != NULL && startSceneName != "")
        {
+               G.scene = (Scene*)maggie->scene.first;
                m_maggie = maggie;
                m_startSceneName = startSceneName;
                result = true;
@@ -488,6 +493,23 @@ 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;
+               
+#ifdef GL_ARB_multitexture
+               // ----------------------------------
+               if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) {
+                       m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0);
+                       int unitmax=0;
+                       glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax);
+                       bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX;
+                       //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl;
+               } else {
+                       bgl::max_texture_units = 0;
+               }
+#else
+               m_blendermat=0;
+#endif//GL_ARB_multitexture
+               // ----------------------------------
+       
                // create the canvas, rasterizer and rendertools
                m_canvas = new GPG_Canvas(window);
                if (!m_canvas)
@@ -606,7 +628,8 @@ bool GPG_Application::startEngine(void)
                
                //      if (always_use_expand_framing)
                //              sceneconverter->SetAlwaysUseExpandFraming(true);
-               
+               if(m_blendermat)
+                       m_sceneconverter->SetMaterials(true);
 
                KX_Scene* startscene = new KX_Scene(m_keyboard,
                        m_mouse,
index 2724b5a..11ede4d 100644 (file)
@@ -142,5 +142,8 @@ protected:
        NG_LoopBackNetworkDeviceInterface* m_networkdevice;
        /** Sound device. */
        SND_IAudioDevice* m_audiodevice;
+
+       bool m_blendermat;
+
 };
 
index d7a9ad2..5b67f8b 100644 (file)
@@ -194,6 +194,7 @@ void usage(char* program)
        printf("       show_properties    0         Show debug properties\n");
        printf("       show_profile       0         Show profiling information\n");
        printf("       vertexarrays       1         Enable vertex arrays\n");
+       printf("       blender_material   0         Enable material settings\n");
        printf("\n");
        printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
        printf("example: %s -g vertexarrays = 0 c:\\loadtest.blend\n", program);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
new file mode 100644 (file)
index 0000000..472acc5
--- /dev/null
@@ -0,0 +1,975 @@
+// ------------------------------------
+// ...
+// ------------------------------------
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include "KX_BlenderMaterial.h"
+#include "BL_Material.h"
+#include "KX_Scene.h"
+#include "KX_Light.h"
+#include "KX_GameObject.h"
+
+#include "MT_Vector3.h"
+#include "MT_Vector4.h"
+#include "MT_Matrix4x4.h"
+
+#include "RAS_MeshObject.h"
+#include "RAS_IRasterizer.h"
+#include "RAS_GLExtensionManager.h"
+#include "ARB_multitexture.h"
+
+extern "C" {
+#include "BDR_drawmesh.h"
+}
+
+#include "STR_HashedString.h"
+
+// ------------------------------------
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "BKE_mesh.h"
+// ------------------------------------
+using namespace bgl;
+#define spit(x) std::cout << x << std::endl;
+
+static PyObject *gTextureDict = 0;
+
+KX_BlenderMaterial::KX_BlenderMaterial(
+    KX_Scene *scene,
+       BL_Material *data,
+       bool skin,
+       int lightlayer,
+       void *clientobject,
+       PyTypeObject *T
+       )
+:      PyObjectPlus(T),
+       RAS_IPolyMaterial(
+               STR_String( data->texname[0] ),
+               STR_String( data->matname ), // needed for physics!
+               data->tile,
+               data->tilexrep[0],
+               data->tileyrep[0],
+               data->mode,
+               ((data->ras_mode &TRANSP)!=0),
+               ((data->ras_mode &ZSORT)!=0),
+               lightlayer,
+               ((data->ras_mode &TRIANGLE)!=0),
+               clientobject
+       ),
+       mMaterial(data),
+       mScene(scene),
+       mShader(0),
+       mUseShader(0),
+       mPass(0)
+{
+       ///RAS_EXT_support._ARB_multitexture == true if were here
+
+       // --------------------------------
+       // RAS_IPolyMaterial variables... 
+       m_flag |=RAS_BLENDERMAT;
+       m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
+       m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
+       
+       // figure max
+       #ifdef GL_ARB_multitexture
+       int enabled = mMaterial->num_enabled;
+       mMaterial->num_enabled = enabled>=bgl::max_texture_units?bgl::max_texture_units:enabled;
+       #else
+       mMaterial->num_enabled=0;
+       #endif
+
+       m_enabled = mMaterial->num_enabled;
+
+       // test the sum of the various modes for equality
+       // so we can ether accept or reject this material 
+       // as being equal, this is rather important to 
+       // prevent material bleeding
+       for(int i=0; i<mMaterial->num_enabled; i++) {
+               m_multimode     +=
+                       (mMaterial->flag[i]     +
+                        mMaterial->blend_mode[i]
+                        );
+       }
+       m_multimode += mMaterial->IdMode+mMaterial->ras_mode;
+
+}
+
+
+KX_BlenderMaterial::~KX_BlenderMaterial()
+{
+       // cleanup work
+       OnExit();
+}
+
+
+TFace* KX_BlenderMaterial::GetTFace(void) const 
+{
+       // fonts on polys
+       MT_assert(mMaterial->tface);
+       return mMaterial->tface;
+}
+
+void KX_BlenderMaterial::OnConstruction()
+{
+       // for each unique material...
+       #ifdef GL_ARB_multitexture
+       if(!gTextureDict)
+               gTextureDict = PyDict_New();
+
+       #ifdef GL_ARB_shader_objects
+       if( RAS_EXT_support._ARB_shader_objects )
+               mShader = new BL_Shader( mMaterial->num_enabled );
+       #endif
+
+       int i;
+       for(i=0; i<mMaterial->num_enabled; i++) {
+               glActiveTextureARB(GL_TEXTURE0_ARB+i);
+               
+               #ifdef GL_ARB_texture_cube_map
+               if( mMaterial->mapping[i].mapping & USEENV ) {
+                       if(!RAS_EXT_support._ARB_texture_cube_map) {
+                               spit("CubeMap textures not supported");
+                               continue;
+                       }
+                       if(!mTextures[i].InitCubeMap( mMaterial->cubemap[i] ) )
+                               spit("unable to initialize image("<<i<<") in "<< 
+                                               mMaterial->matname<< ", image will not be available");
+
+                       if( RAS_EXT_support._ARB_shader_objects )
+                               mShader->InitializeSampler(SAMP_CUBE, i, 0, mTextures[i]);
+               } 
+       
+               else {
+               #endif//GL_ARB_texture_cube_map
+                       if( mMaterial->img[i] ) {
+                               if( ! mTextures[i].InitFromImage(mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
+                                       spit("unable to initialize image("<<i<<") in "<< 
+                                                mMaterial->matname<< ", image will not be available");
+                       
+                               if( RAS_EXT_support._ARB_shader_objects )
+                                       mShader->InitializeSampler(SAMP_2D, i, 0, mTextures[i]);
+                       }
+               #ifdef GL_ARB_texture_cube_map
+               }
+               #endif//GL_ARB_texture_cube_map
+               PyDict_SetItemString(gTextureDict, mTextures[i].GetName().Ptr(), PyInt_FromLong(mTextures[i]));
+       }
+       #endif//GL_ARB_multitexture
+}
+
+void KX_BlenderMaterial::OnExit()
+{
+       #ifdef GL_ARB_multitexture
+
+       #ifdef GL_ARB_shader_objects
+       if( RAS_EXT_support._ARB_shader_objects && mShader ) {
+                //note, the shader here is allocated, per unique material
+                //and this function is called per face
+               glUseProgramObjectARB(0);
+               delete mShader;
+               mShader = 0;
+       }
+       #endif //GL_ARB_shader_objects
+
+       for(int i=0; i<mMaterial->num_enabled; i++) {
+               glActiveTextureARB(GL_TEXTURE0_ARB+i);
+
+               mTextures[i].DeleteTex();
+
+               glMatrixMode(GL_TEXTURE);
+               glLoadIdentity();
+               glMatrixMode(GL_MODELVIEW);
+
+               #ifdef GL_ARB_texture_cube_map
+               if(RAS_EXT_support._ARB_texture_cube_map)
+                       glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+               #endif//GL_ARB_texture_cube_map
+
+               glDisable(GL_TEXTURE_2D);
+               glDisable(GL_TEXTURE_GEN_S);
+               glDisable(GL_TEXTURE_GEN_T);
+               glDisable(GL_TEXTURE_GEN_R);
+               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+       }
+       
+       if (gTextureDict) {
+               PyDict_Clear(gTextureDict);
+               Py_DECREF(gTextureDict);
+               gTextureDict = 0;
+       }
+
+       glActiveTextureARB(GL_TEXTURE0_ARB);
+
+       #ifdef GL_ARB_texture_cube_map
+       if(RAS_EXT_support._ARB_texture_cube_map)
+               glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+       #endif//GL_ARB_texture_cube_map
+
+       glDisable(GL_TEXTURE_2D);
+
+       #endif//GL_ARB_multitexture
+
+       // make sure multi texture units 
+       // revert back to blender...
+       // --
+       if( mMaterial->tface ) 
+               set_tpage(mMaterial->tface);
+}
+
+
+void KX_BlenderMaterial::DisableTexData()
+{
+       glDisable(GL_BLEND);
+       #ifdef GL_ARB_multitexture
+       int i=(MAXTEX>=bgl::max_texture_units?bgl::max_texture_units:MAXTEX)-1;
+       for(; i>=0; i--) {
+               glActiveTextureARB(GL_TEXTURE0_ARB+i);
+               glMatrixMode(GL_TEXTURE);
+               glLoadIdentity();
+               glMatrixMode(GL_MODELVIEW);
+
+               #ifdef GL_ARB_texture_cube_map
+               if(RAS_EXT_support._ARB_texture_cube_map)
+                       glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+               #endif//GL_ARB_texture_cube_map
+
+               glDisable(GL_TEXTURE_2D);       
+               glDisable(GL_TEXTURE_GEN_S);
+               glDisable(GL_TEXTURE_GEN_T);
+               glDisable(GL_TEXTURE_GEN_R);
+               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+       }
+       #endif//GL_ARB_multitexture
+}
+
+
+void KX_BlenderMaterial::setShaderData( bool enable )
+{
+       #ifdef GL_ARB_multitexture 
+       #ifdef GL_ARB_shader_objects 
+
+       MT_assert(RAS_EXT_support._ARB_shader_objects && mShader);
+
+       int i;
+       if( !enable || !mShader->Ok() ) {
+               // frame cleanup.
+               glUseProgramObjectARB( 0 );
+               DisableTexData();
+               return;
+       }
+
+       DisableTexData();
+       glUseProgramObjectARB( mShader->GetProg() );
+       
+       // for each enabled unit
+       for(i=0; i<mMaterial->num_enabled; i++) {
+
+               const uSampler *samp = mShader->getSampler(i);
+               if( samp->loc == -1 || samp->glTexture == 0 ) continue;
+
+               glActiveTextureARB(GL_TEXTURE0_ARB+i);
+
+               #ifdef GL_ARB_texture_cube_map
+               if( mMaterial->mapping[i].mapping &USEENV ) {
+                       glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, samp->glTexture /* mTextures[i]*/ );    
+                       glEnable( GL_TEXTURE_CUBE_MAP_ARB );
+               } 
+               else {
+               #endif//GL_ARB_texture_cube_map
+                       glBindTexture( GL_TEXTURE_2D, samp->glTexture   /*mTextures[i]*/ );     
+                       glEnable( GL_TEXTURE_2D );
+               #ifdef GL_ARB_texture_cube_map
+               }
+               #endif//GL_ARB_texture_cube_map
+               // use a sampler
+               glUniform1iARB(samp->loc, i );
+       }
+       glDisable(GL_BLEND);
+
+       #endif//GL_ARB_shader_objects
+       #endif//GL_ARB_multitexture
+}
+
+
+void KX_BlenderMaterial::setTexData( bool enable )
+{
+       #ifdef GL_ARB_multitexture
+       int i;
+
+       #ifdef GL_ARB_shader_objects
+       if(RAS_EXT_support._ARB_shader_objects) {
+               // switch back to fixed func
+               glUseProgramObjectARB( 0 );
+       }
+       #endif//GL_ARB_shader_objects
+
+       if( !enable ) {
+                // frame cleanup.
+               DisableTexData();
+               return;
+       }
+       
+       DisableTexData();
+
+       if( mMaterial->IdMode == DEFAULT_BLENDER ) {
+               setDefaultBlending();
+               return;
+       }
+
+       if( mMaterial->IdMode == TEXFACE ) {
+
+               // no material connected to the object
+               if( mTextures[0] ) {
+                       if( !mTextures[0].Ok() ) return;
+                       glActiveTextureARB(GL_TEXTURE0_ARB);
+                       glBindTexture( GL_TEXTURE_2D, mTextures[0] );   
+                       glEnable(GL_TEXTURE_2D);
+                       setTextureEnvironment( -1 ); // modulate
+                       setEnvMap( (mMaterial->mapping[0].mapping &USEREFL)!=0 );
+                       setDefaultBlending(); 
+               }
+               return;
+       }
+
+       int lastblend = 0;
+
+       // for each enabled unit
+       for(i=0; (i<mMaterial->num_enabled); i++) {
+               if( !mTextures[i].Ok() ) continue;
+
+               glActiveTextureARB(GL_TEXTURE0_ARB+i);
+
+               #ifdef GL_ARB_texture_cube_map
+               // use environment maps
+               if( mMaterial->mapping[i].mapping &USEENV && RAS_EXT_support._ARB_texture_cube_map ) {
+                       // should not happen
+                       // if(mTextures[i].GetTextureType() & BL_TEX2D) continue;
+
+                       glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, mTextures[i] ); 
+                       glEnable(GL_TEXTURE_CUBE_MAP_ARB);
+                       setTextureEnvironment( i );
+
+                       if( mMaterial->mapping[i].mapping &USEREFL )
+                               setEnvMap( true, true );
+                       else if(mMaterial->mapping[i].mapping &USEOBJ)
+                               setObjectMatrixData(i);
+                       else
+                               setTexMatrixData( i );
+               } 
+               // 2d textures
+               else { 
+               #endif//GL_ARB_texture_cube_map
+                       
+                       // should not happen
+                       //if(mTextures[i].GetTextureType() & BL_TEXCUBE) continue;
+                       //
+                       MT_assert(!(mTextures[i].GetTextureType() & BL_TEXCUBE));
+
+                       glBindTexture( GL_TEXTURE_2D, mTextures[i] );   
+                       glEnable( GL_TEXTURE_2D );
+                       setTextureEnvironment( i );
+                       
+                       if( mMaterial->mapping[i].mapping &USEREFL ){
+                               setEnvMap( true );
+                       }
+                       else if(mMaterial->mapping[i].mapping &USEOBJ){
+                               setObjectMatrixData(i);
+                       }
+                       else {
+                               setTexMatrixData( i );
+                       }
+
+               #ifdef GL_ARB_texture_cube_map
+               }
+               #endif//GL_ARB_texture_cube_map
+
+               // if either unit has set blending
+               // and its the last pass
+               lastblend += setBlending( i ); // dry run
+               if(lastblend >0 && i==mMaterial->num_enabled-1)
+                       setBlending( i, true );
+               else if(lastblend == 0 && i==mMaterial->num_enabled-1)
+                       glDisable(GL_BLEND);
+       }
+       #endif//GL_ARB_multitexture
+}
+
+void
+KX_BlenderMaterial::ActivatShaders(
+       RAS_IRasterizer* rasty, 
+       TCachingInfo& cachingInfo)const
+{
+       if (GetCachingInfo() != cachingInfo) {
+               KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
+
+               if (!cachingInfo)
+                       tmp->setShaderData( false );
+               
+               cachingInfo = GetCachingInfo();
+       
+               if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) {
+                       tmp->setShaderData( true );
+                       rasty->EnableTextures(true);
+               }
+               else {
+                       tmp->setShaderData( false );
+                       rasty->EnableTextures(false);
+               }
+
+               if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
+                       rasty->SetCullFace(false);
+               else
+                       rasty->SetCullFace(true);
+
+               if (mMaterial->mode & RAS_IRasterizer::KX_LINES)
+                       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
+               );
+
+       // Lagan's patch...
+       // added material factor
+       rasty->SetAmbient(mMaterial->amb);
+
+       if (mMaterial->material)
+               rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
+}
+
+void
+KX_BlenderMaterial::ActivateMat( 
+       RAS_IRasterizer* rasty,  
+       TCachingInfo& cachingInfo
+       )const
+{
+       if (GetCachingInfo() != cachingInfo) {
+               KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
+
+               if (!cachingInfo) 
+                       tmp->setTexData( false );
+               
+               cachingInfo = GetCachingInfo();
+
+               if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
+                       tmp->setTexData( true );
+                       rasty->EnableTextures(true);
+               }
+               else{
+                       tmp->setTexData( false );
+                       rasty->EnableTextures(false);
+               }
+
+               if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE)
+                       rasty->SetCullFace(false);
+               else
+                       rasty->SetCullFace(true);
+
+               if (mMaterial->mode & RAS_IRasterizer::KX_LINES)
+                       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
+               );
+       
+       // Lagan's patch...
+       // added material factor
+       rasty->SetAmbient(mMaterial->amb);
+
+       if (mMaterial->material)
+               rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
+}
+
+bool 
+KX_BlenderMaterial::Activate( 
+       RAS_IRasterizer* rasty,  
+       TCachingInfo& cachingInfo
+       )const
+{
+       bool dopass = false;
+       #ifdef GL_ARB_shader_objects
+       if( RAS_EXT_support._ARB_shader_objects &&
+               ( mShader && mShader->Ok() ) ) {
+
+               if( (mPass++) < mShader->getNumPass() ) {
+                       ActivatShaders(rasty, cachingInfo);
+                       dopass = true;
+                       return dopass;
+               }
+               else {
+                       glUseProgramObjectARB( 0 );
+                       mPass = 0;
+                       dopass = false;
+                       return dopass;
+               }
+       }
+       else {
+       #endif//GL_ARB_shader_objects
+               switch (mPass++)
+               {
+                       case 0:
+                               ActivateMat(rasty, cachingInfo);
+                               dopass = true;
+                               break;
+                       default:
+                               mPass = 0;
+                               dopass = false;
+                               break;
+               }
+       #ifdef GL_ARB_shader_objects
+       }
+       #endif//GL_ARB_shader_objects
+       return dopass;
+}
+
+void KX_BlenderMaterial::setTextureEnvironment( int textureIndex )
+{
+#ifndef GL_ARB_texture_env_combine
+       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+       return;
+#else
+       if(textureIndex == -1 || !RAS_EXT_support._ARB_texture_env_combine){
+               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+               return;
+       }
+
+       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
+
+       GLfloat blend_operand           = GL_SRC_COLOR;
+       GLfloat blend_operand_prev      = GL_SRC_COLOR;
+
+       // all sources here are RGB by default
+       GLenum combiner = GL_COMBINE_RGB_ARB;
+       GLenum source0 = GL_SOURCE0_RGB_ARB;
+       GLenum source1 = GL_SOURCE1_RGB_ARB;
+       GLenum source2 = GL_SOURCE2_RGB_ARB;
+       GLenum op0 = GL_OPERAND0_RGB_ARB;
+       GLenum op1 = GL_OPERAND1_RGB_ARB;
+       GLenum op2 = GL_OPERAND2_RGB_ARB;
+
+       // switch to alpha combiners
+       if( (mMaterial->flag[textureIndex] &TEXALPHA) ) {
+               combiner = GL_COMBINE_ALPHA_ARB;
+               source0  = GL_SOURCE0_ALPHA_ARB;
+               source1 = GL_SOURCE1_ALPHA_ARB;
+               source2 = GL_SOURCE2_ALPHA_ARB;
+               op0 = GL_OPERAND0_ALPHA_ARB;
+               op1 = GL_OPERAND1_ALPHA_ARB;
+               op2 = GL_OPERAND2_ALPHA_ARB;
+               blend_operand = GL_SRC_ALPHA;
+               blend_operand_prev = GL_SRC_ALPHA;
+               
+               // invert
+               if(mMaterial->flag[textureIndex] &TEXNEG) {
+                       blend_operand_prev = GL_ONE_MINUS_SRC_ALPHA;
+                       blend_operand = GL_ONE_MINUS_SRC_ALPHA;
+               }
+       }
+       else {
+               if(mMaterial->flag[textureIndex] &TEXNEG) {
+                       blend_operand_prev = GL_ONE_MINUS_SRC_COLOR;
+                       blend_operand = GL_ONE_MINUS_SRC_COLOR;
+               }
+       }
+       // on Texture0 GL_PREVIOUS_ARB is the primary color
+       // on Texture1 GL_PREVIOUS_ARB is Texture0 env
+       switch( mMaterial->blend_mode[textureIndex] ) {
+               case BLEND_MIX:
+                       {
+                               // ------------------------------
+                               GLfloat base_col[4];
+                               base_col[0]      = base_col[1]  = base_col[2]  = 0.f;
+                               base_col[3]      = 1.f-mMaterial->color_blend[textureIndex];
+                               glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,base_col );
+                               glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_INTERPOLATE_ARB);
+                               glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
+                               glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
+                               glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
+                               glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
+                               glTexEnvf(      GL_TEXTURE_ENV, source2,        GL_CONSTANT_ARB );
+                               glTexEnvf(      GL_TEXTURE_ENV, op2,            GL_SRC_ALPHA);
+                       }break;
+               case BLEND_MUL: 
+                       {
+                               // ------------------------------
+                               glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_MODULATE);
+                               glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB);
+                               glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev);
+                               glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
+                               glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
+                       }break;
+               case BLEND_ADD: 
+                       {
+                               // ------------------------------
+                               glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD_SIGNED_ARB);
+                               glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
+                               glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
+                               glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
+                               glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand );
+                       }break;
+               case BLEND_SUB: 
+                       {
+                               // ------------------------------
+                               glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_SUBTRACT_ARB);
+                               glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
+                               glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
+                               glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
+                               glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
+                       }break;
+               case BLEND_SCR: 
+                       {
+                               // ------------------------------
+                               glTexEnvf(      GL_TEXTURE_ENV, combiner,       GL_ADD);
+                               glTexEnvf(      GL_TEXTURE_ENV, source0,        GL_PREVIOUS_ARB );
+                               glTexEnvf(      GL_TEXTURE_ENV, op0,            blend_operand_prev );
+                               glTexEnvf(      GL_TEXTURE_ENV, source1,        GL_TEXTURE );
+                               glTexEnvf(      GL_TEXTURE_ENV, op1,            blend_operand);
+                       } break;
+       }
+#endif //!GL_ARB_texture_env_combine
+}
+
+bool KX_BlenderMaterial::setBlending( int ind, bool enable) 
+{
+       if(!enable) {
+               if(mMaterial->flag[ind] &CALCALPHA )    return true;
+               else if(mMaterial->flag[ind] &USEALPHA )        return true;
+               return false;
+       }
+       else {
+               // additive
+               if(mMaterial->flag[ind] &CALCALPHA ) {
+                       glEnable(GL_BLEND);
+                       glBlendFunc(GL_ONE, GL_ONE);
+                       return true;
+               }
+
+               // use alpha channel
+               else if(mMaterial->flag[ind] &USEALPHA ) {
+                       glEnable(GL_BLEND);
+                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool KX_BlenderMaterial::setDefaultBlending()
+{
+       if( mMaterial->transp &TF_ADD) {
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_ONE, GL_ONE);
+               return true;
+       }
+       
+       if( mMaterial->transp & TF_ALPHA ) {
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               return true;
+       }
+       
+       glDisable(GL_BLEND);
+       return false;
+}
+
+void KX_BlenderMaterial::setEnvMap(bool val, bool cube)
+{
+       #ifdef GL_ARB_texture_cube_map
+       if( cube && RAS_EXT_support._ARB_texture_cube_map ) 
+       {
+               glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB );
+               glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
+               glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
+
+               glEnable(GL_TEXTURE_GEN_S);
+               glEnable(GL_TEXTURE_GEN_T);
+               glEnable(GL_TEXTURE_GEN_R);
+       }
+       else {
+       #endif//GL_ARB_texture_cube_map
+               if( val ) {
+                       glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
+                       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+                       
+                       glEnable(GL_TEXTURE_GEN_S);
+                       glEnable(GL_TEXTURE_GEN_T);
+                       glEnable(GL_TEXTURE_GEN_R);
+               }
+               else {
+                       glDisable(GL_TEXTURE_GEN_S);
+                       glDisable(GL_TEXTURE_GEN_T);
+                       glDisable(GL_TEXTURE_GEN_R);
+               }
+       #ifdef GL_ARB_texture_cube_map
+       }
+       #endif//GL_ARB_texture_cube_map
+}
+
+
+void KX_BlenderMaterial::setTexMatrixData(int i)
+{
+       glMatrixMode(GL_TEXTURE);
+       glLoadIdentity();
+
+       glScalef( 
+               mMaterial->mapping[i].scale[0], 
+               mMaterial->mapping[i].scale[1], 
+               mMaterial->mapping[i].scale[2]
+       );
+       glTranslatef(
+               mMaterial->mapping[i].offsets[0],
+               mMaterial->mapping[i].offsets[1], 
+               mMaterial->mapping[i].offsets[2]
+       );
+
+       glMatrixMode(GL_MODELVIEW);
+
+}
+
+static void GetProjPlane(BL_Material *mat, int index,int num, float*param)
+{
+       param[0]=param[1]=param[2]=param[3]=0.f;
+       if( mat->mapping[index].projplane[num] == PROJX )
+               param[0] = 1.f;
+       else if( mat->mapping[index].projplane[num] == PROJY )
+               param[1] = 1.f;
+       else if( mat->mapping[index].projplane[num] == PROJZ)
+               param[2] = 1.f;
+}
+
+
+void KX_BlenderMaterial::setObjectMatrixData(int i)
+{
+       // will work without cubemaps
+       // but a cubemap will look the best
+       KX_GameObject *obj = 
+               (KX_GameObject*)
+               mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame);
+
+       if(!obj)
+               return;
+
+       glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
+       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
+       glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
+
+       GLenum plane = GL_EYE_PLANE;
+
+       // figure plane gen
+       float proj[4]= {0.f,0.f,0.f,0.f};
+       GetProjPlane(mMaterial, i, 0, proj);
+       glTexGenfv(GL_S, plane, proj);
+       
+       GetProjPlane(mMaterial, i, 1, proj);
+       glTexGenfv(GL_T, plane, proj);
+
+       GetProjPlane(mMaterial, i, 2, proj);
+       glTexGenfv(GL_R, plane, proj);
+
+       glEnable(GL_TEXTURE_GEN_S);
+       glEnable(GL_TEXTURE_GEN_T);
+       glEnable(GL_TEXTURE_GEN_R);
+
+       float matr[16];
+       glGetFloatv(GL_MODELVIEW_MATRIX, matr);
+       MT_Matrix4x4 mvmat(matr);
+
+       glMatrixMode(GL_TEXTURE);
+       glLoadIdentity();
+       glScalef( 
+               mMaterial->mapping[i].scale[0], 
+               mMaterial->mapping[i].scale[1], 
+               mMaterial->mapping[i].scale[2]
+       );
+
+       MT_Point3 pos = obj->NodeGetWorldPosition();
+       MT_Vector4 matmul = MT_Vector4(pos[0], pos[1], pos[2], 1.f);
+       MT_Vector4 t = mvmat*matmul;
+
+       glTranslatef( (float)(-t[0]), (float)(-t[1]), (float)(-t[2]) );
+
+       glMatrixMode(GL_MODELVIEW);
+
+}
+
+
+// ------------------------------------
+void KX_BlenderMaterial::UpdateIPO(
+       MT_Vector4 rgba,
+       MT_Vector3 specrgb,
+       MT_Scalar hard,
+       MT_Scalar spec,
+       MT_Scalar ref,
+       MT_Scalar emit,
+       MT_Scalar alpha
+       )
+{
+       // only works one deep now
+       mMaterial->speccolor[0] = (float)(specrgb)[0];
+       mMaterial->speccolor[1] = (float)(specrgb)[1];
+       mMaterial->speccolor[2] = (float)(specrgb)[2];
+       mMaterial->matcolor[0]  = (float)(rgba[0]);
+       mMaterial->matcolor[1]  = (float)(rgba[1]);
+       mMaterial->matcolor[2]  = (float)(rgba[2]);
+       mMaterial->alpha                = (float)(alpha);
+       mMaterial->hard                 = (float)(hard);
+       mMaterial->emit                 = (float)(emit);
+       mMaterial->spec_f               = (float)(spec);
+}
+
+
+PyMethodDef KX_BlenderMaterial::Methods[] = 
+{
+       KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ),
+       KX_PYMETHODTABLE( KX_BlenderMaterial, useShader ),
+       KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ),
+       KX_PYMETHODTABLE( KX_BlenderMaterial, getTexture ),
+       KX_PYMETHODTABLE( KX_BlenderMaterial, setTexture ),
+
+       {NULL,NULL} //Sentinel
+};
+
+
+PyTypeObject KX_BlenderMaterial::Type = {
+       PyObject_HEAD_INIT(&PyType_Type)
+               0,
+               "KX_BlenderMaterial",
+               sizeof(KX_BlenderMaterial),
+               0,
+               PyDestructor,
+               0,
+               __getattr,
+               __setattr,
+               0,
+               __repr,
+               0
+};
+
+
+PyParentObject KX_BlenderMaterial::Parents[] = {
+       &PyObjectPlus::Type,
+       &KX_BlenderMaterial::Type,
+       NULL
+};
+
+
+PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr)
+{
+       // nodda ?
+       _getattr_up(PyObjectPlus);
+}
+
+int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
+{
+       return PyObjectPlus::_setattr(attr, pyvalue);
+}
+
+KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
+{
+       #ifdef GL_ARB_shader_objects
+       if(!RAS_EXT_support._ARB_shader_objects) {
+               PyErr_Format(PyExc_SystemError, "GLSL not supported");
+               return NULL;
+       }
+       else {
+               Py_INCREF(mShader);
+               return mShader;
+       }
+       #else
+       Py_Return;
+       #endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( KX_BlenderMaterial, useShader, "useShader(1:0)" )
+{
+       #ifdef GL_ARB_shader_objects
+       if(!RAS_EXT_support._ARB_shader_objects) {
+               PyErr_Format(PyExc_SystemError, "GLSL not supported");
+               return NULL;
+       }
+       int use =0;
+       if(PyArg_ParseTuple(args, "i", &use)) {
+               mUseShader = (use!= 0);
+               Py_Return;
+       }
+       return NULL;
+       #else
+       Py_Return;
+       #endif//GL_ARB_shader_objects
+}
+
+KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
+{
+       return PyInt_FromLong( mMaterial->material_index );
+}
+
+KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
+{
+       return NULL;
+}
+
+KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)")
+{
+       return NULL;
+}
+
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
new file mode 100644 (file)
index 0000000..012bbef
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef __KX_BLENDER_MATERIAL_H__
+#define __KX_BLENDER_MATERIAL_H__
+
+#include <vector>
+
+
+#include "RAS_IPolygonMaterial.h"
+#include "BL_Material.h"
+#include "BL_Texture.h"
+#include "BL_Shader.h"
+
+#include "PyObjectPlus.h"
+
+#include "MT_Vector3.h"
+#include "MT_Vector4.h"
+
+struct TFace;
+class KX_Scene;
+
+class KX_BlenderMaterial :  public PyObjectPlus, public RAS_IPolyMaterial
+{
+       Py_Header;
+public:
+       // --------------------------------
+       KX_BlenderMaterial(
+               class KX_Scene* scene, // light/obj list
+               BL_Material*    mat,
+               bool                    skin,
+               int                             lightlayer,
+               void*                   clientobject,
+               PyTypeObject*   T=&Type
+       );
+
+       virtual ~KX_BlenderMaterial();
+
+       // --------------------------------
+       virtual TCachingInfo GetCachingInfo(void) const
+       {
+               // --
+               return (void*) this;
+       }
+
+       // --------------------------------
+       virtual bool Activate(
+               RAS_IRasterizer* rasty, 
+               TCachingInfo& cachingInfo) const;
+       
+       void ActivateMat(
+               RAS_IRasterizer* rasty, 
+               TCachingInfo& cachingInfo)const;
+               
+       void ActivatShaders(
+               RAS_IRasterizer* rasty, 
+               TCachingInfo& cachingInfo)const;
+       // --------------------------------
+
+       TFace* GetTFace(void) const;
+
+       // for ipos
+       void UpdateIPO(
+               MT_Vector4 rgba, MT_Vector3 specrgb,
+               MT_Scalar hard, MT_Scalar spec,
+               MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
+       );
+       
+       // --------------------------------
+       virtual PyObject* _getattr(const STR_String& attr);
+       virtual int       _setattr(const STR_String& attr, PyObject *pyvalue);
+
+       KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader );
+       KX_PYMETHOD_DOC( KX_BlenderMaterial, useShader );
+       KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex );
+       KX_PYMETHOD_DOC( KX_BlenderMaterial, getTexture );
+       KX_PYMETHOD_DOC( KX_BlenderMaterial, setTexture );
+
+       // --------------------------------
+       // pre calculate to avoid pops/lag at startup
+       virtual void OnConstruction( );
+
+private:
+       BL_Material*    mMaterial;
+       BL_Shader*              mShader;
+       bool                    mUseShader;
+       KX_Scene*               mScene;
+       BL_Texture              mTextures[MAXTEX];              // texture array
+       
+       // message centers
+       void    setTexData( bool enable );
+       void    setShaderData( bool enable );
+
+       void    setTextureEnvironment( int textureIndex );
+       void    setEnvMap( bool val, bool cube=false);
+       void    setTexMatrixData(int i);
+       bool    setDefaultBlending();
+       bool    setBlending( int ind, bool enable=false );
+       void    setObjectMatrixData(int i);
+
+       // cleanup stuff
+       void    DisableTexData();
+       void    OnExit();
+
+       //void  DisableNonEnabled();
+       // --
+       mutable int     mPass;
+};
+
+
+#endif
index 009ea4a..674528f 100644 (file)
@@ -338,6 +338,44 @@ bool KX_Camera::GetFrustumCulling() const
 {
        return m_frustum_culling;
 }
+void KX_Camera::EnableViewport(bool viewport)
+{
+       m_camdata.m_viewport = viewport;
+}
+
+void KX_Camera::SetViewport(int left, int bottom, int right, int top)
+{
+       m_camdata.m_viewportleft = left;
+       m_camdata.m_viewportbottom = bottom;
+       m_camdata.m_viewportright = right;
+       m_camdata.m_viewporttop = top;
+}
+
+bool KX_Camera::GetViewport() const
+{
+       return m_camdata.m_viewport;
+}
+
+int KX_Camera::GetViewportLeft() const
+{
+       return m_camdata.m_viewportleft;
+}
+
+int KX_Camera::GetViewportBottom() const
+{
+       return m_camdata.m_viewportbottom;
+}
+
+int KX_Camera::GetViewportRight() const
+{
+       return m_camdata.m_viewportright;
+}
+
+int KX_Camera::GetViewportTop() const
+{
+       return m_camdata.m_viewporttop;
+}
 
 //----------------------------------------------------------------------------
 //Python
@@ -351,6 +389,8 @@ PyMethodDef KX_Camera::Methods[] = {
        KX_PYMETHODTABLE(KX_Camera, getWorldToCamera),
        KX_PYMETHODTABLE(KX_Camera, getProjectionMatrix),
        KX_PYMETHODTABLE(KX_Camera, setProjectionMatrix),
+       KX_PYMETHODTABLE(KX_Camera, enableViewport),
+       KX_PYMETHODTABLE(KX_Camera, setViewport),
        
        {NULL,NULL} //Sentinel
 };
@@ -691,3 +731,31 @@ KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix,
        PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument.");
        return NULL;
 }
+
+KX_PYMETHODDEF_DOC(KX_Camera, enableViewport,
+"enableViewport(viewport)\n"
+"Sets this camera's viewport status\n"
+)
+{
+       int viewport;
+       if (PyArg_ParseTuple(args,"i",&viewport))
+       {
+               if(viewport)
+                       EnableViewport(true);
+               else
+                       EnableViewport(false);
+       }
+       Py_Return;
+}
+
+KX_PYMETHODDEF_DOC(KX_Camera, setViewport,
+"setViewport(left, bottom, right, top)\n"
+"Sets this camera's viewport\n")
+{
+       int left, bottom, right, top;
+       if (PyArg_ParseTuple(args,"iiii",&left, &bottom, &right, &top))
+       {
+               SetViewport(left, bottom, right, top);
+       }
+       Py_Return;
+}
index 52ae64e..ed926f1 100644 (file)
@@ -203,6 +203,42 @@ public:
         * Gets this camera's culling status.
         */
        bool GetFrustumCulling() const;
+       
+       /**
+        * Sets this camera's viewport status.
+        */
+       void EnableViewport(bool viewport);
+       
+       /**
+        * Sets this camera's viewport.
+        */
+       void SetViewport(int left, int bottom, int right, int top);
+       
+       /**
+        * Gets this camera's viewport status.
+        */
+       bool GetViewport() const;
+       
+       /**
+        * Gets this camera's viewport left.
+        */
+       int GetViewportLeft() const;
+       
+       /**
+        * Gets this camera's viewport bottom.
+        */
+       int GetViewportBottom() const;
+       
+       /**
+        * Gets this camera's viewport right.
+        */
+       int GetViewportRight() const;
+       
+       /**
+        * Gets this camera's viewport top.
+        */
+       int GetViewportTop() const;
+
 
        KX_PYMETHOD_DOC(KX_Camera, sphereInsideFrustum);
        KX_PYMETHOD_DOC(KX_Camera, boxInsideFrustum);
@@ -213,6 +249,9 @@ public:
        KX_PYMETHOD_DOC(KX_Camera, getProjectionMatrix);
        KX_PYMETHOD_DOC(KX_Camera, setProjectionMatrix);
        
+       KX_PYMETHOD_DOC(KX_Camera, enableViewport);
+       KX_PYMETHOD_DOC(KX_Camera, setViewport);        
+
        virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
        virtual int       _setattr(const STR_String& attr, PyObject *pyvalue);
 
index 9391715..42e5d55 100644 (file)
@@ -50,6 +50,7 @@ typedef unsigned long uint_ptr;
 
 #define KX_INERTIA_INFINITE 10000
 #include "RAS_IPolygonMaterial.h"
+#include "KX_BlenderMaterial.h"
 #include "KX_GameObject.h"
 #include "RAS_MeshObject.h"
 #include "KX_MeshProxy.h"
@@ -367,6 +368,34 @@ void KX_GameObject::UpdateIPO(float curframetime,
        UpdateTransform();
 }
 
+// IPO update
+void 
+KX_GameObject::UpdateMaterialData(
+               MT_Vector4 rgba,
+               MT_Vector3 specrgb,
+               MT_Scalar hard,
+               MT_Scalar spec,
+               MT_Scalar ref,
+               MT_Scalar emit,
+               MT_Scalar alpha
+
+       )
+{
+       int mesh = 0;
+       if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0) {
+               RAS_MaterialBucket::Set::iterator mit = m_meshes[mesh]->GetFirstMaterial();
+               for(; mit != m_meshes[mesh]->GetLastMaterial(); ++mit)
+               {
+                       RAS_IPolyMaterial* poly = (*mit)->GetPolyMaterial();
+                       if(poly->GetFlag() & RAS_BLENDERMAT )
+                       {
+                               SetObjectColor(rgba);
+                               KX_BlenderMaterial *m =  static_cast<KX_BlenderMaterial*>(poly);
+                               m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+                       }
+               }
+       }
+}
 bool
 KX_GameObject::GetVisible(
        void
@@ -605,7 +634,6 @@ PyMethodDef KX_GameObject::Methods[] = {
        {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
        {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
        KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
-       
        {NULL,NULL} //Sentinel
 };
 
@@ -937,7 +965,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
                                                                   PyObject* kwds)
 {
        int mesh = 0;
-       
+
        if (PyArg_ParseTuple(args, "|i", &mesh))
        {
                if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
@@ -950,7 +978,6 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
 }
 
 
-
 PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, 
                                                                                PyObject* args, 
                                                                                PyObject* kwds)
index 3462889..98544cf 100644 (file)
@@ -420,6 +420,19 @@ public:
                bool ipo_as_force,
                bool force_ipo_local
        );
+       /**
+        * Updates Material Ipo data 
+        */
+               void 
+       UpdateMaterialData(
+               MT_Vector4 rgba,
+               MT_Vector3 specrgb,
+               MT_Scalar hard,
+               MT_Scalar spec,
+               MT_Scalar ref,
+               MT_Scalar emit,
+               MT_Scalar alpha
+       );
 
        /**
         * @section Mesh accessor functions.
index 5cb445a..52a6579 100644 (file)
@@ -67,6 +67,9 @@ public:
        virtual void    WritePhysicsObjectToAnimationIpo(int frameNumber) = 0;
        virtual void    TestHandlesPhysicsObjectToAnimationIpo() = 0;
 
+       // use blender materials
+       virtual void SetMaterials(bool val) =0;
+       virtual bool GetMaterials()=0;
 
 };
 
index bd7ce6c..022c5d0 100644 (file)
@@ -555,20 +555,47 @@ void KX_KetsjiEngine::Render()
        // for each scene, call the proceed functions
        {
                KX_Scene* scene = *sceneit;
-
+               KX_Camera* cam = scene->GetActiveCamera();
                // pass the scene's worldsettings to the rasterizer
                SetWorldSettings(scene->GetWorldInfo());
-               
-               if (scene->IsClearingZBuffer())
-                       m_rasterizer->ClearDepthBuffer();
-
-               m_rendertools->SetAuxilaryClientInfo(scene);
-
-               //Initialize scene viewport.
-               SetupRenderFrame(scene);
 
-               // do the rendering
-               RenderFrame(scene);
+               // Avoid drawing the scene with the active camera twice when it's viewport is enabled
+               if(!cam->GetViewport())
+               {
+                       if (scene->IsClearingZBuffer())
+                               m_rasterizer->ClearDepthBuffer();
+       
+                       m_rendertools->SetAuxilaryClientInfo(scene);
+       
+                       //Initialize scene viewport.
+                       SetupRenderFrame(scene, cam);
+       
+                       // do the rendering
+                       RenderFrame(scene, cam);
+               }
+               
+               set<class KX_Camera*>* cameras = scene->GetCameras();
+               
+               // Draw the scene once for each camera with an enabled viewport
+               set<KX_Camera*>::iterator it = cameras->begin();
+               while(it != cameras->end())
+               {
+                       if((*it)->GetViewport())
+                       {
+                               if (scene->IsClearingZBuffer())
+                                       m_rasterizer->ClearDepthBuffer();
+               
+                               m_rendertools->SetAuxilaryClientInfo(scene);
+               
+                               //Initialize scene viewport.
+                               SetupRenderFrame(scene, (*it));
+               
+                               // do the rendering
+                               RenderFrame(scene, (*it));
+                       }
+                       
+                       it++;
+               }
        }
 
        // only one place that checks for stereo
@@ -584,6 +611,7 @@ void KX_KetsjiEngine::Render()
                // for each scene, call the proceed functions
                {
                        KX_Scene* scene = *sceneit;
+                       KX_Camera* cam = scene->GetActiveCamera();
 
                        // pass the scene's worldsettings to the rasterizer
                        SetWorldSettings(scene->GetWorldInfo());
@@ -595,10 +623,12 @@ void KX_KetsjiEngine::Render()
                        m_rendertools->SetAuxilaryClientInfo(scene);
 
                        //Initialize scene viewport.
-                       SetupRenderFrame(scene);
+                       //SetupRenderFrame(scene);
+                       SetupRenderFrame(scene, cam);
 
                        // do the rendering
-                       RenderFrame(scene);
+                       //RenderFrame(scene);
+                       RenderFrame(scene, cam);
                }
        } // if(m_rasterizer->Stereo())
 
@@ -686,6 +716,13 @@ void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
 {
        if (wi->hasWorld())
        {
+               // ...
+               m_rasterizer->SetAmbientColor(
+                       wi->getAmbientColorRed(),
+                       wi->getAmbientColorGreen(),
+                       wi->getAmbientColorBlue()
+               );
+
                if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
                {       
                        if (wi->hasMist())
@@ -749,7 +786,7 @@ void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat)
 }
 
        
-void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene)
+void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
 {
        // In this function we make sure the rasterizer settings are upto
        // date. We compute the viewport so that logic
@@ -760,11 +797,13 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene)
 
        RAS_Rect viewport;
 
-       if (
-               m_overrideCam || 
-               (scene->GetName() != m_overrideSceneName) || 
-               m_overrideCamUseOrtho
-       ) {
+       if (cam->GetViewport()) {
+               viewport.SetLeft(cam->GetViewportLeft()); 
+               viewport.SetBottom(cam->GetViewportBottom());
+               viewport.SetRight(cam->GetViewportRight());
+               viewport.SetTop(cam->GetViewportTop());
+       }
+       else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) ||  m_overrideCamUseOrtho ) {
                RAS_FramingManager::ComputeViewport(
                        scene->GetFramingType(),
                        m_canvas->GetDisplayArea(),
@@ -792,21 +831,23 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene)
 
        
 // update graphics
-void KX_KetsjiEngine::RenderFrame(KX_Scene* scene)
+void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
 {
        float left, right, bottom, top, nearfrust, farfrust;
        const float ortho = 100.0;
-       KX_Camera* cam = scene->GetActiveCamera();
+//     KX_Camera* cam = scene->GetActiveCamera();
        
        if (!cam)
                return;
-
+       
+       // see KX_BlenderMaterial::Activate
+       //m_rasterizer->SetAmbient();
        m_rasterizer->DisplayFog();
 
        if (m_overrideCam && (scene->GetName() == m_overrideSceneName) && m_overrideCamUseOrtho) {
                MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
                m_rasterizer->SetProjectionMatrix(projmat);
-       } else if (cam->hasValidProjectionMatrix())
+       } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
        {
                m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
        } else
@@ -865,7 +906,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene)
        // redrawn. There is a cache between the actual rescheduling
        // and this call though. Visibility is imparted when this call
        // runs through the individual objects.
-       scene->CalculateVisibleMeshes(m_rasterizer);
+       scene->CalculateVisibleMeshes(m_rasterizer,cam);
 
        scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
 }
@@ -958,6 +999,10 @@ void KX_KetsjiEngine::RenderDebugProperties()
        if (tottime < 1e-6f) {
                tottime = 1e-6f;
        }
+
+       // Set viewport to entire canvas
+       RAS_Rect viewport;
+       m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight()));
        
        /* Framerate display */
        if (m_show_framerate) {
index f7c919e..bea558e 100644 (file)
@@ -173,8 +173,8 @@ private:
        /** Blue component of framing bar color. */
        float                                   m_overrideFrameColorB;
 
-       void                                    SetupRenderFrame(KX_Scene *scene);
-       void                                    RenderFrame(KX_Scene* scene);
+       void                                    SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
+       void                                    RenderFrame(KX_Scene* scene, KX_Camera* cam);
        void                                    RenderDebugProperties();
        void                                    SetBackGround(KX_WorldInfo* worldinfo);
        void                                    SetWorldSettings(KX_WorldInfo* worldinfo);
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
new file mode 100644 (file)
index 0000000..d7a1406
--- /dev/null
@@ -0,0 +1,97 @@
+
+#include "KX_MaterialIpoController.h"
+#include "KX_ScalarInterpolator.h"
+#include "KX_GameObject.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+bool KX_MaterialIpoController::Update(double currentTime)
+{
+       if (m_modified)
+       {
+               m_rgba[0]=0;
+               m_rgba[1]=0;
+               m_rgba[2]=0;
+               m_rgba[3]=0;
+       
+               m_specrgb[0] =0;
+               m_specrgb[1] =0;
+               m_specrgb[2] =0;
+               m_hard =0;
+               m_spec=0;
+               m_ref=0;
+               m_emit=0;
+               m_alpha = 0;
+
+
+               T_InterpolatorList::iterator i;
+               for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+                       (*i)->Execute(m_ipotime);
+               }
+               
+
+               SG_Spatial* ob = (SG_Spatial*)m_pObject;
+               KX_GameObject* kxgameobj= (KX_GameObject*) ob->GetSGClientObject();
+
+               //kxgameobj->SetObjectColor(m_rgba);
+               kxgameobj->UpdateMaterialData( 
+                       m_rgba, 
+                       m_specrgb, 
+                       m_hard, 
+                       m_spec, 
+                       m_ref, 
+                       m_emit,
+                       m_alpha
+               );
+
+               m_modified=false;
+       }
+       return false;
+}
+
+
+void KX_MaterialIpoController::AddInterpolator(KX_IInterpolator* interp)
+{
+       this->m_interpolators.push_back(interp);
+}
+
+SG_Controller* KX_MaterialIpoController::GetReplica(class SG_Node* destnode)
+{
+       KX_MaterialIpoController* iporeplica = new KX_MaterialIpoController(*this);
+       // clear object that ipo acts on
+       iporeplica->ClearObject();
+
+       // dirty hack, ask Gino for a better solution in the ipo implementation
+       // hacken en zagen, in what we call datahiding, not written for replication :(
+
+       T_InterpolatorList oldlist = m_interpolators;
+       iporeplica->m_interpolators.clear();
+
+       T_InterpolatorList::iterator i;
+       for (i = oldlist.begin(); !(i == oldlist.end()); ++i) {
+               KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i));
+               iporeplica->AddInterpolator(copyipo);
+
+               MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
+               int orgbase = (int)this;
+               int orgloc = (int)scaal;
+               int offset = orgloc-orgbase;
+               int newaddrbase = (int)iporeplica + offset;
+               MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
+               copyipo->SetNewTarget((MT_Scalar*)blaptr);
+       }
+       
+       return iporeplica;
+}
+
+KX_MaterialIpoController::~KX_MaterialIpoController()
+{
+
+       T_InterpolatorList::iterator i;
+       for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
+               delete (*i);
+       }
+       
+}
\ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.h b/source/gameengine/Ketsji/KX_MaterialIpoController.h
new file mode 100644 (file)
index 0000000..e76ddee
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __KX_MATERIALIPOCONTROLLER_H__
+#define __KX_MATERIALIPOCONTROLLER_H__
+
+
+
+#include "SG_Controller.h"
+#include "SG_Spatial.h"
+#include "KX_IInterpolator.h"
+
+class KX_MaterialIpoController : public SG_Controller
+{
+public:
+       MT_Vector4                      m_rgba;
+       MT_Vector3                      m_specrgb;
+       MT_Scalar                       m_hard;
+       MT_Scalar                       m_spec;
+       MT_Scalar                       m_ref;
+       MT_Scalar                       m_emit;
+       MT_Scalar                       m_alpha;
+
+private:
+       T_InterpolatorList      m_interpolators;
+       bool                            m_modified;
+
+       double                  m_ipotime;
+public:
+       KX_MaterialIpoController() : 
+                               m_modified(true),
+                               m_ipotime(0.0)
+               {}
+       virtual ~KX_MaterialIpoController();
+       virtual SG_Controller*  GetReplica(class SG_Node* destnode);
+       virtual bool Update(double time);
+       virtual void SetSimulatedTime(double time) {
+               m_ipotime = time;
+               m_modified = true;
+       }
+       
+               void
+       SetOption(
+               int option,
+               int value
+       ){
+               // intentionally empty
+       };
+
+
+       void    AddInterpolator(KX_IInterpolator* interp);
+};
+
+
+
+
+#endif//__KX_MATERIALIPOCONTROLLER_H__
index b4b3cea..f6505c2 100644 (file)
@@ -40,6 +40,7 @@
 #include "KX_VertexProxy.h"
 
 #include "KX_PolygonMaterial.h"
+#include "KX_BlenderMaterial.h"
 
 #include "KX_PyMath.h"
 #include "KX_ConvertPhysicsObject.h"
@@ -67,6 +68,7 @@ PyParentObject KX_MeshProxy::Parents[] = {
        &KX_MeshProxy::Type,
        &SCA_IObject::Type,
        &CValue::Type,
+       &PyObjectPlus::Type,
        NULL
 };
 
@@ -87,27 +89,34 @@ KX_MeshProxy::_getattr(const STR_String& attr)
 {
        if (attr == "materials")
        {
-               PyObject *materials = PyList_New(0); /* new ref */
+               PyObject *materials = PyList_New(0);
                RAS_MaterialBucket::Set::iterator mit = m_meshobj->GetFirstMaterial();
                for(; mit != m_meshobj->GetLastMaterial(); ++mit)
-                       PyList_Append(materials, static_cast<KX_PolygonMaterial*>((*mit)->GetPolyMaterial()));
+               {
+                       RAS_IPolyMaterial *polymat = (*mit)->GetPolyMaterial();
+                       if(polymat->GetFlag() & RAS_BLENDERMAT)
+                       {
+                               KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);
+                               PyList_Append(materials, mat);
+                       }else
+                       {
+                               PyList_Append(materials, static_cast<KX_PolygonMaterial*>(polymat));
+                       }
+               }
                return materials;
        }
-               
        _getattr_up(SCA_IObject);
 }
 
 
 
 KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
-       : m_meshobj(mesh)
+       :       m_meshobj(mesh)
 {
-       
 }
 
 KX_MeshProxy::~KX_MeshProxy()
 {
-       
 }
 
 
index 14071ae..46c60ca 100644 (file)
@@ -111,7 +111,7 @@ public:
        
        KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial);
        KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram);
-       
+
        virtual PyObject* _getattr(const STR_String& attr);
        virtual int       _setattr(const STR_String& attr, PyObject *pyvalue);
 };
index 63896b0..ca2939f 100644 (file)
 #include <config.h>
 #endif
 
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
 #ifdef WIN32
 #pragma warning (disable : 4786)
 #endif //WIN32
@@ -60,6 +71,8 @@
 #include "KX_Scene.h"
 #include "SND_DeviceManager.h"
 
+#include "RAS_GLExtensionManager.h"
+
 #include "KX_PyMath.h"
 
 #include "PHY_IPhysicsEnvironment.h"
@@ -258,7 +271,51 @@ static PyObject* gPyGetCurrentScene(PyObject* self,
        Py_INCREF(gp_KetsjiScene);
        return (PyObject*) gp_KetsjiScene;
 }
-                                          
+
+static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
+{
+#define pprint(x) std::cout << x << std::endl;
+       bgl::BL_EXTInfo ext = bgl::RAS_EXT_support;
+       bool count=0;
+       pprint("Supported Extensions...");
+       #ifdef GL_ARB_shader_objects
+       pprint(" GL_ARB_shader_objects supported?       "<< (ext._ARB_shader_objects?           "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_ARB_vertex_shader
+       pprint(" GL_ARB_vertex_shader supported?        "<< (ext._ARB_vertex_shader?            "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_ARB_fragment_shader
+       pprint(" GL_ARB_fragment_shader supported?      "<< (ext._ARB_fragment_shader?          "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_ARB_texture_cube_map
+       pprint(" GL_ARB_texture_cube_map supported?     "<< (ext._ARB_texture_cube_map?         "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_EXT_texture3D
+       pprint(" GL_EXT_texture3D supported?            "<< (ext._EXT_texture3D?                        "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_EXT_blend_color
+       pprint(" GL_EXT_blend_color supported?          "<< (ext._EXT_blend_color?                      "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_ARB_multitexture
+       pprint(" GL_ARB_multitexture supported?         "<< (ext._ARB_multitexture?                     "yes.":"no."));
+       count = 1;
+       #endif
+       #ifdef GL_ARB_texture_env_combine
+       pprint(" GL_ARB_texture_env_combine supported?  "<< (ext._ARB_texture_env_combine?      "yes.":"no."));
+       count = 1;
+       #endif
+       if(!count)
+               pprint("No extenstions are used in this build");
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
 
 
 static struct PyMethodDef game_methods[] = {
@@ -278,6 +335,7 @@ static struct PyMethodDef game_methods[] = {
        {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, "Sets the logic tic rate"},
        {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_VARARGS, "Gets the physics tic rate"},
        {"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, "Sets the physics tic rate"},
+       {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, "Prints GL Extension Info"},
        {NULL, (PyCFunction) NULL, 0, NULL }
 };
 
@@ -487,6 +545,26 @@ static PyObject* gPySetMistEnd(PyObject*,
 }
 
 
+static PyObject* gPySetAmbientColor(PyObject*, 
+                                                                                PyObject* args, 
+                                                                                PyObject*)
+{
+       
+       MT_Vector3 vec = MT_Vector3(0., 0., 0.);
+       if (PyVecArgTo(args, vec))
+       {
+               if (gp_Rasterizer)
+               {
+                       gp_Rasterizer->SetAmbientColor(vec[0], vec[1], vec[2]);
+               }
+               Py_Return;
+       }
+       
+       return NULL;
+}
+
+
+
 
 static PyObject* gPyMakeScreenshot(PyObject*,
                                                                        PyObject* args,
@@ -526,7 +604,8 @@ static struct PyMethodDef rasterizer_methods[] = {
    {"setMousePosition",(PyCFunction) gPySetMousePosition,
    METH_VARARGS, gPySetMousePosition__doc__.Ptr()},
   {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_VARARGS,"set Background Color (rgb)"},
-  {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
+       {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_VARARGS,"set Ambient Color (rgb)"},
+ {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
   {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
   {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
   
index f13df6b..1f37f07 100644 (file)
@@ -54,6 +54,8 @@
 #include "SCA_JoystickManager.h"
 
 #include "RAS_MeshObject.h"
+#include "BL_SkinMeshObject.h"
+
 #include "RAS_IRasterizer.h"
 #include "RAS_BucketManager.h"
 
@@ -259,6 +261,13 @@ SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
 
 
 
+set<class KX_Camera*>* KX_Scene::GetCameras()
+{
+       return &m_cameras;
+}
+
+
 
 void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings)
 {
@@ -714,6 +723,7 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
                
        if (newobj == m_active_camera)
        {
+               m_active_camera->Release();
                m_active_camera = NULL;
        }
 }
@@ -731,21 +741,30 @@ void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
        if (newobj->m_isDeformable && mesh->m_class == 1) {
                Object* blendobj = (struct Object*)m_logicmgr->FindBlendObjByGameObj(newobj);
                Object* oldblendobj = (struct Object*)m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName());
-               if (blendobj->parent && blendobj->parent->type == OB_ARMATURE && blendobj->partype==PARSKEL && ((Mesh*)blendobj->data)->dvert) {
-                       BL_SkinDeformer* skindeformer = new BL_SkinDeformer(oldblendobj, blendobj, (BL_SkinMeshObject*)mesh,blendobj->parent);
-                       skindeformer->SetArmature((BL_ArmatureObject*) newobj->GetParent());
-                       
+               
+               if (blendobj->parent && blendobj->parent->type == OB_ARMATURE && 
+                       blendobj->partype==PARSKEL && 
+                       ((Mesh*)blendobj->data)->dvert) 
+               {
                        // FIXME: should the old m_pDeformer be deleted?
-                       // delete ((BL_DeformableGameObject*)newobj)->m_pDeformer
+                       // it shouldn't be a problem to delete it now.
+                       // if we are constructing this on the fly like here,
+                       // make sure to release newobj->GetParent(), and things will run shipshape
+                       delete static_cast<BL_DeformableGameObject*>( newobj )->m_pDeformer;
                        
-                       ((BL_DeformableGameObject*)newobj)->m_pDeformer = skindeformer;
+                       BL_SkinDeformer* skindeformer = new BL_SkinDeformer(
+                               oldblendobj, blendobj,
+                               static_cast<BL_SkinMeshObject*>(mesh),
+                               true, // release ref count to BL_ArmatureObject, leak otherwise
+                               static_cast<BL_ArmatureObject*>(newobj->GetParent())
+                       );
+                       static_cast<BL_DeformableGameObject*>( newobj )->m_pDeformer = skindeformer;
                }
                else if (((Mesh*)blendobj->data)->dvert) {
-                       BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(oldblendobj, (BL_SkinMeshObject*)mesh,oldblendobj->parent);
-                       
+                       BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(oldblendobj, (BL_SkinMeshObject*)mesh );
+
                        // FIXME: should the old m_pDeformer be deleted?
                        // delete ((BL_DeformableGameObject*)newobj)->m_pDeformer
-                       
                        ((BL_DeformableGameObject*)newobj)->m_pDeformer = meshdeformer;
                }
        }
@@ -832,48 +851,48 @@ void KX_Scene::UpdateMeshTransformations()
        }
 }
 
-void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty)
+void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam)
 {
        int intersect = KX_Camera::INTERSECT;
        KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
        bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right();
        
        /* If the camera is inside the box, assume intersect. */
-       if (dotest && !node->inside(GetActiveCamera()->NodeGetWorldPosition()))
+       if (dotest && !node->inside( cam->NodeGetWorldPosition()))
        {
                MT_Scalar radius = node->Radius();
                MT_Point3 centre = node->Centre();
                
-               intersect = GetActiveCamera()->SphereInsideFrustum(centre, radius); 
+               intersect =  cam->SphereInsideFrustum(centre, radius); 
                
                if (intersect == KX_Camera::INTERSECT)
                {
                        MT_Point3 box[8];
                        node->get(box);
-                       intersect = GetActiveCamera()->BoxInsideFrustum(box);
+                       intersect = cam->BoxInsideFrustum(box);
                }
        }
 
        switch (intersect)
        {
                case KX_Camera::OUTSIDE:
-                       MarkSubTreeVisible(node, rasty, false);
+                       MarkSubTreeVisible(node, rasty, false, cam);
                        break;
                case KX_Camera::INTERSECT:
                        if (gameobj)
-                               MarkVisible(rasty, gameobj);
+                               MarkVisible(rasty, gameobj,cam);
                        if (node->Left())
-                               MarkVisible(node->Left(), rasty);
+                               MarkVisible(node->Left(), rasty,cam);
                        if (node->Right())
-                               MarkVisible(node->Right(), rasty);
+                               MarkVisible(node->Right(), rasty,cam);
                        break;
                case KX_Camera::INSIDE:
-                       MarkSubTreeVisible(node, rasty, true);
+                       MarkSubTreeVisible(node, rasty, true,cam);
                        break;
        }
 }
 
-void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible)
+void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam)
 {
        if (node->Client())
        {
@@ -883,7 +902,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
                        if (visible)
                        {
                                int nummeshes = gameobj->GetMeshCount();
-                               MT_Transform t( GetActiveCamera()->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
+                               MT_Transform t( cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
        
                                
                                for (int m=0;m<nummeshes;m++)
@@ -896,18 +915,18 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
                }
        }
        if (node->Left())
-               MarkSubTreeVisible(node->Left(), rasty, visible);
+               MarkSubTreeVisible(node->Left(), rasty, visible,cam);
        if (node->Right())
-               MarkSubTreeVisible(node->Right(), rasty, visible);
+               MarkSubTreeVisible(node->Right(), rasty, visible,cam);
 }
 
-void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
+void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera*  cam)
 {
        // User (Python/Actuator) has forced object invisible...
        if (!gameobj->GetVisible())
                return;
        // If Frustum culling is off, the object is always visible.
-       bool vis = !GetActiveCamera()->GetFrustumCulling();
+       bool vis = !cam->GetFrustumCulling();
        
        // If the camera is inside this node, then the object is visible.
        if (!vis)
@@ -920,7 +939,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
        {
                MT_Vector3 scale = gameobj->GetSGNode()->GetWorldScaling();
                MT_Scalar radius = fabs(scale[scale.closestAxis()] * gameobj->GetSGNode()->Radius());
-               switch (GetActiveCamera()->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
+               switch (cam->SphereInsideFrustum(gameobj->NodeGetWorldPosition(), radius))
                {
                        case KX_Camera::INSIDE:
                                vis = true;
@@ -932,7 +951,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
                                // Test the object's bound box against the view frustum.
                                MT_Point3 box[8];
                                gameobj->GetSGNode()->getBBox(box); 
-                               vis = GetActiveCamera()->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
+                               vis = cam->BoxInsideFrustum(box) != KX_Camera::OUTSIDE;
                                break;
                }
        }
@@ -940,7 +959,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
        if (vis)
        {
                int nummeshes = gameobj->GetMeshCount();
-               MT_Transform t(GetActiveCamera()->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
+               MT_Transform t(cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
                
                for (int m=0;m<nummeshes;m++)
                {
@@ -955,20 +974,20 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
        }
 }
 
-void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty)
+void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam)
 {
 // FIXME: When tree is operational
 #if 1
        // do this incrementally in the future
        for (int i = 0; i < m_objectlist->GetCount(); i++)
        {
-               MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)));
+               MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam);
        }
 #else
-       if (GetActiveCamera()->GetFrustumCulling())
-               MarkVisible(m_objecttree, rasty);
+       if (cam->GetFrustumCulling())
+               MarkVisible(m_objecttree, rasty, cam);
        else
-               MarkSubTreeVisible(m_objecttree, rasty, true);
+               MarkSubTreeVisible(m_objecttree, rasty, true, cam);
 #endif
 }
 
index 7203fa8..4bcfb3e 100644 (file)
@@ -248,9 +248,9 @@ protected:
        /**
         * Visibility testing functions.
         */
-       void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty);
-       void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible);
-       void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj);
+       void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam);
+       void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam);
+       void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam);
 
        double                          m_suspendedtime;
        double                          m_suspendeddelta;
@@ -322,6 +322,10 @@ public:
        GetTimeEventManager(
        );
 
+               set<class KX_Camera*>*
+       GetCameras(
+       );
 
        /** Find a camera in the scene by pointer. */
                KX_Camera*              
@@ -450,7 +454,7 @@ public:
        void SetNetworkScene(NG_NetworkScene *newScene);
        void SetWorldInfo(class KX_WorldInfo* wi);
        KX_WorldInfo* GetWorldInfo();
-       void CalculateVisibleMeshes(RAS_IRasterizer* rasty);
+       void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam);
        void UpdateMeshTransformations();
        KX_Camera* GetpCamera();
        SND_Scene* GetSoundScene();
index 7683ce1..b06e9ee 100644 (file)
@@ -70,6 +70,10 @@ PyMethodDef KX_VertexProxy::Methods[] = {
 {"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS},
 {"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS},
 {"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS},
+
+{"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_VARARGS},
+{"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS},
+
 {"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS},
 {"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS},
 {"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS},
@@ -216,6 +220,22 @@ int    KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
                m_vertex->SetUV(uv);
                return 0;
        }
+
+       // uv
+       MT_Point2 uv2 = m_vertex->getUV2();
+       if (attr == "u2")
+       {
+               uv[0] = val;
+               m_vertex->SetUV2(uv);
+               return 0;
+       }
+
+       if (attr == "v2")
+       {
+               uv[1] = val;
+               m_vertex->SetUV2(uv);
+               return 0;
+       }
        
        // col
        unsigned int icol = *((const unsigned int *)m_vertex->getRGBA());
@@ -373,5 +393,31 @@ PyObject* KX_VertexProxy::PySetUV(PyObject*,
        return NULL;
 }
 
+PyObject* KX_VertexProxy::PyGetUV2(PyObject*, 
+                              PyObject*, 
+                              PyObject*)
+{
+       return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
+}
+
+PyObject* KX_VertexProxy::PySetUV2(PyObject*, 
+                              PyObject* args, 
+                              PyObject*)
+{
+       MT_Point2 vec;
+       unsigned int unit=0;
+       PyObject* list=0;
+       if(PyArg_ParseTuple(args, "Oi", &list, &unit))
+       {
+               if (PyVecTo(list, vec))
+               {
+                       m_vertex->SetFlag((m_vertex->getFlag()|TV_2NDUV));
+                       m_vertex->SetUnit(unit);
+                       m_vertex->SetUV2(vec);
+                       Py_Return;
+               }
+       }
+       return NULL;
+}
 
 
index bf3e198..49fa8ca 100644 (file)
@@ -63,6 +63,10 @@ public:
        KX_PYMETHOD(KX_VertexProxy,SetXYZ);
        KX_PYMETHOD(KX_VertexProxy,GetUV);
        KX_PYMETHOD(KX_VertexProxy,SetUV);
+       
+       KX_PYMETHOD(KX_VertexProxy,GetUV2);
+       KX_PYMETHOD(KX_VertexProxy,SetUV2);
+
        KX_PYMETHOD(KX_VertexProxy,GetRGBA);
        KX_PYMETHOD(KX_VertexProxy,SetRGBA);
        KX_PYMETHOD(KX_VertexProxy,GetNormal);
index 6b8eac9..ecc0c04 100644 (file)
@@ -53,6 +53,10 @@ public:
        virtual float   getMistColorGreen()=0;
        virtual float   getMistColorBlue()=0;
 
+       virtual float   getAmbientColorRed()=0;
+       virtual float   getAmbientColorGreen()=0;
+       virtual float   getAmbientColorBlue()=0;
+
        virtual void    setMistStart(float)=0;
        virtual void    setMistDistance(float)=0;
        virtual void    setMistColorRed(float)=0;
index 4f6d19a..6bcbab5 100644 (file)
@@ -45,6 +45,7 @@ CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include
 CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include
 CPPFLAGS += -I$(NAN_SOLID)/include
 CPPFLAGS += -I$(NAN_BULLET)/include
+CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
 CPPFLAGS += -I../Rasterizer -I../GameLogic -I../SceneGraph
 CPPFLAGS += -I../BlenderRoutines -I../Expressions
 CPPFLAGS += -I../../kernel/gen_system
index 7051f7e..39a7408 100644 (file)
@@ -58,7 +58,9 @@ source_files = ['KX_WorldIpoController.cpp',
                 'KX_CameraIpoSGController.cpp',
                 'KX_CameraActuator.cpp',
                 'KX_Camera.cpp',
-                'KX_BulletPhysicsController.cpp'
+                'KX_BulletPhysicsController.cpp',
+                'KX_BlenderMaterial.cpp',
+                'KX_MaterialIpoController.cpp',
                 ]
 
 if user_options_dict['USE_PHYSICS'] == 'solid':
index 4ce072d..091e78c 100644 (file)
@@ -141,10 +141,17 @@ void RAS_BucketManager::Renderbuckets(
        }
        
        for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
+       {
+               if((*bucket)->GetPolyMaterial()->IsZSort())
+                       rasty->SetAlphaTest(true);
+               else
+                       rasty->SetAlphaTest(false);
+
                (*bucket)->Render(cameratrans,rasty,rendertools);
-       
+       }
+       rasty->SetAlphaTest(false);
+
        RenderAlphaBuckets(cameratrans, rasty, rendertools);    
-       
        RAS_MaterialBucket::EndFrame();
 }
 
index a424502..69a43dd 100644 (file)
@@ -38,12 +38,23 @@ struct RAS_CameraData
        float m_clipstart;
        float m_clipend;
        bool m_perspective;
-       
-       RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true) :
+       bool m_viewport;
+       int m_viewportleft;
+       int m_viewportbottom;
+       int m_viewportright;
+       int m_viewporttop;
+
+       RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true,
+       bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) :
                m_lens(lens),
                m_clipstart(clipstart),
                m_clipend(clipend),
-               m_perspective(perspective)
+               m_perspective(perspective),
+               m_viewport(viewport),
+               m_viewportleft(viewportleft),
+               m_viewportbottom(viewportbottom),
+               m_viewportright(viewportright),
+               m_viewporttop(viewporttop)
        {
        }
 };
index 330f964..b5882bd 100644 (file)
@@ -57,7 +57,10 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
                m_zsort(zsort),
                m_lightlayer(lightlayer),
                m_bIsTriangle(bIsTriangle),
-               m_polymatid(m_newpolymatid++)
+               m_polymatid(m_newpolymatid++),
+               m_flag(0),
+               m_enabled(0),
+               m_multimode(0)
 {
        m_shininess = 35.0;
        m_specular = MT_Vector3(0.5,0.5,0.5);
@@ -68,18 +71,32 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
 
 bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
 {
-       return (
-                       this->m_tile            ==              lhs.m_tile &&
-                       this->m_tilexrep        ==              lhs.m_tilexrep &&
-                       this->m_tileyrep        ==              lhs.m_tileyrep &&
-                       this->m_transparant     ==              lhs.m_transparant &&
-                       this->m_zsort           ==              lhs.m_zsort &&
-                       this->m_drawingmode     ==              lhs.m_drawingmode &&
-                       this->m_bIsTriangle     ==              lhs.m_bIsTriangle &&
-                       this->m_lightlayer      ==              lhs.m_lightlayer &&
+       if(m_flag &RAS_BLENDERMAT)
+       {
+               return (
+                       this->m_multimode                       ==              lhs.m_multimode &&
+                       this->m_flag                            ==              lhs.m_flag              &&
+                       this->m_drawingmode                     ==              lhs.m_drawingmode &&
+                       this->m_lightlayer                      ==              lhs.m_lightlayer &&
                        this->m_texturename.hash()      ==              lhs.m_texturename.hash() &&
                        this->m_materialname.hash() ==          lhs.m_materialname.hash()
-       );
+               );
+       }
+       else
+       {
+               return (
+                               this->m_tile            ==              lhs.m_tile &&
+                               this->m_tilexrep        ==              lhs.m_tilexrep &&
+                               this->m_tileyrep        ==              lhs.m_tileyrep &&
+                               this->m_transparant     ==              lhs.m_transparant &&
+                               this->m_zsort           ==              lhs.m_zsort &&
+                               this->m_drawingmode     ==              lhs.m_drawingmode &&
+                               this->m_bIsTriangle     ==              lhs.m_bIsTriangle &&
+                               this->m_lightlayer      ==              lhs.m_lightlayer &&
+                               this->m_texturename.hash()      ==              lhs.m_texturename.hash() &&
+                               this->m_materialname.hash() ==          lhs.m_materialname.hash()
+               );
+       }
 }
 
 bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const
@@ -130,4 +147,14 @@ const STR_String& RAS_IPolyMaterial::GetTextureName() const
        return m_texturename;
 }
 
+const unsigned int     RAS_IPolyMaterial::GetFlag() const
+{
+       return m_flag;
+}
+const unsigned int     RAS_IPolyMaterial::GetEnabled() const
+{
+       return m_enabled;
+}
+
+
 unsigned int RAS_IPolyMaterial::m_newpolymatid = 0;
index b039b51..3e296c2 100644 (file)
 
 class RAS_IRasterizer;
 
+enum MaterialProps
+{
+       RAS_ZSORT               =1,
+       RAS_TRANSPARENT =2,
+       RAS_TRIANGLE    =4,
+       RAS_MULTITEX    =8,
+       RAS_MULTILIGHT  =16,
+       RAS_BLENDERMAT  =32,
+       RAS_GLSHADER    =64,
+       RAS_AUTOGEN             =128,
+       RAS_NORMAL              =256,
+       RAS_DEFMULTI    =512
+};
+
 /**
  * Material properties.
  */
@@ -52,18 +66,21 @@ class RAS_IPolyMaterial
 protected:
        STR_HashedString                m_texturename;
        STR_HashedString                m_materialname; //also needed for touchsensor  
-       int                             m_tile;
-       int                             m_tilexrep,m_tileyrep;
-       int                             m_drawingmode;  // tface->mode
-       bool                            m_transparant;
-       bool                            m_zsort;
-       int                             m_lightlayer;
-       bool                            m_bIsTriangle;
+       int                                             m_tile;
+       int                                             m_tilexrep,m_tileyrep;
+       int                                             m_drawingmode;  // tface->mode
+       bool                                    m_transparant;
+       bool                                    m_zsort;
+       int                                             m_lightlayer;
+       bool                                    m_bIsTriangle;
        
        unsigned int                    m_polymatid;
-       
        static unsigned int             m_newpolymatid;
-       
+
+       // will move...
+       unsigned int                    m_flag;//MaterialProps
+       unsigned int                    m_enabled;// enabled for this mat 
+       int                                             m_multimode; // sum of values
 public:
 
        MT_Vector3                      m_diffuse;
@@ -124,6 +141,14 @@ public:
        int                                     GetDrawingMode() const;
        const STR_String&       GetMaterialName() const;
        const STR_String&       GetTextureName() const;
+       const unsigned int      GetFlag() const;
+       const unsigned int      GetEnabled() const;
+       
+       /*
+        * PreCalculate texture gen
+        */
+       virtual void OnConstruction(){}
+
 };
 
 inline  bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial & lhs)
index 03c7e1d..68a9429 100644 (file)
@@ -219,6 +219,25 @@ public:
                                                        bool useObjectColor,
                                                        const MT_Vector4& rgbacolor)=0;
 
+       virtual void IndexPrimitivesMulti( 
+                                               const vecVertexArray& vertexarrays,
+                                               const vecIndexArrays & indexarrays,
+                                               int mode,
+                                               class RAS_IPolyMaterial* polymat,
+                                               class RAS_IRenderTools* rendertools,
+                                               bool useObjectColor,
+                                               const MT_Vector4& rgbacolor)=0;
+
+       virtual void IndexPrimitivesMulti_Ex( 
+                                               const vecVertexArray& vertexarrays,
+                                               const vecIndexArrays & indexarrays,
+                                               int mode,
+                                               class RAS_IPolyMaterial* polymat,
+                                               class RAS_IRenderTools* rendertools,
+                                               bool useObjectColor,
+                                               const MT_Vector4& rgbacolor)=0;
+
+
        virtual void    SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0;
        /* This one should become our final version, methinks. */
        /**
@@ -328,6 +347,22 @@ public:
                                                           float difY,
                                                           float difZ,
                                                           float diffuse)=0;
+       /**
+        * Sets the emissive colour component of the lighting equation.
+        */ 
+       virtual void    SetEmissive(float eX,
+                                                               float eY,
+                                                               float eZ,
+                                                               float e
+                                                          )=0;
+       
+       virtual void    SetAmbientColor(float red, float green, float blue)=0;
+       virtual void    SetAmbient(float factor)=0;
+       /**
+        * Sets alpha testing
+        */
+       virtual void    SetAlphaTest(bool enable)=0;
+
        /**
         * Sets a polygon offset.  z depth will be: z1 = mult*z0 + add
         */
index 7f9f5b4..b1d3232 100644 (file)
@@ -177,7 +177,13 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I
        if (!rasty->SetMaterial(*m_material))
                return false;
        
-       bool dolights = m_material->GetDrawingMode()&16;
+       bool dolights = false;
+       const unsigned int flag = m_material->GetFlag();
+
+       if( flag & RAS_BLENDERMAT)
+               dolights = flag &RAS_MULTILIGHT;
+       else
+               dolights = m_material->GetDrawingMode()&16;
 
        if ((rasty->GetDrawingMode() <= RAS_IRasterizer::KX_SOLID) || !dolights)
        {
@@ -229,6 +235,35 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
                                ms.m_RGBAcolor);
 
        }
+
+       // for using glMultiTexCoord
+       else if(m_material->GetFlag() & RAS_MULTITEX )
+       {
+               rasty->IndexPrimitivesMulti(
+                               ms.m_mesh->GetVertexCache(m_material), 
+                               ms.m_mesh->GetIndexCache(m_material), 
+                               drawmode,
+                               m_material,
+                               rendertools,
+                               ms.m_bObjectColor,
+                               ms.m_RGBAcolor
+                               );
+       }
+
+       // for using glMultiTexCoord on deformer
+       else if(m_material->GetFlag() & RAS_DEFMULTI )
+       {
+               rasty->IndexPrimitivesMulti(
+                      &