BGE: Some as of yet unmerged work I did in the Swiss branch. These changes include:
authorMitchell Stokes <mogurijin@gmail.com>
Tue, 18 Dec 2012 20:56:25 +0000 (20:56 +0000)
committerMitchell Stokes <mogurijin@gmail.com>
Tue, 18 Dec 2012 20:56:25 +0000 (20:56 +0000)
  * Cleaning up the conversion code to avoid a per-face material conversion. Materials are now stored in buckets and only converted if a new material is found. This replaces some of Campbell's earlier work on the subject. His work wasn't as thorough, but it was much safer for a release.
  * Shaders are only compiled for LibLoaded materials once. Before they could be compiled twice, which could really slow things down.
  * Refactoring the rasterizer code to use a strategy design pattern to handle different geometry rendering methods such as immediate mode, vertex arrays and vertex buffer objects. VBOs are added, but they will be disabled in a following commit since they are still slower than vertex arrays with display lists. However, VBOs are still useful for mobile, so it's good to keep them around.
  * Better multi-uv support. The BGE should now be able to handle more than two UV layers, which should help it better match the viewport.

46 files changed:
release/scripts/startup/bl_ui/properties_game.py
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_BlenderDataConversion.h
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.h
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/BL_BlenderShader.cpp
source/gameengine/Ketsji/BL_Material.cpp
source/gameengine/Ketsji/BL_Material.h
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_ISceneConverter.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_VertexProxy.cpp
source/gameengine/Ketsji/KX_VertexProxy.h
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h [moved from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h with 57% similarity]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h [new file with mode: 0644]
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp [deleted file]
source/gameengine/Rasterizer/RAS_TexVert.cpp
source/gameengine/Rasterizer/RAS_TexVert.h
source/gameengine/Rasterizer/RAS_texmatrix.cpp

index bf0c9eb762a4a61be7e6c16ed250049fea65dd7e..42f651de6dfe20e2fc45022cedfa37289f668eaf 100644 (file)
@@ -402,14 +402,18 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
         layout = self.layout
 
         gs = context.scene.game_settings
-
-        row = layout.row()
-        row.prop(gs, "use_frame_rate")
-        row.prop(gs, "restrict_animation_updates")
-
+        col = layout.column()
+        row = col.row()
+        col = row.column()
+        col.prop(gs, "use_frame_rate")
+        col.prop(gs, "restrict_animation_updates")
+        col = row.column()
+        col.prop(gs, "use_display_lists")
+        col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
+               
         row = layout.row()
-        row.prop(gs, "use_display_lists")
-
+        row.prop(gs, "raster_storage")
+        
         row = layout.row()
         row.label("Exit Key")
         row.prop(gs, "exit_key", text="", event=True)
index b3aabf1265a97e88c81a89fafd20926c74c7c6db..2edbf14eb6c3c025dbedbea05bd4399acbb90070 100644 (file)
@@ -636,7 +636,8 @@ typedef struct GameData {
        short physicsEngine;
        short exitkey, pad;
        short ticrate, maxlogicstep, physubstep, maxphystep;
-       short obstacleSimulation, pad1;
+       short obstacleSimulation;
+       short raster_storage;
        float levelHeight;
        float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2;
 } GameData;
@@ -663,6 +664,12 @@ typedef struct GameData {
 #define OBSTSIMULATION_TOI_rays                1
 #define OBSTSIMULATION_TOI_cells       2
 
+/* Raster storage */
+#define RAS_STORE_AUTO         0
+#define RAS_STORE_IMMEDIATE    1
+#define RAS_STORE_VA           2
+#define RAS_STORE_VBO          3
+
 /* GameData.flag */
 #define GAME_RESTRICT_ANIM_UPDATES                     (1 << 0)
 #define GAME_ENABLE_ALL_FRAMES                         (1 << 1)
index fad4a2035fd940f04f634f663993695009db610a..03f566b5bcab7229a9a4156270e8720961b9c9b7 100644 (file)
@@ -2444,6 +2444,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
                {0, NULL, 0, NULL, NULL}
        };
 
+       static EnumPropertyItem storage_items[] ={
+               {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
+               {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
+               {RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Moderate performance, requires at least OpenGL 1.1"},
+               {RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects", "Best performance, requires at least OpenGL 1.4"},
+               {0, NULL, 0, NULL, NULL}};
+
        srna = RNA_def_struct(brna, "SceneGameData", NULL);
        RNA_def_struct_sdna(srna, "GameData");
        RNA_def_struct_nested(brna, srna, "Scene");
@@ -2479,6 +2486,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Exit Key",  "The key that exits the Game Engine");
        RNA_def_property_update(prop, NC_SCENE, NULL);
        
+       prop= RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "raster_storage");
+       RNA_def_property_enum_items(prop, storage_items);
+       RNA_def_property_ui_text(prop, "Storage",  "Sets the storage mode used by the rasterizer");
+       RNA_def_property_update(prop, NC_SCENE, NULL);
+       
        /* Do we need it here ? (since we already have it in World */
        prop = RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "freqplay");
index 6807f531f0a76f6fdbf9db4d2a7ad0a352605ca6..9f788b29ac655c7ce765a7dfac2da68b9e448427 100644 (file)
@@ -58,7 +58,6 @@
 
 #include "RAS_GLExtensionManager.h"
 #include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
 #include "RAS_ListRasterizer.h"
 
 #include "NG_LoopBackNetworkDeviceInterface.h"
@@ -287,16 +286,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
                RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
                RAS_IRasterizer* rasterizer = NULL;
                
-               if (displaylists) {
-                       if (GLEW_VERSION_1_1 && !novertexarrays)
-                               rasterizer = new RAS_ListRasterizer(canvas, true, true);
-                       else
-                               rasterizer = new RAS_ListRasterizer(canvas);
-               }
-               else if (GLEW_VERSION_1_1 && !novertexarrays)
-                       rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
+               //Don't use displaylists with VBOs
+               //If auto starts using VBOs, make sure to check for that here
+               if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
+                       rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
                else
-                       rasterizer = new RAS_OpenGLRasterizer(canvas);
+                       rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);
                
                // create the inputdevices
                KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
index ab0630bf3987d2b2954a3e457273665b352977b2..15fc5ba76c7f12028383f0c7d4490ff43bed7aba 100644 (file)
@@ -423,55 +423,61 @@ static void SetDefaultLightMode(Scene* scene)
 
 
 // --
-static void GetRGB(
-        const bool use_mcol,
-        MFace *mface,
-        MCol *mmcol,
-        Material *mat,
-        unsigned int &c0,
-        unsigned int &c1,
-        unsigned int &c2,
-        unsigned int &c3)
+static void GetRGB(short type,
+       MFace* mface,
+       MCol* mmcol,
+       Material *mat,
+       unsigned int c[4])
 {
        unsigned int color = 0xFFFFFFFFL;
-       if (use_mcol) {
-               // vertex colors
-
-               if (mmcol) {
-                       c0 = KX_Mcol2uint_new(mmcol[0]);
-                       c1 = KX_Mcol2uint_new(mmcol[1]);
-                       c2 = KX_Mcol2uint_new(mmcol[2]);
+       switch (type) {
+               case 0: // vertex colors
+               {
+                       if (mmcol) {
+                               c[0] = KX_Mcol2uint_new(mmcol[0]);
+                               c[1] = KX_Mcol2uint_new(mmcol[1]);
+                               c[2] = KX_Mcol2uint_new(mmcol[2]);
+                               if (mface->v4)
+                                       c[3] = KX_Mcol2uint_new(mmcol[3]);
+                       }
+                       else { // backup white
+                               c[0] = KX_rgbaint2uint_new(color);
+                               c[1] = KX_rgbaint2uint_new(color);
+                               c[2] = KX_rgbaint2uint_new(color);
+                               if (mface->v4)
+                                       c[3] = KX_rgbaint2uint_new( color );
+                       }
+               } 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.0f);
+                               col_converter.cp[2] = (unsigned char) (mat->g     * 255.0f);
+                               col_converter.cp[1] = (unsigned char) (mat->b     * 255.0f);
+                               col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
+                               color = col_converter.integer;
+                       }
+                       c[0] = KX_rgbaint2uint_new(color);
+                       c[1] = KX_rgbaint2uint_new(color);
+                       c[2] = KX_rgbaint2uint_new(color);
                        if (mface->v4)
-                               c3 = KX_Mcol2uint_new(mmcol[3]);
-               }
-               else { // backup white
-                       c0 = KX_rgbaint2uint_new(color);
-                       c1 = KX_rgbaint2uint_new(color);
-                       c2 = KX_rgbaint2uint_new(color);
+                               c[3] = KX_rgbaint2uint_new(color);
+               } break;
+               
+               default: // white
+               {
+                       c[0] = KX_rgbaint2uint_new(color);
+                       c[1] = KX_rgbaint2uint_new(color);
+                       c[2] = KX_rgbaint2uint_new(color);
                        if (mface->v4)
-                               c3 = KX_rgbaint2uint_new( color );
-               }
-       }
-       else {
-               // material rgba
-               if (mat) {
-                       union {
-                               unsigned char cp[4];
-                               unsigned int integer;
-                       } col_converter;
-                       col_converter.cp[3] = (unsigned char) (mat->r     * 255.0f);
-                       col_converter.cp[2] = (unsigned char) (mat->g     * 255.0f);
-                       col_converter.cp[1] = (unsigned char) (mat->b     * 255.0f);
-                       col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
-                       color = col_converter.integer;
-               }
-               // backup white is fallback
-
-               c0 = KX_rgbaint2uint_new(color);
-               c1 = KX_rgbaint2uint_new(color);
-               c2 = KX_rgbaint2uint_new(color);
-               if (mface->v4)
-                       c3 = KX_rgbaint2uint_new(color);
+                               c[3] = KX_rgbaint2uint_new(color);
+               } break;
        }
 }
 
@@ -480,42 +486,67 @@ typedef struct MTF_localLayer {
        const char *name;
 } MTF_localLayer;
 
-static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4])
+static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX])
 {
-       uv[0].setValue(tface->uv[0]);
-       uv[1].setValue(tface->uv[1]);
-       uv[2].setValue(tface->uv[2]);
-       if (mface->v4) {
-               uv[3].setValue(tface->uv[3]);
+       int unit = 0;
+       if (tface)
+       {
+                       
+               uvs[0][0].setValue(tface->uv[0]);
+               uvs[1][0].setValue(tface->uv[1]);
+               uvs[2][0].setValue(tface->uv[2]);
+
+               if (mface->v4) 
+                       uvs[3][0].setValue(tface->uv[3]);
        }
-}
+       else
+       {
+               uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f);
+       }
+       
+       for (int vind = 0; vind<MAXTEX; vind++)
+       {
+               BL_Mapping &map = material->mapping[vind];
 
-static void GetUV(
-        MFace *mface,
-        MTFace *tface,
-        MTF_localLayer *layers,
-        const int layer_uv[2],
-        MT_Point2 uv[4],
-        MT_Point2 uv2[4])
-{
-       bool validface  = (tface != NULL);
+               if (!(map.mapping & USEUV)) continue;
 
-       uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f);
+               //If no UVSet is specified, try grabbing one from the UV/Image editor
+               if (map.uvCoName.IsEmpty() && tface)
+               {                       
+                       uvs[0][unit].setValue(tface->uv[0]);
+                       uvs[1][unit].setValue(tface->uv[1]);
+                       uvs[2][unit].setValue(tface->uv[2]);
 
-       /* No material, what to do? let's see what is in the UV and set the material accordingly
-        * light and visible is always on */
-       if (layer_uv[0] != -1) {
-               tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv);
-               if (layer_uv[1] != -1) {
-                       tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2);
+                       if (mface->v4) 
+                               uvs[3][unit].setValue(tface->uv[3]);
+
+                       ++unit;
+                       continue;
+               }
+
+
+               for (int lay=0; lay<MAX_MTFACE; lay++)
+               {
+                       MTF_localLayer& layer = layers[lay];
+                       if (layer.face == 0) break;
+
+                       if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
+                       {
+                               MT_Point2 uvSet[4];
+
+                               uvs[0][unit].setValue(layer.face->uv[0]);
+                               uvs[1][unit].setValue(layer.face->uv[1]);
+                               uvs[2][unit].setValue(layer.face->uv[2]);
+
+                               if (mface->v4) 
+                                       uvs[3][unit].setValue(layer.face->uv[3]);
+                               else
+                                       uvs[3][unit].setValue(0.0f, 0.0f);
+
+                               ++unit;
+                               break;
+                       }
                }
-       }
-       else if (validface) {
-               tface_to_uv_bge(mface, tface, uv);
-       }
-       else {
-               // nothing at all
-               uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f);
        }
 }
 
@@ -526,25 +557,29 @@ static bool ConvertMaterial(
        MTFace* tface,  
        const char *tfaceName,
        MFace* mface, 
-       MCol* mmcol,  /* only for text, use first mcol, weak */
-       MTF_localLayer *layers,
-       int layer_uv[2],
-       const bool glslmat)
+       MCol* mmcol,
+       bool glslmat)
 {
        material->Initialize();
-       int numchan =   -1, texalpha = 0;
+       int texalpha = 0;
        bool validmat   = (mat!=0);
        bool validface  = (tface!=0);
        
+       short type = 0;
+       if ( validmat )
+               type = 1; // material color 
+       
        material->IdMode = DEFAULT_BLENDER;
        material->glslmat = (validmat)? glslmat: false;
        material->materialindex = mface->mat_nr;
 
-       /* default value for being unset */
-       layer_uv[0] = layer_uv[1] = -1;
-
        // --------------------------------
        if (validmat) {
+
+               // use vertex colors by explicitly setting
+               if (mat->mode &MA_VERTEXCOLP || glslmat)
+                       type = 0;
+
                // use lighting?
                material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
                material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
@@ -552,7 +587,6 @@ static bool ConvertMaterial(
                // cast shadows?
                material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
                MTex *mttmp = 0;
-               numchan = getNumTexChannels(mat);
                int valid_index = 0;
                
                /* In Multitexture use the face texture if and only if
@@ -561,12 +595,9 @@ static bool ConvertMaterial(
                bool facetex = false;
                if (validface && mat->mode &MA_FACETEXTURE) 
                        facetex = true;
-
-               numchan = numchan>MAXTEX?MAXTEX:numchan;
-               if (facetex && numchan == 0) numchan = 1;
        
                // foreach MTex
-               for (int i=0; i<numchan; i++) {
+               for (int i=0; i<MAXTEX; i++) {
                        // use face tex
 
                        if (i==0 && facetex ) {
@@ -798,14 +829,11 @@ static bool ConvertMaterial(
                material->ras_mode |= USE_LIGHT;
        }
 
-       const char *uvName = "", *uv2Name = "";
-
        /* No material, what to do? let's see what is in the UV and set the material accordingly
         * light and visible is always on */
        if ( validface ) {
                material->tile  = tface->tile;
-               uvName = tfaceName;
-       } 
+       }
        else {
                // nothing at all
                material->alphablend    = GEMAT_SOLID;
@@ -826,45 +854,19 @@ static bool ConvertMaterial(
                material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0;
        }
 
-       // get uv sets
-       if (validmat) {
-               bool isFirstSet = true;
-
-               // only two sets implemented, but any of the eight 
-               // sets can make up the two layers
-               for (int vind = 0; vind<material->num_enabled; vind++) {
-                       BL_Mapping &map = material->mapping[vind];
+       // XXX The RGB values here were meant to be temporary storage for the conversion process,
+       // but fonts now make use of them too, so we leave them in for now.
+       unsigned int rgb[4];
+       GetRGB(type,mface,mmcol,mat,rgb);
 
-                       if (map.uvCoName.IsEmpty()) {
-                               isFirstSet = false;
-                       }
-                       else {
-                               for (int lay=0; lay<MAX_MTFACE; lay++) {
-                                       MTF_localLayer& layer = layers[lay];
-                                       if (layer.face == 0) break;
-
-                                       if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) {
-                                               if (isFirstSet) {
-                                                       layer_uv[0] = lay;
-                                                       isFirstSet = false;
-                                                       uvName = layer.name;
-                                               }
-                                               else if (strcmp(layer.name, uvName) != 0) {
-                                                       layer_uv[1] = lay;
-                                                       map.mapping |= USECUSTOMUV;
-                                                       uv2Name = layer.name;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (validmat && mmcol) { /* color is only for text */
-               material->m_mcol = *(unsigned int *)mmcol;
+       // swap the material color, so MCol on bitmap font works
+       if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT))
+       {
+               rgb[0] = KX_rgbaint2uint_new(rgb[0]);
+               rgb[1] = KX_rgbaint2uint_new(rgb[1]);
+               rgb[2] = KX_rgbaint2uint_new(rgb[2]);
+               rgb[3] = KX_rgbaint2uint_new(rgb[3]);
        }
-       material->SetUVLayerName(uvName);
-       material->SetUVLayerName2(uv2Name);
 
        if (validmat)
                material->matname       =(mat->id.name);
@@ -879,8 +881,189 @@ static bool ConvertMaterial(
        return true;
 }
 
+RAS_MaterialBucket* material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+{
+       RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(ma);
+       BL_Material* bl_mat = converter->FindCachedBlenderMaterial(ma);
+       KX_BlenderMaterial* kx_blmat = NULL;
+       KX_PolygonMaterial* kx_polymat = NULL;
+               
+       if (converter->GetMaterials()) {
+               /* do Blender Multitexture and Blender GLSL materials */
+
+               /* first is the BL_Material */
+               if (!bl_mat)
+               {
+                       bl_mat = new BL_Material();
+
+                       ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
+                               converter->GetGLSLMaterials());
+
+                       converter->CacheBlenderMaterial(ma, bl_mat);
+               }
+
+
+               short type = (ma) ? ((ma->mode & MA_VERTEXCOLP || bl_mat->glslmat) ? 0 : 1) : 0;
+               GetRGB(type,mface,mcol,ma,rgb);
+
+               GetUVs(bl_mat, layers, mface, tface, uvs);
+                               
+               /* then the KX_BlenderMaterial */
+               if (polymat == NULL)
+               {
+                       kx_blmat = new KX_BlenderMaterial();
+
+                       kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
+                       polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
+                       converter->CachePolyMaterial(ma, polymat);
+               }
+       }
+       else {
+               /* do Texture Face materials */
+               Image* bima = (tface)? (Image*)tface->tpage: NULL;
+               STR_String imastr =  (tface)? (bima? (bima)->id.name : "" ) : "";
+               
+               char alpha_blend=0;
+               short tile=0;
+               int     tilexrep=4,tileyrep = 4;
+
+               /* set material properties - old TexFace */
+               if (ma) {
+                       alpha_blend = ma->game.alpha_blend;
+                       /* Commented out for now. If we ever get rid of
+                               * "Texture Face/Singletexture" we can then think about it */
+
+                       /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
+       #if 0
+                       if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
+                               bima = NULL;
+                               imastr = "";
+                               alpha_blend = GEMAT_SOLID;       
+                       }
+                       else {
+                               alpha_blend = ma->game.alpha_blend;
+                       }
+       #endif
+               }
+               /* check for tface tex to fallback on */
+               else {
+                       if (bima) {
+                               /* see if depth of the image is 32 */
+                               if (BKE_image_has_alpha(bima))
+                                       alpha_blend = GEMAT_ALPHA;
+                               else
+                                       alpha_blend = GEMAT_SOLID;
+                       }
+                       else {
+                               alpha_blend = GEMAT_SOLID;
+                       }
+               }
+
+               if (bima) {
+                       tilexrep = bima->xrep;
+                       tileyrep = bima->yrep;
+               }
+
+               /* set UV properties */
+               if (tface) {
+                       uvs[0][0].setValue(tface->uv[0]);
+                       uvs[1][0].setValue(tface->uv[1]);
+                       uvs[2][0].setValue(tface->uv[2]);
+       
+                       if (mface->v4)
+                               uvs[3][0].setValue(tface->uv[3]);
+
+                       tile = tface->tile;
+               } 
+               else {
+                       /* no texfaces */
+                       tile = 0;
+               }
+
+               /* get vertex colors */
+               if (mcol) {
+                       /* we have vertex colors */
+                       rgb[0] = KX_Mcol2uint_new(mcol[0]);
+                       rgb[1] = KX_Mcol2uint_new(mcol[1]);
+                       rgb[2] = KX_Mcol2uint_new(mcol[2]);
+                                       
+                       if (mface->v4)
+                               rgb[3] = KX_Mcol2uint_new(mcol[3]);
+               }
+               else {
+                       /* no vertex colors, take from material, otherwise white */
+                       unsigned int color = 0xFFFFFFFFL;
+
+                       if (ma)
+                       {
+                               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);
+                                               
+                               color = col_converter.integer;
+                       }
+
+                       rgb[0] = KX_rgbaint2uint_new(color);
+                       rgb[1] = KX_rgbaint2uint_new(color);
+                       rgb[2] = KX_rgbaint2uint_new(color);    
+                                       
+                       if (mface->v4)
+                               rgb[3] = KX_rgbaint2uint_new(color);
+               }
+
+               // only zsort alpha + add
+               bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
+               bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
+               bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
+
+               // don't need zort anymore, deal as if it it's alpha blend
+               if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
+
+               if (polymat == NULL)
+               {
+                       kx_polymat = new KX_PolygonMaterial();
+                       kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
+                               tile, tilexrep, tileyrep, 
+                               alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
+                       polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
+       
+                       if (ma) {
+                               polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+                               polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
+                               polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+                       }
+                       else {
+                               polymat->m_specular.setValue(0.0f,0.0f,0.0f);
+                               polymat->m_shininess = 35.0;
+                       }
+                       
+                       converter->CachePolyMaterial(ma, polymat);
+               }
+       }
+       
+       // see if a bucket was reused or a new one was created
+       // this way only one KX_BlenderMaterial object has to exist per bucket
+       bool bucketCreated; 
+       RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
+       if (bucketCreated) {
+               // this is needed to free up memory afterwards
+               converter->RegisterPolyMaterial(polymat);
+               if (converter->GetMaterials())
+                       converter->RegisterBlenderMaterial(bl_mat);
+       }
+
+       return bucket;
+}
+
 /* blenderobj can be NULL, make sure its checked for */
-RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading)
 {
        RAS_MeshObject *meshobj;
        int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
@@ -910,7 +1093,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
 
        // Extract avaiable layers
        MTF_localLayer *layers =  new MTF_localLayer[MAX_MTFACE];
-       int layer_uv[2];  /* store uv1, uv2 layers */
        for (int lay=0; lay<MAX_MTFACE; lay++) {
                layers[lay].face = 0;
                layers[lay].name = "";
@@ -933,31 +1115,23 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
 
        meshobj->SetName(mesh->id.name + 2);
        meshobj->m_sharedvertex_map.resize(totvert);
-       RAS_IPolyMaterial* polymat = NULL;
-       STR_String imastr;
-       // These pointers will hold persistent material structure during the conversion
-       // to avoid countless allocation/deallocation of memory.
-       BL_Material* bl_mat = NULL;
-       KX_BlenderMaterial* kx_blmat = NULL;
-       KX_PolygonMaterial* kx_polymat = NULL;
 
-       for (int f=0;f<totface;f++,mface++)
-       {
-               Material* ma = 0;
-               bool collider = true;
-               MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
-               MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
-               unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
+       Material* ma = 0;
+       bool collider = true;
+       MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
+       unsigned int rgb[4] = {0};
 
-               MT_Point3 pt0, pt1, pt2, pt3;
-               MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
-               MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
+       MT_Point3 pt[4];
+       MT_Vector3 no[4];
+       MT_Vector4 tan[4];
 
+       for (int f=0;f<totface;f++,mface++)
+       {
                /* get coordinates, normals and tangents */
-               pt0.setValue(mvert[mface->v1].co);
-               pt1.setValue(mvert[mface->v2].co);
-               pt2.setValue(mvert[mface->v3].co);
-               if (mface->v4) pt3.setValue(mvert[mface->v4].co);
+               pt[0].setValue(mvert[mface->v1].co);
+               pt[1].setValue(mvert[mface->v2].co);
+               pt[2].setValue(mvert[mface->v3].co);
+               if (mface->v4) pt[3].setValue(mvert[mface->v4].co);
 
                if (mface->flag & ME_SMOOTH) {
                        float n0[3], n1[3], n2[3], n3[3];
@@ -965,13 +1139,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
                        normal_short_to_float_v3(n0, mvert[mface->v1].no);
                        normal_short_to_float_v3(n1, mvert[mface->v2].no);
                        normal_short_to_float_v3(n2, mvert[mface->v3].no);
-                       no0 = n0;
-                       no1 = n1;
-                       no2 = n2;
+                       no[0] = n0;
+                       no[1] = n1;
+                       no[2] = n2;
 
                        if (mface->v4) {
                                normal_short_to_float_v3(n3, mvert[mface->v4].no);
-                               no3 = n3;
+                               no[3] = n3;
                        }
                }
                else {
@@ -982,16 +1156,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
                        else
                                normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
 
-                       no0 = no1 = no2 = no3 = MT_Vector3(fno);
+                       no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno);
                }
 
                if (tangent) {
-                       tan0 = tangent[f*4 + 0];
-                       tan1 = tangent[f*4 + 1];
-                       tan2 = tangent[f*4 + 2];
+                       tan[0] = tangent[f*4 + 0];
+                       tan[1] = tangent[f*4 + 1];
+                       tan[2] = tangent[f*4 + 2];
 
                        if (mface->v4)
-                               tan3 = tangent[f*4 + 3];
+                               tan[3] = tangent[f*4 + 3];
                }
                if (blenderobj)
                        ma = give_current_material(blenderobj, mface->mat_nr+1);
@@ -1007,171 +1181,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
                        bool visible = true;
                        bool twoside = false;
 
-                       if (converter->GetMaterials()) {
-                               const bool is_bl_mat_new   = (bl_mat == NULL);
-                               //const bool is_kx_blmat_new = (kx_blmat == NULL);
-                               const bool glslmat = converter->GetGLSLMaterials();
-                               const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true;
-                               /* do Blender Multitexture and Blender GLSL materials */
-                               MT_Point2 uv_1[4];
-                               MT_Point2 uv_2[4];
-
-                               /* first is the BL_Material */
-                               if (!bl_mat) {
-                                       bl_mat = new BL_Material();
-                               }
-
-                               /* only */
-                               if (is_bl_mat_new || (bl_mat->material != ma)) {
-                                       ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
-                                                       layers, layer_uv, glslmat);
-                               }
-
-                               /* vertex colors and uv's from the faces */
-                               GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3);
-                               GetUV(mface, tface, layers, layer_uv, uv_1, uv_2);
-
-                               uv0 = uv_1[0]; uv1 = uv_1[1];
-                               uv2 = uv_1[2]; uv3 = uv_1[3];
-
-                               uv20 = uv_2[0]; uv21 = uv_2[1];
-                               uv22 = uv_2[2]; uv23 = uv_2[3];
-                               
-                               /* then the KX_BlenderMaterial */
-                               if (kx_blmat == NULL)
-                                       kx_blmat = new KX_BlenderMaterial();
-
-                               //if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) {
-                                       kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL));
-                               //}
-
-                               polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
-                       }
-                       else {
-                               /* do Texture Face materials */
-                               Image* bima = (tface)? (Image*)tface->tpage: NULL;
-                               imastr =  (tface)? (bima? (bima)->id.name : "" ) : "";
-               
-                               char alpha_blend=0;
-                               short tile=0;
-                               int     tilexrep=4,tileyrep = 4;
-
-                               /* set material properties - old TexFace */
-                               if (ma) {
-                                       alpha_blend = ma->game.alpha_blend;
-                                       /* Commented out for now. If we ever get rid of
-                                        * "Texture Face/Singletexture" we can then think about it */
-
-                                       /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
-#if 0
-                                       if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
-                                               bima = NULL;
-                                               imastr = "";
-                                               alpha_blend = GEMAT_SOLID;       
-                                       }
-                                       else {
-                                               alpha_blend = ma->game.alpha_blend;
-                                       }
-#endif
-                               }
-                               /* check for tface tex to fallback on */
-                               else {
-                                       if (bima) {
-                                               /* see if depth of the image is 32 */
-                                               if (BKE_image_has_alpha(bima))
-                                                       alpha_blend = GEMAT_ALPHA;
-                                               else
-                                                       alpha_blend = GEMAT_SOLID;
-                                       }
-                                       else {
-                                               alpha_blend = GEMAT_SOLID;
-                                       }
-                               }
-
-                               if (bima) {
-                                       tilexrep = bima->xrep;
-                                       tileyrep = bima->yrep;
-                               }
-
-                               /* set UV properties */
-                               if (tface) {
-                                       uv0.setValue(tface->uv[0]);
-                                       uv1.setValue(tface->uv[1]);
-                                       uv2.setValue(tface->uv[2]);
-       
-                                       if (mface->v4)
-                                               uv3.setValue(tface->uv[3]);
-
-                                       tile = tface->tile;
-                               } 
-                               else {
-                                       /* no texfaces */
-                                       tile = 0;
-                               }
-
-                               /* get vertex colors */
-                               if (mcol) {
-                                       /* we have vertex colors */
-                                       rgb0 = KX_Mcol2uint_new(mcol[0]);
-                                       rgb1 = KX_Mcol2uint_new(mcol[1]);
-                                       rgb2 = KX_Mcol2uint_new(mcol[2]);
-                                       
-                                       if (mface->v4)
-                                               rgb3 = KX_Mcol2uint_new(mcol[3]);
-                               }
-                               else {
-                                       /* no vertex colors, take from material, otherwise white */
-                                       unsigned int color = 0xFFFFFFFFL;
-
-                                       if (ma)
-                                       {
-                                               union
-                                               {
-                                                       unsigned char cp[4];
-                                                       unsigned int integer;
-                                               } col_converter;
-                                               
-                                               col_converter.cp[3] = (unsigned char) (ma->r     * 255.0f);
-                                               col_converter.cp[2] = (unsigned char) (ma->g     * 255.0f);
-                                               col_converter.cp[1] = (unsigned char) (ma->b     * 255.0f);
-                                               col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f);
-                                               
-                                               color = col_converter.integer;
-                                       }
-
-                                       rgb0 = KX_rgbaint2uint_new(color);
-                                       rgb1 = KX_rgbaint2uint_new(color);
-                                       rgb2 = KX_rgbaint2uint_new(color);
-                                       
-                                       if (mface->v4)
-                                               rgb3 = KX_rgbaint2uint_new(color);
-                               }
-
-                               // only zsort alpha + add
-                               bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
-                               bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
-                               bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
-
-                               // don't need zort anymore, deal as if it it's alpha blend
-                               if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
-
-                               if (kx_polymat == NULL)
-                                       kx_polymat = new KX_PolygonMaterial();
-                               kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
-                                       tile, tilexrep, tileyrep, 
-                                       alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
-                               polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
-       
-                               if (ma) {
-                                       polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
-                                       polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
-                                       polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
-                               }
-                               else {
-                                       polymat->m_specular.setValue(0.0f,0.0f,0.0f);
-                                       polymat->m_shininess = 35.0;
-                               }
-                       }
+                       RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter);
 
                        // set render flags
                        if (ma)
@@ -1188,30 +1198,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
 
                        /* mark face as flat, so vertices are split */
                        bool flat = (mface->flag & ME_SMOOTH) == 0;
-
-                       // see if a bucket was reused or a new one was created
-                       // this way only one KX_BlenderMaterial object has to exist per bucket
-                       bool bucketCreated; 
-                       RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
-                       if (bucketCreated) {
-                               // this is needed to free up memory afterwards
-                               converter->RegisterPolyMaterial(polymat);
-                               if (converter->GetMaterials()) {
-                                       converter->RegisterBlenderMaterial(bl_mat);
-                                       // the poly material has been stored in the bucket, next time we must create a new one
-                                       bl_mat = NULL;
-                                       kx_blmat = NULL;
-                               } else {
-                                       // the poly material has been stored in the bucket, next time we must create a new one
-                                       kx_polymat = NULL;
-                               }
-                       } else {
-                               // from now on, use the polygon material from the material bucket
-                               polymat = bucket->GetPolyMaterial();
-                               // keep the material pointers, they will be reused for next face
-                       }
-                                                
+                               
                        int nverts = (mface->v4)? 4: 3;
+
                        RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
 
                        poly->SetVisible(visible);
@@ -1219,12 +1208,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
                        poly->SetTwoside(twoside);
                        //poly->SetEdgeCode(mface->edcode);
 
-                       meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
-                       meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
-                       meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
+                       meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1);
+                       meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2);
+                       meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3);
 
                        if (nverts==4)
-                               meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
+                               meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4);
                }
 
                if (tface) 
@@ -1246,22 +1235,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
        meshobj->EndConversion();
 
        // pre calculate texture generation
-       for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
-               mit != meshobj->GetLastMaterial(); ++ mit) {
-               mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
+       // However, we want to delay this if we're libloading so we can make sure we have the right scene.
+       if (!libloading) {
+               for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
+                       mit != meshobj->GetLastMaterial(); ++ mit) {
+                       mit->m_bucket->GetPolyMaterial()->OnConstruction();
+               }
        }
 
        if (layers)
                delete []layers;
        
        dm->release(dm);
-       // cleanup material
-       if (bl_mat)
-               delete bl_mat;
-       if (kx_blmat)
-               delete kx_blmat;
-       if (kx_polymat)
-               delete kx_polymat;
+
        converter->RegisterGameMesh(meshobj, mesh);
        return meshobj;
 }
@@ -1921,7 +1907,8 @@ static KX_GameObject *gameobject_from_blenderobject(
                                                                Object *ob, 
                                                                KX_Scene *kxscene, 
                                                                RAS_IRenderTools *rendertools, 
-                                                               KX_BlenderSceneConverter *converter) 
+                                                               KX_BlenderSceneConverter *converter,
+                                                               bool libloading) 
 {
        KX_GameObject *gameobj = NULL;
        Scene *blenderscene = kxscene->GetBlenderScene();
@@ -1958,7 +1945,7 @@ static KX_GameObject *gameobject_from_blenderobject(
                Mesh* mesh = static_cast<Mesh*>(ob->data);
                float center[3], extents[3];
                float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
-               RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
+               RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading);
                
                // needed for python scripting
                kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
@@ -2332,7 +2319,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                          RAS_IRenderTools* rendertools,
                                                          RAS_ICanvas* canvas,
                                                          KX_BlenderSceneConverter* converter,
-                                                         bool alwaysUseExpandFraming
+                                                         bool alwaysUseExpandFraming,
+                                                         bool libloading
                                                          )
 {
 
@@ -2442,7 +2430,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                                                base->object, 
                                                                                kxscene, 
                                                                                rendertools, 
-                                                                               converter);
+                                                                               converter,
+                                                                               libloading);
                                                                                
                bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
                bool addobj=true;
@@ -2501,7 +2490,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                                                                                blenderobject, 
                                                                                                                kxscene, 
                                                                                                                rendertools, 
-                                                                                                               converter);
+                                                                                                               converter,
+                                                                                                               libloading);
                                                                                
                                                // this code is copied from above except that
                                                // object from groups are never in active layer
index 2a7efaac898ee8b8b59ac728534c8689444cefdd..f3a680929fbcc319e99d8748e81eac6cb7f1642b 100644 (file)
@@ -38,7 +38,7 @@
 #include "KX_PhysicsEngineEnums.h"
 #include "SCA_IInputDevice.h"
 
-class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
+class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter, bool libloading);
 
 void BL_ConvertBlenderObjects(struct Main* maggie,
                                                          class KX_Scene* kxscene,
@@ -47,7 +47,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                          class RAS_IRenderTools* rendertools,
                                                          class RAS_ICanvas* canvas, 
                                                          class KX_BlenderSceneConverter* sceneconverter, 
-                                                         bool alwaysUseExpandFraming
+                                                         bool alwaysUseExpandFraming,
+                                                         bool libloading=false
                                                          );
 
 SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code);
index d1684db0f5a49f5dea33042e319970d2d2822d82..260ca9ede9679270497aa2e88a7846fbfff326a7 100644 (file)
@@ -151,6 +151,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
 
        vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
        while (itp != m_polymaterials.end()) {
+               m_polymat_cache.erase((*itp).second->GetBlenderMaterial());
                delete (*itp).second;
                itp++;
        }
@@ -158,6 +159,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
        // delete after RAS_IPolyMaterial
        vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
        while (itmat != m_materials.end()) {
+               m_mat_cache.erase((*itmat).second->material);
                delete (*itmat).second;
                itmat++;
        }
@@ -286,7 +288,8 @@ struct      BlenderDebugDraw : public btIDebugDraw
 
 void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
                                                                                        class RAS_IRenderTools* rendertools,
-                                                                                       class RAS_ICanvas* canvas)
+                                                                                       class RAS_ICanvas* canvas,
+                                                                                       bool libloading)
 {
        //find out which physics engine
        Scene *blenderscene = destinationscene->GetBlenderScene();
@@ -355,7 +358,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
                rendertools,
                canvas,
                this,
-               m_alwaysUseExpandFraming
+               m_alwaysUseExpandFraming,
+               libloading
                );
 
        //These lookup are not needed during game
@@ -406,6 +410,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
        size = m_polymaterials.size();
        for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
                if ((*polymit).first == scene) {
+                       m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
                        delete (*polymit).second;
                        *polymit = m_polymaterials.back();
                        m_polymaterials.pop_back();
@@ -420,6 +425,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
        size = m_materials.size();
        for (i=0, matit=m_materials.begin(); i<size; ) {
                if ((*matit).first == scene) {
+                       m_mat_cache.erase((*matit).second->material);
                        delete (*matit).second;
                        *matit = m_materials.back();
                        m_materials.pop_back();
@@ -470,6 +476,12 @@ bool KX_BlenderSceneConverter::GetGLSLMaterials()
 
 void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
 {
+       // First make sure we don't register the material twice
+       vector<pair<KX_Scene*,BL_Material*> >::iterator it;
+       for (it = m_materials.begin(); it != m_materials.end(); ++it)
+               if (it->second == mat)
+                       return;
+
        m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
 }
 
@@ -540,19 +552,37 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
        } else {
                return NULL;
        }
-}
-
-       
-
-
-       
+}      
 
 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
 {
+       // First make sure we don't register the material twice
+       vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it;
+       for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it)
+               if (it->second == polymat)
+                       return;
        m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
 }
 
+void KX_BlenderSceneConverter::CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat)
+{
+       m_polymat_cache[mat] = polymat;
+}
+
+RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(struct Material *mat)
+{
+       return m_polymat_cache[mat];
+}
 
+void KX_BlenderSceneConverter::CacheBlenderMaterial(struct Material *mat, BL_Material *blmat)
+{
+       m_mat_cache[mat] = blmat;
+}
+
+BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(struct Material *mat)
+{
+       return m_mat_cache[mat];
+}
 
 void KX_BlenderSceneConverter::RegisterInterpolatorList(
                                                                        BL_InterpolatorList *actList,
@@ -1016,7 +1046,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
                for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
                        if (options & LIB_LOAD_VERBOSE)
                                printf("MeshName: %s\n", mesh->name+2);
-                       RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
+                       RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders
                        scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
                }
        }
@@ -1038,7 +1068,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
                                printf("SceneName: %s\n", scene->name+2);
                        
                        /* merge into the base  scene */
-                       KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
+                       KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true);
                        scene_merge->MergeScene(other);
                        
                        // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
@@ -1302,7 +1332,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
                }
 
                if (IS_TAGGED(bmat)) {
-
+                       m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
                        delete (*polymit).second;
                        *polymit = m_polymaterials.back();
                        m_polymaterials.pop_back();
@@ -1320,6 +1350,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
        for (i=0, matit=m_materials.begin(); i<size; ) {
                BL_Material *mat= (*matit).second;
                if (IS_TAGGED(mat->material)) {
+                       m_mat_cache.erase((*matit).second->material);
                        delete (*matit).second;
                        *matit = m_materials.back();
                        m_materials.pop_back();
@@ -1469,7 +1500,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
                }
        }
        
-       RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
+       RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
        kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
        m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
        return meshobj;
index 34a1117a0ebec85669ac1aab3288a3f806871879..eddb377dbc713e9117f02e7c3573bb366cacf30f 100644 (file)
@@ -39,6 +39,8 @@
 #include "KX_ISceneConverter.h"
 #include "KX_IpoConvert.h"
 
+#include <map>
+
 using namespace std;
 
 class KX_WorldInfo;
@@ -58,6 +60,11 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
        vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
        vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
        vector<pair<KX_Scene*,BL_Material *> >  m_materials;
+
+       // Cached material conversions
+       map<struct Material*, BL_Material*> m_mat_cache;
+       map<struct Material*, RAS_IPolyMaterial*> m_polymat_cache;
+
        // Should also have a list of collision shapes. 
        // For the time being this is held in KX_Scene::m_shapes
 
@@ -93,7 +100,8 @@ public:
        virtual void    ConvertScene(
                                                class KX_Scene* destinationscene,
                                                class RAS_IRenderTools* rendertools,
-                                               class RAS_ICanvas* canvas
+                                               class RAS_ICanvas* canvas,
+                                               bool libloading=false
                                        );
        virtual void RemoveScene(class KX_Scene *scene);
 
@@ -110,8 +118,12 @@ public:
        RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/);
 
        void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+       void CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat);
+       RAS_IPolyMaterial *FindCachedPolyMaterial(struct Material *mat);
 
        void RegisterBlenderMaterial(BL_Material *mat);
+       void CacheBlenderMaterial(struct Material *mat, BL_Material *blmat);
+       BL_Material *FindCachedBlenderMaterial(struct Material *mat);
        
        void RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act);
        BL_InterpolatorList *FindInterpolatorList(struct bAction *for_act);
index 06399642edd2929eb1d43c26d726ecd60611914e..695bf0c4dc80121ca507ba3ecd3c157f6e6cf6d9 100644 (file)
@@ -523,7 +523,8 @@ void BL_ConvertActuators(const char* maggiename,
                                                                    editobact->me,
                                                                    blenderobject,
                                                                    scene,
-                                                                   converter
+                                                                   converter,
+                                                                   false
                                                                    );
 
                                                KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
index 92db1fe790e8ac9c4c2cc46fa59a63b57c21151a..1dcc68c8e75685ee44a4c68e8bacb2fdbb7aefa2 100644 (file)
@@ -76,7 +76,6 @@ extern "C"
 #include "SCA_IActuator.h"
 #include "RAS_MeshObject.h"
 #include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
 #include "RAS_ListRasterizer.h"
 #include "RAS_GLExtensionManager.h"
 #include "KX_PythonInit.h"
@@ -582,16 +581,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
                if (!m_rendertools)
                        goto initFailed;
                
-               if (useLists) {
-                       if (GLEW_VERSION_1_1)
-                               m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
-                       else
-                               m_rasterizer = new RAS_ListRasterizer(m_canvas);
-               }
-               else if (GLEW_VERSION_1_1)
-                       m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
+               //Don't use displaylists with VBOs
+               //If auto starts using VBOs, make sure to check for that here
+               if (useLists && gm->raster_storage != RAS_STORE_VBO)
+                       m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
                else
-                       m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+                       m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);
 
                /* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
                m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
index 23bfd7a111b9e72feec26e13fb6c2d72289027a0..64e191fe9603f9866aae010a4856de45e4db76e6 100644 (file)
@@ -95,21 +95,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
 
                ras->SetTexCoordNum(0);
                ras->SetAttribNum(attrib_num);
-               for (i=0; i<attrib_num; i++)
+               for (i = 0; i < attrib_num; i++)
                        ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
 
                for (i = 0; i < attribs.totlayer; i++) {
                        if (attribs.layer[i].glindex > attrib_num)
                                continue;
 
-                       if (attribs.layer[i].type == CD_MTFACE) {
-                               if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
-                                       ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
-                               else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
-                                       ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
-                               else
-                                       ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
-                       }
+                       if (attribs.layer[i].type == CD_MTFACE)
+                               ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex);
                        else if (attribs.layer[i].type == CD_TANGENT)
                                ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
                        else if (attribs.layer[i].type == CD_ORCO)
index 0954aa0f7ab346a5cab96ef2e947d0e8af71cd2b..461a8c51a52e48a0a78714c613692e5044b4a4ea 100644 (file)
@@ -20,15 +20,6 @@ MTex* getImageFromMaterial(Material *mat, int 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()
 {
        Initialize();
@@ -36,7 +27,10 @@ BL_Material::BL_Material()
 
 void BL_Material::Initialize()
 {
-       m_mcol = 0xFFFFFFFFL;
+       rgb[0] = 0;
+       rgb[1] = 0;
+       rgb[2] = 0;
+       rgb[3] = 0;
        IdMode = 0;
        ras_mode = 0;
        glslmat = 0;
@@ -64,7 +58,7 @@ void BL_Material::Initialize()
 
        int i;
 
-       for (i=0; i<MAXTEX; i++) // :(
+       for (i = 0; i < MAXTEX; i++) // :(
        {
                mapping[i].mapping = 0;
                mapping[i].offsets[0] = 0.f;
@@ -90,15 +84,6 @@ void BL_Material::Initialize()
        }
 }
 
-void BL_Material::SetUVLayerName(const STR_String& name)
-{
-       uvName = name;
-}
-void BL_Material::SetUVLayerName2(const STR_String& name)
-{
-       uv2Name = name;
-}
-
 void BL_Material::SetSharedMaterial(bool v)
 {
        if ((v && num_users == -1) || num_users > 1 )
index ef180ed21263c23459f244856cbea45dbd0894ac..0383c0891b6b9020bb984199fddf091d2c1cc080 100644 (file)
@@ -87,13 +87,8 @@ public:
        MTFace                          tface; /* copy of the derived meshes tface */
        Image*                          img[MAXTEX];
        EnvMap*                         cubemap[MAXTEX];
-       unsigned int            m_mcol; /* for text color (only) */
 
-       STR_String uvName;
-       STR_String uv2Name;
-
-       void SetUVLayerName(const STR_String &name);
-       void SetUVLayerName2(const STR_String &name);
+       unsigned int rgb[4];
 
        void SetSharedMaterial(bool v);
        bool IsShared();
@@ -180,7 +175,6 @@ enum BL_MappingProj
 // ------------------------------------
 //extern void initBL_Material(BL_Material* mat);
 extern MTex* getImageFromMaterial(Material *mat, int index);
-extern int  getNumTexChannels( Material *mat );
 // ------------------------------------
 
 #endif
index 66423ed820ed7423d4053f4c03cfa67a1257e576..98fff5c8b6573c70395677d3943381d9e759480d 100644 (file)
@@ -60,6 +60,7 @@ public:
 
 typedef std::map<char*, BL_TextureObject> BL_TextureMap;
 static BL_TextureMap g_textureManager;
+static GLint g_max_units = -1;
 
 
 BL_Texture::BL_Texture()
@@ -379,14 +380,17 @@ unsigned int BL_Texture::GetTextureType() const
 
 int BL_Texture::GetMaxUnits()
 {
-       GLint unit=0;
-
-       if (GLEW_ARB_multitexture) {
-               glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
-               return (MAXTEX>=unit?unit:MAXTEX);
+       if (g_max_units < 0) {
+               GLint unit;
+               if (GLEW_ARB_multitexture) {
+                       glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
+                       g_max_units = (MAXTEX>=unit)?unit:MAXTEX;
+               } else {
+                       g_max_units = 0;
+               }
        }
 
-       return 0;
+       return g_max_units;
 }
 
 void BL_Texture::ActivateFirst()
index 20c36c2cc44dc7a660611de04ad16610b8486870..a55dd7018268bf4feebc77a06b55c5065c2d8cba 100644 (file)
@@ -60,7 +60,8 @@ KX_BlenderMaterial::KX_BlenderMaterial()
 void KX_BlenderMaterial::Initialize(
        KX_Scene *scene,
        BL_Material *data,
-       GameSettings *game)
+       GameSettings *game,
+       int lightlayer)
 {
        RAS_IPolyMaterial::Initialize(
                data->texname[0],
@@ -84,6 +85,7 @@ void KX_BlenderMaterial::Initialize(
        mModified = 0;
        mConstructed = false;
        mPass = 0;
+       mLightLayer = lightlayer;
        // --------------------------------
        // RAS_IPolyMaterial variables...
        m_flag |= RAS_BLENDERMAT;
@@ -92,16 +94,11 @@ void KX_BlenderMaterial::Initialize(
        m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
        m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
 
-       // figure max
-       int enabled = mMaterial->num_enabled;
-       int max = BL_Texture::GetMaxUnits();
-       mMaterial->num_enabled = enabled>=max?max: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++) {
+       for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
                m_multimode     += (mMaterial->flag[i] + mMaterial->blend_mode[i]);
        }
        m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
@@ -124,7 +121,7 @@ MTFace* KX_BlenderMaterial::GetMTFace(void) const
 unsigned int* KX_BlenderMaterial::GetMCol(void) const 
 {
        // fonts on polys
-       return &mMaterial->m_mcol;
+       return mMaterial->rgb;
 }
 
 void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
@@ -138,11 +135,6 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
                RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
 }
 
-bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const
-{
-       return (mMaterial == bl_mat);
-}
-
 Material *KX_BlenderMaterial::GetBlenderMaterial() const
 {
        return mMaterial->material;
@@ -163,7 +155,7 @@ void KX_BlenderMaterial::InitTextures()
 {
        // for each unique material...
        int i;
-       for (i=0; i<mMaterial->num_enabled; i++) {
+       for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
                if ( mMaterial->mapping[i].mapping & USEENV ) {
                        if (!GLEW_ARB_texture_cube_map) {
                                spit("CubeMap textures not supported");
@@ -185,14 +177,14 @@ void KX_BlenderMaterial::InitTextures()
        }
 }
 
-void KX_BlenderMaterial::OnConstruction(int layer)
+void KX_BlenderMaterial::OnConstruction()
 {
        if (mConstructed)
                // when material are reused between objects
                return;
        
        if (mMaterial->glslmat)
-               SetBlenderGLSLShader(layer);
+               SetBlenderGLSLShader();
 
        InitTextures();
 
@@ -239,7 +231,8 @@ void KX_BlenderMaterial::OnExit()
        }
 
        BL_Texture::ActivateFirst();
-       for (int i=0; i<mMaterial->num_enabled; i++) {
+       for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
+               if (!mTextures[i].Ok()) continue;
                BL_Texture::ActivateUnit(i);
                mTextures[i].DeleteTex();
                mTextures[i].DisableUnit();
@@ -278,7 +271,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
        mShader->ApplyShader();
 
        // for each enabled unit
-       for (i=0; i<mMaterial->num_enabled; i++) {
+       for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
                if (!mTextures[i].Ok()) continue;
                mTextures[i].ActivateTexture();
                mTextures[0].SetMapping(mMaterial->mapping[i].mapping);
@@ -354,7 +347,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
        }
 
        int mode = 0,i=0;
-       for (i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) {
+       for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
                if ( !mTextures[i].Ok() ) continue;
 
                mTextures[i].ActivateTexture();
@@ -647,16 +640,9 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
 
                ras->SetTexCoordNum(mMaterial->num_enabled);
 
-               for (int i=0; i<mMaterial->num_enabled; i++) {
+               for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
                        int mode = mMaterial->mapping[i].mapping;
 
-                       if (mode &USECUSTOMUV)
-                       {
-                               if (!mMaterial->mapping[i].uvCoName.IsEmpty())
-                                       ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
-                               continue;
-                       }
-
                        if ( mode &(USEREFL|USEOBJ))
                                ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
                        else if (mode &USEORCO)
@@ -664,7 +650,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
                        else if (mode &USENORM)
                                ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
                        else if (mode &USEUV)
-                               ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i);
+                               ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
                        else if (mode &USETANG)
                                ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
                        else 
@@ -790,10 +776,19 @@ void KX_BlenderMaterial::UpdateIPO(
        mMaterial->ref                  = (float)(ref);
 }
 
-void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
+void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
+{
+       mScene= static_cast<KX_Scene *>(val);
+       if (mBlenderShader)
+               mBlenderShader->SetScene(mScene);
+       
+       OnConstruction();
+}
+
+void KX_BlenderMaterial::SetBlenderGLSLShader()
 {
        if (!mBlenderShader)
-               mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
+               mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer);
 
        if (!mBlenderShader->Ok()) {
                delete mBlenderShader;
index 7bc9c7c3863171db62bf593a4897e31de42eed0f..c34a49e1bde26accfebee30e15c27ca3adad78ff 100644 (file)
@@ -39,7 +39,8 @@ public:
        void Initialize(
                class KX_Scene* scene,
                BL_Material*    mat,
-               GameSettings*   game
+               GameSettings*   game,
+               int                             lightlayer
        );
 
        virtual ~KX_BlenderMaterial();
@@ -76,8 +77,6 @@ public:
                TCachingInfo& cachingInfo
        )const;
 
-       /* mMaterial is private, but need this for conversion */
-       bool IsMaterial(const BL_Material *bl_mat) const;
        Material* GetBlenderMaterial() const;
        MTFace* GetMTFace(void) const;
        unsigned int* GetMCol(void) const;
@@ -97,14 +96,7 @@ public:
                MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
        );
        
-       virtual void Replace_IScene(SCA_IScene *val)
-       {
-               mScene= static_cast<KX_Scene *>(val);
-               if (mBlenderShader)
-               {
-                       mBlenderShader->SetScene(mScene);
-               }
-       };
+       virtual void Replace_IScene(SCA_IScene *val);
 
 #ifdef WITH_PYTHON
        // --------------------------------
@@ -125,7 +117,7 @@ public:
 
        // --------------------------------
        // pre calculate to avoid pops/lag at startup
-       virtual void OnConstruction(int layer);
+       virtual void OnConstruction();
 
        static void     EndFrame();
 
@@ -139,10 +131,11 @@ private:
        unsigned int    mBlendFunc[2];
        bool                    mModified;
        bool                    mConstructed;                   // if false, don't clean on exit
+       int                             mLightLayer;
 
        void InitTextures();
 
-       void SetBlenderGLSLShader(int layer);
+       void SetBlenderGLSLShader();
 
        void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
        void ActivateTexGen( RAS_IRasterizer *ras ) const;
index 18fb336dbe0ea75884308748dcd33f376080aad8..0dbfd7de2c606a336112b35b908c7406e0509edd 100644 (file)
@@ -57,7 +57,8 @@ public:
        virtual void ConvertScene(
                class KX_Scene* destinationscene,
                class RAS_IRenderTools* rendertools, 
-               class RAS_ICanvas*  canvas)=0;
+               class RAS_ICanvas*  canvas,
+               bool libloading=false)=0;
        
        virtual void RemoveScene(class KX_Scene *scene)=0;
 
index a12e12ccef26a6e20d5180a0e22f29f37aad53a6..890b9d4c47293e3a3dcb7fd64a6c8afd4124992d 100644 (file)
@@ -1686,7 +1686,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
        }
 }
 
-KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
+KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
 {
        KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
                                                                          m_mousedevice,
@@ -1697,7 +1697,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
 
        m_sceneconverter->ConvertScene(tmpscene,
                                                          m_rendertools,
-                                                         m_canvas);
+                                                         m_canvas,
+                                                         libloading);
 
        return tmpscene;
 }
index 972594bd90fa6e0f0d1779e36140bd7709359a64..92ffaf47aa4c685d2334acceed48c628e25103ca 100644 (file)
@@ -413,7 +413,7 @@ public:
        void GetOverrideFrameColor(float& r, float& g, float& b) const;
 
        KX_Scene*               CreateScene(const STR_String& scenename);
-       KX_Scene*               CreateScene(Scene *scene);
+       KX_Scene*               CreateScene(Scene *scene, bool libloading=false);
 
        GlobalSettings* GetGlobalSettings(void);
        void                    SetGlobalSettings(GlobalSettings* gs);
index d83e98d4712a78d881151e2bc4e1630f735e1739..57695df27821ff104efde2ac3d0a85f675bd0ebf 100644 (file)
@@ -338,20 +338,20 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds)
                        for (i = it.startvertex; i < it.endvertex; i++) {
                                RAS_TexVert *vert = &it.vertex[i];
                                if (uvindex_from != -1) {
-                                       if (uvindex_from == 0) vert->SetUV2(vert->getUV1());
-                                       else                   vert->SetUV1(vert->getUV2());
+                                       if (uvindex_from == 0) vert->SetUV(1, vert->getUV(0));
+                                       else                   vert->SetUV(0, vert->getUV(1));
                                }
 
                                switch (uvindex) {
                                        case 0:
-                                               vert->TransformUV1(transform);
+                                               vert->TransformUV(0, transform);
                                                break;
                                        case 1:
-                                               vert->TransformUV2(transform);
+                                               vert->TransformUV(1, transform);
                                                break;
                                        case -1:
-                                               vert->TransformUV1(transform);
-                                               vert->TransformUV2(transform);
+                                               vert->TransformUV(0, transform);
+                                               vert->TransformUV(1, transform);
                                                break;
                                }
                        }
index f157d9ed20ab1c9dcdb65679e693ead7784c723b..5ce370ccdfe2ad221555e433349d4036d4e05c6e 100644 (file)
@@ -109,7 +109,7 @@ void KX_PolygonMaterial::Initialize(
                m_mcol = *mcol;
        }
        else {
-               m_mcol = 0;
+               memset(&m_mcol, 0, sizeof(m_mcol));
        }
 
        m_material = ma;
index 2ce8f480c1c4b7880b8dfc2dcb954de93b5c5442..89bfb4ff9fba1fc0cbc1730800a6750cf1dd578e 100644 (file)
@@ -60,7 +60,7 @@ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial
 private:
        /** Blender texture face structure. */
        mutable MTFace       m_tface;
-       mutable unsigned int m_mcol; /* for text color (only) */
+       mutable unsigned int m_mcol;
        Material*            m_material;
 
 #ifdef WITH_PYTHON
index 2354359af1810e1f2c11afcfd62ea77070866390..ab73ba1902a107e305edb602156085199f173e4e 100644 (file)
@@ -94,6 +94,7 @@ PyAttributeDef KX_VertexProxy::Attributes[] = {
 
        KX_PYATTRIBUTE_RW_FUNCTION("XYZ", KX_VertexProxy, pyattr_get_XYZ, pyattr_set_XYZ),
        KX_PYATTRIBUTE_RW_FUNCTION("UV", KX_VertexProxy, pyattr_get_UV, pyattr_set_UV),
+       KX_PYATTRIBUTE_RW_FUNCTION("uvs", KX_VertexProxy, pyattr_get_uvs, pyattr_set_uvs),
 
        KX_PYATTRIBUTE_RW_FUNCTION("color", KX_VertexProxy, pyattr_get_color, pyattr_set_color),
        KX_PYATTRIBUTE_RW_FUNCTION("normal", KX_VertexProxy, pyattr_get_normal, pyattr_set_normal),
@@ -146,25 +147,25 @@ PyObject *KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a
 PyObject *KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
-       return PyFloat_FromDouble(self->m_vertex->getUV1()[0]);
+       return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]);
 }
 
 PyObject *KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
-       return PyFloat_FromDouble(self->m_vertex->getUV1()[1]);
+       return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]);
 }
 
 PyObject *KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
-       return PyFloat_FromDouble(self->m_vertex->getUV2()[0]);
+       return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]);
 }
 
 PyObject *KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
-       return PyFloat_FromDouble(self->m_vertex->getUV2()[1]);
+       return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]);
 }
 
 PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -176,7 +177,20 @@ PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF
 PyObject *KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
-       return PyObjectFrom(MT_Point2(self->m_vertex->getUV1()));
+       return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0)));
+}
+
+PyObject *KX_VertexProxy::pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+       KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+       
+       PyObject* uvlist = PyList_New(RAS_TexVert::MAX_UNIT);
+       for (int i=0; i<RAS_TexVert::MAX_UNIT; ++i)
+       {
+               PyList_SET_ITEM(uvlist, i, PyObjectFrom(MT_Point2(self->m_vertex->getUV(i))));
+       }
+
+       return uvlist;
 }
 
 PyObject *KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -245,9 +259,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF *
        if (PyFloat_Check(value))
        {
                float val = PyFloat_AsDouble(value);
-               MT_Point2 uv = self->m_vertex->getUV1();
+               MT_Point2 uv = self->m_vertex->getUV(0);
                uv[0] = val;
-               self->m_vertex->SetUV1(uv);
+               self->m_vertex->SetUV(0, uv);
                self->m_mesh->SetMeshModified(true);
                return PY_SET_ATTR_SUCCESS;
        }
@@ -260,9 +274,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF *
        if (PyFloat_Check(value))
        {
                float val = PyFloat_AsDouble(value);
-               MT_Point2 uv = self->m_vertex->getUV1();
+               MT_Point2 uv = self->m_vertex->getUV(0);
                uv[1] = val;
-               self->m_vertex->SetUV1(uv);
+               self->m_vertex->SetUV(0, uv);
                self->m_mesh->SetMeshModified(true);
                return PY_SET_ATTR_SUCCESS;
        }
@@ -275,9 +289,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF
        if (PyFloat_Check(value))
        {
                float val = PyFloat_AsDouble(value);
-               MT_Point2 uv = self->m_vertex->getUV2();
+               MT_Point2 uv = self->m_vertex->getUV(1);
                uv[0] = val;
-               self->m_vertex->SetUV2(uv);
+               self->m_vertex->SetUV(1, uv);
                self->m_mesh->SetMeshModified(true);
                return PY_SET_ATTR_SUCCESS;
        }
@@ -290,9 +304,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF
        if (PyFloat_Check(value))
        {
                float val = PyFloat_AsDouble(value);
-               MT_Point2 uv = self->m_vertex->getUV2();
+               MT_Point2 uv = self->m_vertex->getUV(1);
                uv[1] = val;
-               self->m_vertex->SetUV2(uv);
+               self->m_vertex->SetUV(1, uv);
                self->m_mesh->SetMeshModified(true);
                return PY_SET_ATTR_SUCCESS;
        }
@@ -390,7 +404,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
        {
                MT_Point2 vec;
                if (PyVecTo(value, vec)) {
-                       self->m_vertex->SetUV1(vec);
+                       self->m_vertex->SetUV(0, vec);
                        self->m_mesh->SetMeshModified(true);
                        return PY_SET_ATTR_SUCCESS;
                }
@@ -398,6 +412,32 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
        return PY_SET_ATTR_FAIL;
 }
 
+int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+       KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+       if (PySequence_Check(value))
+       {
+               MT_Point2 vec;
+               for (int i=0; i<PySequence_Size(value) && i<RAS_TexVert::MAX_UNIT; ++i)
+               {
+                       if (PyVecTo(PySequence_GetItem(value, i), vec))
+                       {
+                               self->m_vertex->SetUV(i, vec);
+                               self->m_mesh->SetMeshModified(true);
+                       }
+                       else
+                       {
+                               PyErr_SetString(PyExc_AttributeError, STR_String().Format("list[%d] was not a vector", i).ReadPtr());
+                               return PY_SET_ATTR_FAIL;
+                       }
+               }
+               
+               self->m_mesh->SetMeshModified(true);
+               return PY_SET_ATTR_SUCCESS;
+       }
+       return PY_SET_ATTR_FAIL;
+}
+
 int KX_VertexProxy::pyattr_set_color(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 {
        KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
@@ -522,7 +562,7 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value)
 
 PyObject *KX_VertexProxy::PyGetUV1()
 {
-       return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
+       return PyObjectFrom(MT_Vector2(m_vertex->getUV(0)));
 }
 
 PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
@@ -531,31 +571,23 @@ PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
        if (!PyVecTo(value, vec))
                return NULL;
 
-       m_vertex->SetUV1(vec);
+       m_vertex->SetUV(0, vec);
        m_mesh->SetMeshModified(true);
        Py_RETURN_NONE;
 }
 
 PyObject *KX_VertexProxy::PyGetUV2()
 {
-       return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
+       return PyObjectFrom(MT_Vector2(m_vertex->getUV(1)));
 }
 
 PyObject *KX_VertexProxy::PySetUV2(PyObject *args)
 {
        MT_Point2 vec;
-       unsigned int unit= RAS_TexVert::SECOND_UV;
-
-       PyObject *list = NULL;
-       if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
-               return NULL;
-
-       if (!PyVecTo(list, vec))
+       if (!PyVecTo(args, vec))
                return NULL;
 
-       m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
-       m_vertex->SetUnit(unit);
-       m_vertex->SetUV2(vec);
+       m_vertex->SetUV(1, vec);
        m_mesh->SetMeshModified(true);
        Py_RETURN_NONE;
 }
index 4247d138a661ec9a4d7744c9afd2457bb1161d76..8070825ad11f5d741bdba386ff63cc1f176b97af 100644 (file)
@@ -74,6 +74,7 @@ public:
        static PyObject *pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static PyObject *pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static PyObject *pyattr_get_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+       static PyObject *pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static int pyattr_set_x(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static int pyattr_set_y(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static int pyattr_set_z(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@@ -89,6 +90,7 @@ public:
        static int pyattr_set_UV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static int pyattr_set_color(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
        static int pyattr_set_normal(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+       static int pyattr_set_uvs(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
 
        KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
        KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
index f24e339780158a0625b44a32eca1f72f0bc16353..2b5b0aeac2a13361593a3182deda800d7232f2c9 100644 (file)
@@ -232,6 +232,24 @@ void RAS_BucketManager::Renderbuckets(
        RenderSolidBuckets(cameratrans, rasty, rendertools);
        RenderAlphaBuckets(cameratrans, rasty, rendertools);
 
+       /* All meshes should be up to date now */
+       /* Don't do this while processing buckets because some meshes are split between buckets */
+       BucketList::iterator bit;
+       list<RAS_MeshSlot>::iterator mit;
+       for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
+               RAS_MaterialBucket* bucket = *bit;
+               for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+                       mit->m_mesh->SetMeshModified(false);
+               }
+       }
+       for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+               RAS_MaterialBucket* bucket = *bit;
+               for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+                       mit->m_mesh->SetMeshModified(false);
+               }
+       }
+       
+
        rendertools->SetClientObject(rasty, NULL);
 }
 
index 9fffc8bebc9122f34eafcb88ec3f5755539b9609..b267879611e1f19a7ef8d2d61ac54df7a441bd2a 100644 (file)
@@ -184,7 +184,7 @@ public:
        /*
         * PreCalculate texture gen
         */
-       virtual void OnConstruction(int layer) {}
+       virtual void OnConstruction() {}
 
 
 #ifdef WITH_CXX_GUARDEDALLOC
index e69480259994ec92231a5861b5cc29aa4a6a8f94..5a720857d5055bb49dfb6f1666c2d3d4bc1d14ae 100644 (file)
@@ -52,6 +52,7 @@ using namespace std;
 
 class RAS_ICanvas;
 class RAS_IPolyMaterial;
+class RAS_MeshSlot;
 
 typedef vector<unsigned short> KX_IndexArray;
 typedef vector<RAS_TexVert> KX_VertexArray;
@@ -129,7 +130,7 @@ public:
                RAS_TEXCO_GEN,          //< GPU will generate texture coordinates
                RAS_TEXCO_ORCO,         //< Vertex coordinates (object space)
                RAS_TEXCO_GLOB,         //< Vertex coordinates (world space)
-               RAS_TEXCO_UV1,          //< UV coordinates
+               RAS_TEXCO_UV          //< UV coordinates
                RAS_TEXCO_OBJECT,       //< Use another object's position as coordinates
                RAS_TEXCO_LAVECTOR,     //< Light vector as coordinates
                RAS_TEXCO_VIEW,         //< View vector as coordinates
@@ -137,7 +138,6 @@ public:
                RAS_TEXCO_WINDOW,       //< Window coordinates
                RAS_TEXCO_NORM,         //< Normal coordinates 
                RAS_TEXTANGENT,         //<
-               RAS_TEXCO_UV2,          //<
                RAS_TEXCO_VCOL,         //< Vertex Color
                RAS_TEXCO_DISABLE       //< Disable this texture unit (cached)
        };
index 9fb47117f1db9644a6aad3cf3e13353087305f48..54fe19a291ff6d0dfd48314f32e18c56e791c91d 100644 (file)
@@ -605,7 +605,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
 
        if (ms.m_pDeformer)
        {
-               ms.m_pDeformer->Apply(m_material);
+               if (ms.m_pDeformer->Apply(m_material));
+                       ms.m_mesh->SetMeshModified(true);
        //      KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
        }
        
@@ -648,10 +649,6 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
        else
                rasty->IndexPrimitives(ms);
 
-       if (rasty->QueryLists())
-               if (ms.m_DisplayList)
-                       ms.m_mesh->SetMeshModified(false);
-
        rendertools->PopMatrix();
 }
 
index 2ccb9453b3d05321c426334dff9917357ab35a75..49b7489530248ab94c0a2701cac99c60a504988a 100644 (file)
@@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
 
 void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
                                                                const MT_Point3& xyz,
-                                                               const MT_Point2& uv,
-                                                               const MT_Point2& uv2,
+                                                               const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
                                                                const MT_Vector4& tangent,
                                                                const unsigned int rgba,
                                                                const MT_Vector3& normal,
                                                                bool flat,
                                                                int origindex)
 {
-       RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
+       RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex);
        RAS_MeshMaterial *mmat;
        RAS_DisplayArray *darray;
        RAS_MeshSlot *slot;
index 281eae8734af301d78a74930ada36740ece85b2f..d77d048302499fd9a0c63904b84d695c5015bb87 100644 (file)
@@ -116,8 +116,7 @@ public:
        virtual RAS_Polygon*    AddPolygon(RAS_MaterialBucket *bucket, int numverts);
        virtual void                    AddVertex(RAS_Polygon *poly, int i,
                                                        const MT_Point3& xyz,
-                                                       const MT_Point2& uv,
-                                                       const MT_Point2& uv2,
+                                                       const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
                                                        const MT_Vector4& tangent,
                                                        const unsigned int rgbacolor,
                                                        const MT_Vector3& normal,
index 189c4f78f778b46cc4900e31601d395462504fd6..11cb4b1d9f94393417b5f7bef6ccfc107f2913b9 100644 (file)
@@ -46,12 +46,17 @@ set(SRC
        RAS_GLExtensionManager.cpp
        RAS_ListRasterizer.cpp
        RAS_OpenGLRasterizer.cpp
-       RAS_VAOpenGLRasterizer.cpp
+       RAS_StorageIM.cpp
+       RAS_StorageVA.cpp
+       RAS_StorageVBO.cpp
 
        RAS_GLExtensionManager.h
+       RAS_IStorage.h
        RAS_ListRasterizer.h
        RAS_OpenGLRasterizer.h
-       RAS_VAOpenGLRasterizer.h
+       RAS_StorageIM.h
+       RAS_StorageVA.h
+       RAS_StorageVBO.h
 )
 
 add_definitions(-DGLEW_STATIC)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
new file mode 100644 (file)
index 0000000..f5c16bc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_STORAGE
+#define __KX_STORAGE
+
+#include "RAS_MaterialBucket.h"
+
+enum RAS_STORAGE_TYPE  {
+       RAS_AUTO_STORAGE,
+       RAS_IMMEDIATE,
+       RAS_VA,
+       RAS_VBO
+};
+
+class RAS_IStorage
+{
+
+public:
+       virtual ~RAS_IStorage() {};
+
+       virtual bool    Init()=0;
+       virtual void    Exit()=0;
+
+       virtual void    IndexPrimitives(RAS_MeshSlot& ms)=0;
+       virtual void    IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0;
+
+       virtual void    SetDrawingMode(int drawingmode)=0;
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+       void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); }
+       void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_STORAGE
index d74aa134779b4ebee14faea06c2dc1fcc065c3bb..3a60643e9e7929c42013ed6177b97ffdfca094a3 100644 (file)
@@ -106,9 +106,8 @@ bool RAS_ListSlot::End()
 
 
 
-RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
-:      RAS_VAOpenGLRasterizer(canvas, lock),
-       mUseVertexArrays(useVertexArrays),
+RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage)
+:      RAS_OpenGLRasterizer(canvas, storage),
        mATI(false)
 {
        if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
@@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
                        return;
                }
        }
-       // derived mesh cannot use vertex array
-       if (mUseVertexArrays && !ms.m_pDerivedMesh)
-               RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
-       else
-               RAS_OpenGLRasterizer::IndexPrimitives(ms);
+       
+       RAS_OpenGLRasterizer::IndexPrimitives(ms);
 
        if (ms.m_bDisplayList) {
                localSlot->EndList();
@@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
                }
        }
 
-       // workaround: note how we do not use vertex arrays for making display
-       // lists, since glVertexAttribPointerARB doesn't seem to work correct
-       // in display lists on ATI? either a bug in the driver or in Blender ..
-       if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh)
-               RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
-       else
-               RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
+       RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
 
        if (ms.m_bDisplayList) {
                localSlot->EndList();
@@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
 
 bool RAS_ListRasterizer::Init(void)
 {
-       if (mUseVertexArrays) {
-               return RAS_VAOpenGLRasterizer::Init();
-       } else {
-               return RAS_OpenGLRasterizer::Init();
-       }
+       return RAS_OpenGLRasterizer::Init();
 }
 
 void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
 {
-       if (mUseVertexArrays) {
-               RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
-       } else {
-               RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
-       }
+       RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
 }
 
 void RAS_ListRasterizer::Exit()
 {
-       if (mUseVertexArrays) {
-               RAS_VAOpenGLRasterizer::Exit();
-       } else {
-               RAS_OpenGLRasterizer::Exit();
-       }
+       RAS_OpenGLRasterizer::Exit();
 }
 
 // eof
index a8eb2d5ffdfbdb07381c9f73755248ace3565d4f..0eddde7c2039b36ff331e10f0b26f28a4518535c 100644 (file)
@@ -7,7 +7,7 @@
 #define __RAS_LISTRASTERIZER_H__
 
 #include "RAS_MaterialBucket.h"
-#include "RAS_VAOpenGLRasterizer.h"
+#include "RAS_OpenGLRasterizer.h"
 #include <vector>
 #include <map>
 
@@ -49,7 +49,7 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
 typedef std::vector<RAS_ListSlot*>                                       RAS_ListSlots;        // indexed by material slot number
 typedef std::map<DerivedMesh*, RAS_ListSlots*>           RAS_DerivedMeshLists;
 
-class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
+class RAS_ListRasterizer : public RAS_OpenGLRasterizer
 {
        bool mUseVertexArrays;
        bool mATI;
@@ -61,7 +61,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
 
 public:
        void RemoveListSlot(RAS_ListSlot* list);
-       RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
+       RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE);
        virtual ~RAS_ListRasterizer();
 
        virtual void    IndexPrimitives(class RAS_MeshSlot& ms);
index 22a700c7d2b839241dacccd356fcc1ef21645d9a..1328a5521b4845785495c923c68b31bff5951198 100644 (file)
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
+#include "RAS_StorageIM.h"
+#include "RAS_StorageVA.h"
+#include "RAS_StorageVBO.h"
+
 #include "GPU_draw.h"
 #include "GPU_material.h"
 #include "GPU_extensions.h"
@@ -74,7 +78,7 @@ static GLuint right_eye_vinterlace_mask[32];
  */
 static GLuint hinterlace_mask[33];
 
-RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
+RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
        :RAS_IRasterizer(canvas),
        m_2DCanvas(canvas),
        m_fogenabled(false),
@@ -93,7 +97,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        m_attrib_num(0),
        //m_last_alphablend(GPU_BLEND_SOLID),
        m_last_frontface(true),
-       m_materialCachingInfo(0)
+       m_materialCachingInfo(0),
+       m_storage_type(storage)
 {
        m_viewmatrix.setIdentity();
        m_viewinvmatrix.setIdentity();
@@ -107,6 +112,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        hinterlace_mask[32] = 0;
 
        m_prevafvalue = GPU_get_anisotropic();
+
+       if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
+       {
+               m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+               m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+               m_storage_type = RAS_VBO;
+       }
+       else if (m_storage_type == RAS_VA || m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1)
+       {
+               m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+               m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+               m_storage_type = RAS_VA;
+       }
+       else
+       {
+               m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+               m_storage_type = RAS_IMMEDIATE;
+       }
 }
 
 
@@ -115,10 +138,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
 {
        // Restore the previous AF value
        GPU_set_anisotropic(m_prevafvalue);
+       if (m_failsafe_storage && m_failsafe_storage != m_storage)
+               delete m_failsafe_storage;
+
+       if (m_storage)
+               delete m_storage;
 }
 
 bool RAS_OpenGLRasterizer::Init()
 {
+       bool storage_init;
        GPU_state_init();
 
 
@@ -146,7 +175,9 @@ bool RAS_OpenGLRasterizer::Init()
 
        glShadeModel(GL_SMOOTH);
 
-       return true;
+       storage_init = m_storage->Init();
+
+       return true && storage_init;
 }
 
 
@@ -267,6 +298,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
 void RAS_OpenGLRasterizer::Exit()
 {
 
+       m_storage->Exit();
+
        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);
        glClearDepth(1.0); 
@@ -289,7 +322,7 @@ void RAS_OpenGLRasterizer::Exit()
 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
 {
        m_time = time;
-       m_drawingmode = drawingmode;
+       SetDrawingMode(drawingmode);
 
        // Blender camera routine destroys the settings
        if (m_drawingmode < KX_SOLID)
@@ -328,6 +361,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
 
        if (m_drawingmode == KX_WIREFRAME)
                glDisable(GL_CULL_FACE);
+
+       m_storage->SetDrawingMode(drawingmode);
 }
 
 int RAS_OpenGLRasterizer::GetDrawingMode()
@@ -666,7 +701,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
                                glattrib = -1;
                                if (GLEW_ARB_vertex_program)
                                        for (unit=0; unit<m_attrib_num; unit++)
-                                               if (m_attrib[unit] == RAS_TEXCO_UV1)
+                                               if (m_attrib[unit] == RAS_TEXCO_UV)
                                                        glattrib = unit;
                                
                                rendertools->RenderText(polymat->GetDrawingMode(), polymat,
@@ -708,257 +743,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
                m_attrib[unit] = coords;
 }
 
-void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
-{
-       int unit;
-
-       if (GLEW_ARB_multitexture) {
-               for (unit=0; unit<m_texco_num; unit++) {
-                       if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
-                               glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
-                               continue;
-                       }
-                       switch (m_texco[unit]) {
-                               case RAS_TEXCO_ORCO:
-                               case RAS_TEXCO_GLOB:
-                                       glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
-                                       break;
-                               case RAS_TEXCO_UV1:
-                                       glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
-                                       break;
-                               case RAS_TEXCO_NORM:
-                                       glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
-                                       break;
-                               case RAS_TEXTANGENT:
-                                       glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
-                                       break;
-                               case RAS_TEXCO_UV2:
-                                       glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-       }
-
-       if (GLEW_ARB_vertex_program) {
-               for (unit=0; unit<m_attrib_num; unit++) {
-                       switch (m_attrib[unit]) {
-                               case RAS_TEXCO_ORCO:
-                               case RAS_TEXCO_GLOB:
-                                       glVertexAttrib3fvARB(unit, tv.getXYZ());
-                                       break;
-                               case RAS_TEXCO_UV1:
-                                       glVertexAttrib2fvARB(unit, tv.getUV1());
-                                       break;
-                               case RAS_TEXCO_NORM:
-                                       glVertexAttrib3fvARB(unit, tv.getNormal());
-                                       break;
-                               case RAS_TEXTANGENT:
-                                       glVertexAttrib4fvARB(unit, tv.getTangent());
-                                       break;
-                               case RAS_TEXCO_UV2:
-                                       glVertexAttrib2fvARB(unit, tv.getUV2());
-                                       break;
-                               case RAS_TEXCO_VCOL:
-                                       glVertexAttrib4ubvARB(unit, tv.getRGBA());
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-       }
-
-}
-
 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
 {
-       IndexPrimitivesInternal(ms, false);
+       if (ms.m_pDerivedMesh)
+               m_failsafe_storage->IndexPrimitives(ms);
+       else
+               m_storage->IndexPrimitives(ms);
 }
 
 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
 {
-       IndexPrimitivesInternal(ms, true);
-}
-
-static bool current_wireframe;
-static RAS_MaterialBucket *current_bucket;
-static RAS_IPolyMaterial *current_polymat;
-static RAS_MeshSlot *current_ms;
-static RAS_MeshObject *current_mesh;
-static int current_blmat_nr;
-static GPUVertexAttribs current_gpu_attribs;
-static Image *current_image;
-static int CheckMaterialDM(int matnr, void *attribs)
-{
-       // only draw the current material
-       if (matnr != current_blmat_nr)
-               return 0;
-       GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
-       if (gattribs)
-               memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
-       return 1;
-}
-
-/*
-static int CheckTexfaceDM(void *mcol, int index)
-{
-
-       // index is the original face index, retrieve the polygon
-       RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
-               current_mesh->GetPolygon(index) : NULL;
-       if (polygon && polygon->GetMaterial() == current_bucket) {
-               // must handle color.
-               if (current_wireframe)
-                       return 2;
-               if (current_ms->m_bObjectColor) {
-                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
-                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-                       // don't use mcol
-                       return 2;
-               }
-               if (!mcol) {
-                       // we have to set the color from the material
-                       unsigned char rgba[4];
-                       current_polymat->GetMaterialRGBAColor(rgba);
-                       glColor4ubv((const GLubyte *)rgba);
-                       return 2;
-               }
-               return 1;
-       }
-       return 0;
-}
-*/
-
-static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
-{
-
-       // index is the original face index, retrieve the polygon
-       if (matnr == current_blmat_nr &&
-               (tface == NULL || tface->tpage == current_image)) {
-               // must handle color.
-               if (current_wireframe)
-                       return DM_DRAW_OPTION_NO_MCOL;
-               if (current_ms->m_bObjectColor) {
-                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
-                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-                       // don't use mcol
-                       return DM_DRAW_OPTION_NO_MCOL;
-               }
-               if (!has_mcol) {
-                       // we have to set the color from the material
-                       unsigned char rgba[4];
-                       current_polymat->GetMaterialRGBAColor(rgba);
-                       glColor4ubv((const GLubyte *)rgba);
-                       return DM_DRAW_OPTION_NO_MCOL;
-               }
-               return DM_DRAW_OPTION_NORMAL;
-       }
-       return DM_DRAW_OPTION_SKIP;
-}
-
-void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
-{ 
-       bool obcolor = ms.m_bObjectColor;
-       bool wireframe = m_drawingmode <= KX_WIREFRAME;
-       MT_Vector4& rgba = ms.m_RGBAcolor;
-       RAS_MeshSlot::iterator it;
-
-       if (ms.m_pDerivedMesh) {
-               // mesh data is in derived mesh, 
-               current_bucket = ms.m_bucket;
-               current_polymat = current_bucket->GetPolyMaterial();
-               current_ms = &ms;
-               current_mesh = ms.m_mesh;
-               current_wireframe = wireframe;
-               // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
-
-               // handle two-side
-               if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
-                       this->SetCullFace(true);
-               else
-                       this->SetCullFace(false);
-
-               if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
-                       // GetMaterialIndex return the original mface material index, 
-                       // increment by 1 to match what derived mesh is doing
-                       current_blmat_nr = current_polymat->GetMaterialIndex()+1;
-                       // For GLSL we need to retrieve the GPU material attribute
-                       Material* blmat = current_polymat->GetBlenderMaterial();
-                       Scene* blscene = current_polymat->GetBlenderScene();
-                       if (!wireframe && blscene && blmat)
-                               GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
-                       else
-                               memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
-                       // DM draw can mess up blending mode, restore at the end
-                       int current_blend_mode = GPU_get_material_alpha_blend();
-                       ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
-                       GPU_set_material_alpha_blend(current_blend_mode);
-               }
-               else {
-                       //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
-                       current_blmat_nr = current_polymat->GetMaterialIndex();
-                       current_image = current_polymat->GetBlenderImage();
-                       ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
-               }
-               return;
-       }
-       // iterate over display arrays, each containing an index + vertex array
-       for (ms.begin(it); !ms.end(it); ms.next(it)) {
-               RAS_TexVert *vertex;
-               size_t i, j, numvert;
-               
-               numvert = it.array->m_type;
-
-               if (it.array->m_type == RAS_DisplayArray::LINE) {
-                       // line drawing
-                       glBegin(GL_LINES);
-
-                       for (i=0; i<it.totindex; i+=2)
-                       {
-                               vertex = &it.vertex[it.index[i]];
-                               glVertex3fv(vertex->getXYZ());
-
-                               vertex = &it.vertex[it.index[i+1]];
-                               glVertex3fv(vertex->getXYZ());
-                       }
-
-                       glEnd();
-               }
-               else {
-                       // triangle and quad drawing
-                       if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
-                               glBegin(GL_TRIANGLES);
-                       else
-                               glBegin(GL_QUADS);
-
-                       for (i=0; i<it.totindex; i+=numvert)
-                       {
-                               if (obcolor)
-                                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-
-                               for (j=0; j<numvert; j++) {
-                                       vertex = &it.vertex[it.index[i+j]];
-
-                                       if (!wireframe) {
-                                               if (!obcolor)
-                                                       glColor4ubv((const GLubyte *)(vertex->getRGBA()));
-
-                                               glNormal3fv(vertex->getNormal());
-
-                                               if (multi)
-                                                       TexCoord(*vertex);
-                                               else
-                                                       glTexCoord2fv(vertex->getUV1());
-                                       }
-
-                                       glVertex3fv(vertex->getXYZ());
-                               }
-                       }
-
-                       glEnd();
-               }
-       }
+       if (ms.m_pDerivedMesh)
+               m_failsafe_storage->IndexPrimitivesMulti(ms);
+       else
+               m_storage->IndexPrimitivesMulti(ms);
 }
 
 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
index 88bb0be531b75faba9f702bb90f711670837dd72..c156ee53ed39e3ac7f2ca6becc66b7dc911902ac 100644 (file)
@@ -41,6 +41,7 @@
 using namespace std;
 
 #include "RAS_IRasterizer.h"
+#include "RAS_IStorage.h"
 #include "RAS_MaterialBucket.h"
 #include "RAS_ICanvas.h"
 
@@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
        float                   m_ambr;
        float                   m_ambg;
        float                   m_ambb;
-
        double                  m_time;
        MT_Matrix4x4    m_viewmatrix;
        MT_Matrix4x4    m_viewinvmatrix;
@@ -115,9 +115,15 @@ protected:
        /** Stores the caching information for the last material activated. */
        RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
 
+       /** Making use of a Strategy desing pattern for storage behavior.
+           Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/
+       int                             m_storage_type;
+       RAS_IStorage*   m_storage;
+       RAS_IStorage*   m_failsafe_storage; //So derived mesh can use immediate mode
+
 public:
        double GetTime();
-       RAS_OpenGLRasterizer(RAS_ICanvas* canv);
+       RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE);
        virtual ~RAS_OpenGLRasterizer();
 
        /*enum DrawType
@@ -166,8 +172,6 @@ public:
                                                class RAS_IPolyMaterial* polymat,
                                                class RAS_IRenderTools* rendertools);
 
-       void                    IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
-
        virtual void    SetProjectionMatrix(MT_CmMatrix4x4 & mat);
        virtual void    SetProjectionMatrix(const MT_Matrix4x4 & mat);
        virtual void    SetViewMatrix(
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
new file mode 100644 (file)
index 0000000..7b38b3b
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageIM.h"
+
+#include "GL/glew.h"
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+
+#include "DNA_meshdata_types.h"
+
+extern "C"{
+       #include "BLI_utildefines.h"
+       #include "BKE_DerivedMesh.h"
+}
+
+RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+       m_texco_num(texco_num),
+       m_texco(texco),
+       m_attrib_num(attrib_num),
+       m_attrib(attrib)
+{
+}
+RAS_StorageIM::~RAS_StorageIM()
+{
+}
+
+bool RAS_StorageIM::Init()
+{
+       return true;
+}
+void RAS_StorageIM::Exit()
+{
+}
+
+void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageIM::TexCoord(const RAS_TexVert &tv)
+{
+       int unit;
+
+       if (GLEW_ARB_multitexture) {
+               for (unit = 0; unit < *m_texco_num; unit++) {
+                       switch(m_texco[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit));
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent());
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+       if (GLEW_ARB_vertex_program) {
+               int uv = 0;
+               for (unit = 0; unit < *m_attrib_num; unit++) {
+                       switch(m_attrib[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glVertexAttrib3fvARB(unit, tv.getXYZ());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glVertexAttrib2fvARB(unit, tv.getUV(uv++));
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glVertexAttrib3fvARB(unit, tv.getNormal());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glVertexAttrib4fvARB(unit, tv.getTangent());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_VCOL:
+                                       glVertexAttrib4ubvARB(unit, tv.getRGBA());
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+}
+
+void RAS_StorageIM::SetCullFace(bool enable)
+{
+       if (enable)
+               glEnable(GL_CULL_FACE);
+       else
+               glDisable(GL_CULL_FACE);
+}
+
+static bool current_wireframe;
+static RAS_MaterialBucket *current_bucket;
+static RAS_IPolyMaterial *current_polymat;
+static RAS_MeshSlot *current_ms;
+static RAS_MeshObject *current_mesh;
+static int current_blmat_nr;
+static GPUVertexAttribs current_gpu_attribs;
+static Image *current_image;
+static int CheckMaterialDM(int matnr, void *attribs)
+{
+       // only draw the current material
+       if (matnr != current_blmat_nr)
+               return 0;
+       GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
+       if (gattribs)
+               memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
+       return 1;
+}
+
+/*
+static int CheckTexfaceDM(void *mcol, int index)
+{
+
+       // index is the original face index, retrieve the polygon
+       RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
+               current_mesh->GetPolygon(index) : NULL;
+       if (polygon && polygon->GetMaterial() == current_bucket) {
+               // must handle color.
+               if (current_wireframe)
+                       return 2;
+               if (current_ms->m_bObjectColor) {
+                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
+                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                       // don't use mcol
+                       return 2;
+               }
+               if (!mcol) {
+                       // we have to set the color from the material
+                       unsigned char rgba[4];
+                       current_polymat->GetMaterialRGBAColor(rgba);
+                       glColor4ubv((const GLubyte *)rgba);
+                       return 2;
+               }
+               return 1;
+       }
+       return 0;
+}
+*/
+
+static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
+{
+
+       // index is the original face index, retrieve the polygon
+       if (matnr == current_blmat_nr &&
+               (tface == NULL || tface->tpage == current_image)) {
+               // must handle color.
+               if (current_wireframe)
+                       return DM_DRAW_OPTION_NO_MCOL;
+               if (current_ms->m_bObjectColor) {
+                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
+                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                       // don't use mcol
+                       return DM_DRAW_OPTION_NO_MCOL;
+               }
+               if (!has_mcol) {
+                       // we have to set the color from the material
+                       unsigned char rgba[4];
+                       current_polymat->GetMaterialRGBAColor(rgba);
+                       glColor4ubv((const GLubyte *)rgba);
+                       return DM_DRAW_OPTION_NO_MCOL;
+               }
+               return DM_DRAW_OPTION_NORMAL;
+       }
+       return DM_DRAW_OPTION_SKIP;
+}
+
+void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{ 
+       bool obcolor = ms.m_bObjectColor;
+       bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+       MT_Vector4& rgba = ms.m_RGBAcolor;
+       RAS_MeshSlot::iterator it;
+
+       if (ms.m_pDerivedMesh) {
+               // mesh data is in derived mesh, 
+               current_bucket = ms.m_bucket;
+               current_polymat = current_bucket->GetPolyMaterial();
+               current_ms = &ms;
+               current_mesh = ms.m_mesh;
+               current_wireframe = wireframe;
+               // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
+
+               // handle two-side
+               if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
+                       this->SetCullFace(true);
+               else
+                       this->SetCullFace(false);
+
+               if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+                       // GetMaterialIndex return the original mface material index, 
+                       // increment by 1 to match what derived mesh is doing
+                       current_blmat_nr = current_polymat->GetMaterialIndex()+1;
+                       // For GLSL we need to retrieve the GPU material attribute
+                       Material* blmat = current_polymat->GetBlenderMaterial();
+                       Scene* blscene = current_polymat->GetBlenderScene();
+                       if (!wireframe && blscene && blmat)
+                               GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
+                       else
+                               memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
+                       // DM draw can mess up blending mode, restore at the end
+                       int current_blend_mode = GPU_get_material_alpha_blend();
+                       ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
+                       GPU_set_material_alpha_blend(current_blend_mode);
+               } else {
+                       //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
+                       current_blmat_nr = current_polymat->GetMaterialIndex();
+                       current_image = current_polymat->GetBlenderImage();
+                       ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
+               }
+               return;
+       }
+       // iterate over display arrays, each containing an index + vertex array
+       for (ms.begin(it); !ms.end(it); ms.next(it)) {
+               RAS_TexVert *vertex;
+               size_t i, j, numvert;
+               
+               numvert = it.array->m_type;
+
+               if (it.array->m_type == RAS_DisplayArray::LINE) {
+                       // line drawing
+                       glBegin(GL_LINES);
+
+                       for (i = 0; i < it.totindex; i += 2)
+                       {
+                               vertex = &it.vertex[it.index[i]];
+                               glVertex3fv(vertex->getXYZ());
+
+                               vertex = &it.vertex[it.index[i+1]];
+                               glVertex3fv(vertex->getXYZ());
+                       }
+
+                       glEnd();
+               }
+               else {
+                       // triangle and quad drawing
+                       if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+                               glBegin(GL_TRIANGLES);
+                       else
+                               glBegin(GL_QUADS);
+
+                       for (i = 0; i < it.totindex; i += numvert)
+                       {
+                               if (obcolor)
+                                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+
+                               for (j = 0; j < numvert; j++) {
+                                       vertex = &it.vertex[it.index[i+j]];
+
+                                       if (!wireframe) {
+                                               if (!obcolor)
+                                                       glColor4ubv((const GLubyte *)(vertex->getRGBA()));
+
+                                               glNormal3fv(vertex->getNormal());
+
+                                               if (multi)
+                                                       TexCoord(*vertex);
+                                               else
+                                                       glTexCoord2fv(vertex->getUV(0));
+                                       }
+
+                                       glVertex3fv(vertex->getXYZ());
+                               }
+                       }
+
+                       glEnd();
+               }
+       }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
new file mode 100644 (file)
index 0000000..de4ff30
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_IMMEDIATEMODESTORAGE
+#define __KX_IMMEDIATEMODESTORAGE
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+class RAS_StorageIM : public RAS_IStorage
+{
+public:
+       RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+       virtual ~RAS_StorageIM();
+
+       virtual bool    Init();
+       virtual void    Exit();
+
+       virtual void    IndexPrimitives(RAS_MeshSlot& ms);
+       virtual void    IndexPrimitivesMulti(class RAS_MeshSlot& ms);
+
+       virtual void    SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+       int                             m_drawingmode;
+       int*                    m_texco_num;
+       int*                    m_attrib_num;
+       RAS_IRasterizer::TexCoGen*              m_texco;
+       RAS_IRasterizer::TexCoGen*              m_attrib;
+
+       void    TexCoord(const RAS_TexVert &tv);
+       void    SetCullFace(bool enable);
+
+       void    IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+       void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); }
+       void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_IMMEDIATEMODESTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
new file mode 100644 (file)
index 0000000..e0d580e
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageVA.h"
+
+#include "GL/glew.h"
+
+RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+       m_texco_num(texco_num),
+       m_texco(texco),
+       m_attrib_num(attrib_num),
+       m_attrib(attrib),
+       m_last_texco_num(0),
+       m_last_attrib_num(0)
+{
+}
+
+RAS_StorageVA::~RAS_StorageVA()
+{
+}
+
+bool RAS_StorageVA::Init()
+{
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+       return true;
+}
+
+void RAS_StorageVA::Exit()
+{
+}
+
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
+{
+       static const GLsizei stride = sizeof(RAS_TexVert);
+       bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+       RAS_MeshSlot::iterator it;
+       GLenum drawmode;
+
+       if (!wireframe)
+               glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glEnableClientState(GL_NORMAL_ARRAY);
+
+       // use glDrawElements to draw each vertexarray
+       for (ms.begin(it); !ms.end(it); ms.next(it)) {
+               if (it.totindex == 0)
+                       continue;
+
+               // drawing mode
+               if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+                       drawmode = GL_TRIANGLES;
+               else if (it.array->m_type == RAS_DisplayArray::QUAD)
+                       drawmode = GL_QUADS;
+               else
+                       drawmode = GL_LINES;
+
+               // colors
+               if (drawmode != GL_LINES && !wireframe) {
+                       if (ms.m_bObjectColor) {
+                               const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+                               glDisableClientState(GL_COLOR_ARRAY);
+                               glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                       }
+                       else {
+                               glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+                               glEnableClientState(GL_COLOR_ARRAY);
+                       }
+               }
+               else
+                       glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+               glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+               glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+               if (!wireframe) {
+                       glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
+                       if (glIsEnabled(GL_COLOR_ARRAY))
+                               glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+               }
+
+               // here the actual drawing takes places
+               glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+       }
+       
+       glDisableClientState(GL_VERTEX_ARRAY);
+       glDisableClientState(GL_NORMAL_ARRAY);
+       if (!wireframe) {
+               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+               glDisableClientState(GL_COLOR_ARRAY);
+       }
+}
+
+void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+       static const GLsizei stride = sizeof(RAS_TexVert);
+       bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
+       RAS_MeshSlot::iterator it;
+       GLenum drawmode;
+
+       if (!wireframe)
+               EnableTextures(true);
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glEnableClientState(GL_NORMAL_ARRAY);
+
+       // use glDrawElements to draw each vertexarray
+       for (ms.begin(it); !ms.end(it); ms.next(it)) {
+               if (it.totindex == 0)
+                       continue;
+
+               // drawing mode
+               if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+                       drawmode = GL_TRIANGLES;
+               else if (it.array->m_type == RAS_DisplayArray::QUAD)
+                       drawmode = GL_QUADS;
+               else
+                       drawmode = GL_LINES;
+
+               // colors
+               if (drawmode != GL_LINES && !wireframe) {
+                       if (ms.m_bObjectColor) {
+                               const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+                               glDisableClientState(GL_COLOR_ARRAY);
+                               glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                               use_color_array = false;
+                       }
+                       else {
+                               glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+                               glEnableClientState(GL_COLOR_ARRAY);
+                               use_color_array = true;
+                       }
+               }
+               else
+                       glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+               glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+               glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+
+               if (!wireframe) {
+                       TexCoordPtr(it.vertex);
+                       if (use_color_array)
+                               glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+               }
+
+               // here the actual drawing takes places
+               glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+       }
+       
+       glDisableClientState(GL_VERTEX_ARRAY);
+       glDisableClientState(GL_NORMAL_ARRAY);
+       if (!wireframe) {
+               glDisableClientState(GL_COLOR_ARRAY);
+               EnableTextures(false);
+       }
+}
+
+void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
+{
+       /* note: this function must closely match EnableTextures to enable/disable
+        * the right arrays, otherwise coordinate and attribute pointers from other
+        * materials can still be used and cause crashes */
+       int unit;
+
+       if (GLEW_ARB_multitexture)
+       {
+               for (unit = 0; unit < *m_texco_num; unit++)
+               {
+                       glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
+                       switch (m_texco[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+
+               glClientActiveTextureARB(GL_TEXTURE0_ARB);
+       }
+
+       if (GLEW_ARB_vertex_program) {
+               int uv = 0;
+               for (unit = 0; unit < *m_attrib_num; unit++) {
+                       switch (m_attrib[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_VCOL:
+                                       glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+}
+
+void RAS_StorageVA::EnableTextures(bool enable)
+{
+       RAS_IRasterizer::TexCoGen *texco, *attrib;
+       int unit, texco_num, attrib_num;
+
+       /* we cache last texcoords and attribs to ensure we disable the ones that
+        * were actually last set */
+       if (enable) {
+               texco = m_texco;
+               texco_num = *m_texco_num;
+               attrib = m_attrib;
+               attrib_num = *m_attrib_num;
+               
+               memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
+               m_last_texco_num = *m_texco_num;
+               memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
+               m_last_attrib_num = *m_attrib_num;
+       }
+       else {
+               texco = m_last_texco;
+               texco_num = m_last_texco_num;
+               attrib = m_last_attrib;
+               attrib_num = m_last_attrib_num;
+       }
+
+       if (GLEW_ARB_multitexture) {
+               for (unit = 0; unit < texco_num; unit++) {
+                       glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
+
+                       switch (texco[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       break;
+                               default:
+                                       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       break;
+                       }
+               }
+
+               glClientActiveTextureARB(GL_TEXTURE0_ARB);
+       }
+       else {
+               if (texco_num) {
+                       if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                       else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+               }
+       }
+
+       if (GLEW_ARB_vertex_program) {
+               for (unit = 0; unit < attrib_num; unit++) {
+                       switch (attrib[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                               case RAS_IRasterizer::RAS_TEXCO_VCOL:
+                                       if (enable) glEnableVertexAttribArrayARB(unit);
+                                       else glDisableVertexAttribArrayARB(unit);
+                                       break;
+                               default:
+                                       glDisableVertexAttribArrayARB(unit);
+                                       break;
+                       }
+               }
+       }
+
+       if (!enable) {
+               m_last_texco_num = 0;
+               m_last_attrib_num = 0;
+       }
+}
+
similarity index 57%
rename from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
rename to source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
index 6b159db05ed58e86cbd8e3643f206deedf70081f..da7766ec5cad4ce992832234eeb3434baba909eb 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file RAS_VAOpenGLRasterizer.h
- *  \ingroup bgerastogl
- */
+#ifndef __KX_VERTEXARRAYSTORAGE
+#define __KX_VERTEXARRAYSTORAGE
 
-#ifndef __RAS_VAOPENGLRASTERIZER_H__
-#define __RAS_VAOPENGLRASTERIZER_H__
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
 
 #include "RAS_OpenGLRasterizer.h"
 
-class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
+class RAS_StorageVA : public RAS_IStorage
 {
-       void TexCoordPtr(const RAS_TexVert *tv);
-       /* bool m_Lock; */ /* UNUSED */
-
-       TexCoGen                m_last_texco[RAS_MAX_TEXCO];
-       TexCoGen                m_last_attrib[RAS_MAX_ATTRIB];
-       int                             m_last_texco_num;
-       int                             m_last_attrib_num;
 
 public:
-       RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
-       virtual ~RAS_VAOpenGLRasterizer();
+       RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+       virtual ~RAS_StorageVA();
 
        virtual bool    Init();
        virtual void    Exit();
 
-       virtual void    SetDrawingMode(int drawingmode);
-
-       virtual void    IndexPrimitives(class RAS_MeshSlot& ms);
+       virtual void    IndexPrimitives(RAS_MeshSlot& ms);
        virtual void    IndexPrimitivesMulti(class RAS_MeshSlot& ms);
 
-private:
+       virtual void    SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+       int                             m_drawingmode;
+
+       int*                    m_texco_num;
+       int*                    m_attrib_num;
+
+       int                             m_last_texco_num;
+       int                             m_last_attrib_num;
+
+       RAS_IRasterizer::TexCoGen*              m_texco;
+       RAS_IRasterizer::TexCoGen*              m_attrib;
+
+       RAS_IRasterizer::TexCoGen               m_last_texco[RAS_MAX_TEXCO];
+       RAS_IRasterizer::TexCoGen               m_last_attrib[RAS_MAX_ATTRIB];
+
        virtual void    EnableTextures(bool enable);
-       //virtual bool  QueryArrays() {return true;}
-       //virtual bool  QueryLists() {return m_Lock;}
+       virtual void    TexCoordPtr(const RAS_TexVert *tv);
 
 
 #ifdef WITH_CXX_GUARDEDALLOC
-       MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer")
+public:
+       void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+       void operator delete( void *mem ) { MEM_freeN(mem); }
 #endif
 };
 
-#endif  /* __RAS_VAOPENGLRASTERIZER_H__ */
+#endif //__KX_VERTEXARRAYSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
new file mode 100644 (file)
index 0000000..d40aa98
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageVBO.h"
+#include "RAS_MeshObject.h"
+
+#include "GL/glew.h"
+
+VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
+{
+       this->data = data;
+       this->size = data->m_vertex.size();
+       this->indices = indices;
+       this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding
+
+       //      Determine drawmode
+       if (data->m_type == data->QUAD)
+               this->mode = GL_QUADS;
+       else if (data->m_type == data->TRIANGLE)
+               this->mode = GL_TRIANGLES;
+       else
+               this->mode = GL_LINE;
+
+       // Generate Buffers
+       glGenBuffersARB(1, &this->ibo);
+       glGenBuffersARB(1, &this->vbo_id);
+
+       // Fill the buffers with initial data
+       UpdateIndices();
+       UpdateData();
+
+       // Establish offsets
+       this->vertex_offset = 0;
+       this->normal_offset = (void*)(3*sizeof(GLfloat));
+       this->tangent_offset = (void*)(6*sizeof(GLfloat));
+       this->color_offset = (void*)(10*sizeof(GLfloat));
+       this->uv_offset = (void*)(11*sizeof(GLfloat));
+}
+
+VBO::~VBO()
+{
+       glDeleteBuffersARB(1, &this->ibo);
+       glDeleteBuffersARB(1, &this->vbo_id);
+}
+
+void VBO::UpdateData()
+{
+       unsigned int i, j, k;
+       
+       glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+       glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW);
+
+       // Map the buffer
+       GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+       // Gather data
+       for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
+       {
+               memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
+               memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
+               memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
+               memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
+
+               for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
+                       memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
+       }
+       
+       glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+}
+
+void VBO::UpdateIndices()
+{
+       int space = data->m_index.size() * sizeof(GLushort);
+       glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+
+       // Upload Data to VBO
+       glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW);
+}
+
+void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi)
+{
+       int unit;
+       
+       // Bind buffers
+       glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+       glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+
+       // Vertexes
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+
+       // Normals
+       glEnableClientState(GL_NORMAL_ARRAY);
+       glNormalPointer(GL_FLOAT, this->stride, this->normal_offset);
+
+       // Colors
+       glEnableClientState(GL_COLOR_ARRAY);
+       glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset);
+
+       if (multi)
+       {
+               for (unit = 0; unit < texco_num; ++unit)
+               {
+                       glClientActiveTexture(GL_TEXTURE0_ARB + unit);
+                       switch (texco[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit)));
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset);
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                                       glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset);
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               glClientActiveTextureARB(GL_TEXTURE0_ARB);
+       }
+       else //TexFace
+       {
+               glClientActiveTextureARB(GL_TEXTURE0_ARB);
+               glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+               glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset);
+       }
+
+       if (GLEW_ARB_vertex_program)
+       {
+               int uv = 0;
+               for (unit = 0; unit < attrib_num; ++unit)
+               {
+                       switch (attrib[unit]) {
+                               case RAS_IRasterizer::RAS_TEXCO_ORCO:
+                               case RAS_IRasterizer::RAS_TEXCO_GLOB:
+                                       glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset);
+                                       glEnableVertexAttribArrayARB(unit);
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_UV:
+                                       glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv));
+                                       uv += sizeof(GLfloat)*2;
+                                       glEnableVertexAttribArrayARB(unit);
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXCO_NORM:
+                                       glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset);
+                                       glEnableVertexAttribArrayARB(unit);
+                                       break;
+                               case RAS_IRasterizer::RAS_TEXTANGENT:
+                                       glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset);
+                                       glEnableVertexAttribArrayARB(unit);
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+       
+       glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0);
+
+       glDisableClientState(GL_VERTEX_ARRAY);
+       glDisableClientState(GL_NORMAL_ARRAY);
+       glDisableClientState(GL_COLOR_ARRAY);
+       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+       if (GLEW_ARB_vertex_program)
+       {
+               for (int i = 0; i < attrib_num; ++i)
+                       glDisableVertexAttribArrayARB(i);
+       }
+
+       glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+       glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ }
+
+RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib):
+       m_texco_num(texco_num),
+       m_texco(texco),
+       m_attrib_num(attrib_num),
+       m_attrib(attrib)
+{
+}
+
+RAS_StorageVBO::~RAS_StorageVBO()
+{
+}
+
+bool RAS_StorageVBO::Init()
+{
+       return true;
+}
+
+void RAS_StorageVBO::Exit()
+{
+       m_vbo_lookup.clear();
+}
+
+void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+       IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{
+       RAS_MeshSlot::iterator it;
+       VBO *vbo;
+       
+       for (ms.begin(it); !ms.end(it); ms.next(it))
+       {
+               vbo = m_vbo_lookup[it.array];
+
+               if (vbo == 0)
+                       m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex);
+
+               // Update the vbo
+               if (ms.m_mesh->MeshModified())
+               {
+                       vbo->UpdateData();
+               }
+
+               vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi);
+       }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
new file mode 100644 (file)
index 0000000..d8d8192
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE
+#define __KX_VERTEXBUFFEROBJECTSTORAGE
+
+#include <map>
+#include "GL/glew.h"
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+#include "RAS_OpenGLRasterizer.h"
+
+class VBO
+{
+public:
+       VBO(RAS_DisplayArray *data, unsigned int indices);
+       ~VBO();
+
+       void    Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi);
+
+       void    UpdateData();
+       void    UpdateIndices();
+private:
+       RAS_DisplayArray*       data;
+       GLuint                  size;
+       GLuint                  stride;
+       GLuint                  indices;
+       GLenum                  mode;
+       GLuint                  ibo;
+       GLuint                  vbo_id;
+
+       void*                   vertex_offset;
+       void*                   normal_offset;
+       void*                   color_offset;
+       void*                   tangent_offset;
+       void*                   uv_offset;
+};
+
+class RAS_StorageVBO : public RAS_IStorage
+{
+
+public:
+       RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+       virtual ~RAS_StorageVBO();
+
+       virtual bool    Init();
+       virtual void    Exit();
+
+       virtual void    IndexPrimitives(RAS_MeshSlot& ms);
+       virtual void    IndexPrimitivesMulti(RAS_MeshSlot& ms);
+
+       virtual void    SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+       int                             m_drawingmode;
+
+       int*                    m_texco_num;
+       int*                    m_attrib_num;
+
+       RAS_IRasterizer::TexCoGen*              m_texco;
+       RAS_IRasterizer::TexCoGen*              m_attrib;
+
+       std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup;
+
+       virtual void                    IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+       void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+       void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_VERTEXBUFFEROBJECTSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
deleted file mode 100644 (file)
index 076acb0..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
- *  \ingroup bgerastogl
- */
-
-#include "RAS_VAOpenGLRasterizer.h"
-#include <stdlib.h>
-
-#include "GL/glew.h"
-#include "GPU_extensions.h"
-
-#include "STR_String.h"
-#include "RAS_TexVert.h"
-#include "MT_CmMatrix4x4.h"
-#include "RAS_IRenderTools.h" // rendering text
-       
-RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
-:      RAS_OpenGLRasterizer(canvas),
-       /* m_Lock(lock && GLEW_EXT_compiled_vertex_array), */ /* UNUSED */
-       m_last_texco_num(0),
-       m_last_attrib_num(0)
-{
-}
-
-RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
-{
-}
-
-bool RAS_VAOpenGLRasterizer::Init(void)
-{
-       
-       bool result = RAS_OpenGLRasterizer::Init();
-       
-       if (result)
-       {
-               glEnableClientState(GL_VERTEX_ARRAY);
-               glEnableClientState(GL_NORMAL_ARRAY);
-               glDisableClientState(GL_COLOR_ARRAY);
-               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
-               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-       }
-
-       return result;
-}
-
-void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
-{
-       m_drawingmode = drawingmode;
-
-       switch (m_drawingmode)
-       {
-               case KX_BOUNDINGBOX:
-               case KX_WIREFRAME:
-                       //glDisableClientState(GL_COLOR_ARRAY);
-                       //glDisable(GL_CULL_FACE);
-                       break;
-               case KX_SOLID:
-                       //glDisableClientState(GL_COLOR_ARRAY);
-                       break;
-               case KX_TEXTURED:
-               case KX_SHADED:
-               case KX_SHADOW:
-                       //glEnableClientState(GL_COLOR_ARRAY);
-               default:
-                       break;
-       }
-}
-
-void RAS_VAOpenGLRasterizer::Exit()
-{
-       glDisableClientState(GL_VERTEX_ARRAY);
-       glDisableClientState(GL_NORMAL_ARRAY);
-       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-       glDisableClientState(GL_COLOR_ARRAY);
-
-       RAS_OpenGLRasterizer::Exit();
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
-{
-       static const GLsizei stride = sizeof(RAS_TexVert);
-       bool wireframe = m_drawingmode <= KX_WIREFRAME;
-       RAS_MeshSlot::iterator it;
-       GLenum drawmode;
-
-       if (ms.m_pDerivedMesh) {
-               // cannot be handled here, pass to RAS_OpenGLRasterizer
-               RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
-               return;
-       }
-
-       if (!wireframe)
-               glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-       // use glDrawElements to draw each vertexarray
-       for (ms.begin(it); !ms.end(it); ms.next(it)) {
-               if (it.totindex == 0)
-                       continue;
-
-               // drawing mode
-               if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
-                       drawmode = GL_TRIANGLES;
-               else if (it.array->m_type == RAS_DisplayArray::QUAD)
-                       drawmode = GL_QUADS;
-               else
-                       drawmode = GL_LINES;
-
-               // colors
-               if (drawmode != GL_LINES && !wireframe) {
-                       if (ms.m_bObjectColor) {
-                               const MT_Vector4& rgba = ms.m_RGBAcolor;
-
-                               glDisableClientState(GL_COLOR_ARRAY);
-                               glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-                       }
-                       else {
-                               glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-                               glEnableClientState(GL_COLOR_ARRAY);
-                       }
-               }
-               else
-                       glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
-               glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
-               glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
-               if (!wireframe) {
-                       glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1());
-                       if (glIsEnabled(GL_COLOR_ARRAY))
-                               glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
-               }
-
-               // here the actual drawing takes places
-               glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
-       }
-
-       if (!wireframe) {
-               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-               glDisableClientState(GL_COLOR_ARRAY);
-       }
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
-{
-       static const GLsizei stride = sizeof(RAS_TexVert);
-       bool wireframe = m_drawingmode <= KX_WIREFRAME;
-       RAS_MeshSlot::iterator it;
-       GLenum drawmode;
-
-       if (ms.m_pDerivedMesh) {
-               // cannot be handled here, pass to RAS_OpenGLRasterizer
-               RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
-               return;
-       }
-
-       if (!wireframe)
-               EnableTextures(true);
-
-       // use glDrawElements to draw each vertexarray
-       for (ms.begin(it); !ms.end(it); ms.next(it)) {
-               if (it.totindex == 0)
-                       continue;
-
-               // drawing mode
-               if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
-                       drawmode = GL_TRIANGLES;
-               else if (it.array->m_type == RAS_DisplayArray::QUAD)
-                       drawmode = GL_QUADS;
-               else
-                       drawmode = GL_LINES;
-
-               // colors
-               if (drawmode != GL_LINES && !wireframe) {
-                       if (ms.m_bObjectColor) {
-                               const MT_Vector4& rgba = ms.m_RGBAcolor;
-
-                               glDisableClientState(GL_COLOR_ARRAY);
-                               glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-                       }
-                       else {
-                               glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-                               glEnableClientState(GL_COLOR_ARRAY);
-                       }
-               }
-               else
-                       glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
-               glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
-               glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
-               if (!wireframe) {
-                       TexCoordPtr(it.vertex);
-                       if (glIsEnabled(GL_COLOR_ARRAY))
-                               glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
-               }
-
-               // here the actual drawing takes places
-               glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
-       }
-
-       if (!wireframe) {
-               glDisableClientState(GL_COLOR_ARRAY);
-               EnableTextures(false);
-       }
-}
-
-void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
-{
-       /* note: this function must closely match EnableTextures to enable/disable
-        * the right arrays, otherwise coordinate and attribute pointers from other
-        * materials can still be used and cause crashes */
-       int unit;
-
-       if (GLEW_ARB_multitexture)
-       {
-               for (unit=0; unit<m_texco_num; unit++)
-               {
-                       glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
-                       if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) {
-                               glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                               glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
-                               continue;
-                       }
-                       switch (m_texco[unit]) {
-                       case RAS_TEXCO_ORCO:
-                       case RAS_TEXCO_GLOB:
-                               glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
-                               break;
-                       case RAS_TEXCO_UV1:
-                               glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
-                               break;
-                       case RAS_TEXCO_NORM:
-                               glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
-                               break;
-                       case RAS_TEXTANGENT:
-                               glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
-                               break;
-                       case RAS_TEXCO_UV2:
-                               glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
-                               break;
-                       default:
-                               break;
-                       }
-               }
-
-               glClientActiveTextureARB(GL_TEXTURE0_ARB);
-       }
-
-       if (GLEW_ARB_vertex_program) {
-               for (unit=0; unit<m_attrib_num; unit++) {
-                       switch (m_attrib[unit]) {
-                       case RAS_TEXCO_ORCO:
-                       case RAS_TEXCO_GLOB:
-                               glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
-                               break;
-                       case RAS_TEXCO_UV1:
-                               glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
-                               break;
-                       case RAS_TEXCO_NORM:
-                               glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
-                               break;
-                       case RAS_TEXTANGENT:
-                               glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
-                               break;
-                       case RAS_TEXCO_UV2:
-                               glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
-                               break;
-                       case RAS_TEXCO_VCOL:
-                               glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
-                               break;
-                       default:
-                               break;
-                       }
-               }
-       }
-}
-
-void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
-{
-       TexCoGen *texco, *attrib;
-       int unit, texco_num, attrib_num;
-
-       /* we cache last texcoords and attribs to ensure we disable the ones that
-        * were actually last set */
-       if (enable) {
-               texco = m_texco;
-               texco_num = m_texco_num;
-               attrib = m_attrib;
-               attrib_num = m_attrib_num;
-               
-               memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num);
-               m_last_texco_num = m_texco_num;
-               memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num);
-               m_last_attrib_num = m_attrib_num;
-       }
-       else {
-               texco = m_last_texco;
-               texco_num = m_last_texco_num;
-               attrib = m_last_attrib;
-               attrib_num = m_last_attrib_num;
-       }
-
-       if (GLEW_ARB_multitexture) {
-               for (unit=0; unit<texco_num; unit++) {
-                       glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
-
-                       switch (texco[unit]) {
-                       case RAS_TEXCO_ORCO:
-                       case RAS_TEXCO_GLOB:
-                       case RAS_TEXCO_UV1:
-                       case RAS_TEXCO_NORM:
-                       case RAS_TEXTANGENT:
-                       case RAS_TEXCO_UV2:
-                               if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                               else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-                               break;
-                       default:
-                               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-                               break;
-                       }
-               }
-
-               glClientActiveTextureARB(GL_TEXTURE0_ARB);
-       }
-       else {
-               if (texco_num) {
-                       if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                       else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-               }
-       }
-
-       if (GLEW_ARB_vertex_program) {
-               for (unit=0; unit<attrib_num; unit++) {
-                       switch (attrib[unit]) {
-                       case RAS_TEXCO_ORCO:
-                       case RAS_TEXCO_GLOB:
-                       case RAS_TEXCO_UV1:
-                       case RAS_TEXCO_NORM:
-                       case RAS_TEXTANGENT:
-                       case RAS_TEXCO_UV2:
-                       case RAS_TEXCO_VCOL:
-                               if (enable) glEnableVertexAttribArrayARB(unit);
-                               else glDisableVertexAttribArrayARB(unit);
-                               break;
-                       default:
-                               glDisableVertexAttribArrayARB(unit);
-                               break;
-                       }
-               }
-       }
-
-       if (!enable) {
-               m_last_texco_num = 0;
-               m_last_attrib_num = 0;
-       }
-}
-
index 945644ff3e62462253c7e3ac53b9e65a5838407d..0a90054275bc103172a7b7c771bd5a1806ae7c67 100644 (file)
@@ -34,8 +34,7 @@
 #include "MT_Matrix4x4.h"
 
 RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
-                                                const MT_Point2& uv,
-                                                const MT_Point2& uv2,
+                                                const MT_Point2 uvs[MAX_UNIT],
                                                 const MT_Vector4& tangent,
                                                 const unsigned int rgba,
                                                 const MT_Vector3& normal,
@@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
                                                 const unsigned int origindex)
 {
        xyz.getValue(m_localxyz);
-       uv.getValue(m_uv1);
-       uv2.getValue(m_uv2);
        SetRGBA(rgba);
        SetNormal(normal);
        tangent.getValue(m_tangent);
@@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
        m_origindex = origindex;
        m_unit = 2;
        m_softBodyIndex = -1;
+
+       for (int i = 0; i < MAX_UNIT; ++i)
+       {
+               uvs[i].getValue(m_uvs[i]);
+       }
 }
 
 const MT_Point3& RAS_TexVert::xyz()
@@ -80,26 +82,15 @@ void RAS_TexVert::SetXYZ(const float xyz[3])
        m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2];
 }
 
-void RAS_TexVert::SetUV1(const MT_Point2& uv)
-{
-       uv.getValue(m_uv1);
-}
-
-void RAS_TexVert::SetUV1(const float uv[3])
+void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
 {
-       m_uv1[0] = uv[0];
-       m_uv1[1] = uv[1];
+       uv.getValue(m_uvs[index]);
 }
 
-void RAS_TexVert::SetUV2(const MT_Point2& uv)
+void RAS_TexVert::SetUV(int index, const float uv[2])
 {
-       uv.getValue(m_uv2);
-}
-
-void RAS_TexVert::SetUV2(const float uv[3])
-{
-       m_uv2[0] = uv[0];
-       m_uv2[1] = uv[1];
+       m_uvs[index][0] = uv[0];
+       m_uvs[index][1] = uv[1];
 }
 
 void RAS_TexVert::SetRGBA(const unsigned int rgba)
@@ -132,14 +123,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
 // compare two vertices, and return TRUE if both are almost identical (they can be shared)
 bool RAS_TexVert::closeTo(const RAS_TexVert* other)
 {
+       bool uv_match = true;
+       for (int i=0; i<MAX_UNIT; i++)
+               uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_uvs[i]));
+
        return (
                /* m_flag == other->m_flag && */
                /* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
                m_rgba == other->m_rgba &&
                MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
                MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
-               MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
-               MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* &&
+               uv_match /* &&
                MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/);
        /* don't bother comparing m_localxyz since we know there from the same vert */
 }
@@ -162,12 +156,7 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat)
        SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue());
 }
 
-void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat)
-{
-       SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue());
-}
-
-void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat)
+void RAS_TexVert::TransformUV(int index, const MT_Matrix4x4& mat)
 {
-       SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue());
+       SetUV(index, (mat * MT_Vector4(m_uvs[index][0], m_uvs[index][1], 0.0, 1.0)).getValue());
 }
index 98ea4dd60aa1e027c574c8d4da1c12089c60e56b..a91d2c7f8483a0b2d0354bc28ad24331cb057a62 100644 (file)
@@ -48,23 +48,21 @@ class RAS_TexVert
 {
        
        float                   m_localxyz[3];  // 3*4 = 12
-       float                   m_uv1[2];               // 2*4 =  8
-       float                   m_uv2[2];               // 2*4 =  8
+       float                   m_uvs[8][2];    // 8*2*4=64             //8 = MAX_UNIT
        unsigned int    m_rgba;                 //        4
-       float                   m_tangent[4];   // 4*4 =  16
-       float                   m_normal[3];    // 3*4 =  12
+       float                   m_tangent[4];   // 4*4 = 16
+       float                   m_normal[3];    // 3*4 = 12
        short                   m_flag;                 //        2
        short                   m_softBodyIndex;                //2
        unsigned int    m_unit;                 //                4
        unsigned int    m_origindex;            //    4
                                                                        //---------
-                                                                       //       56+6+8+2=72
-       // 32 bytes total size, fits nice = 56 = not fit nice.
+                                                                       //      120
+       // 32 bytes total size, fits nice = 120 = not fit nice.
 
 public:
        enum {
                FLAT = 1,
-               SECOND_UV = 2,
                MAX_UNIT = 8
        };
 
@@ -74,8 +72,7 @@ public:
        RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
        {}
        RAS_TexVert(const MT_Point3& xyz,
-                               const MT_Point2& uv,
-                               const MT_Point2& uv2,
+                               const MT_Point2 uvs[MAX_UNIT],
                                const MT_Vector4& tangent,
                                const unsigned int rgba,
                                const MT_Vector3& normal,
@@ -83,12 +80,8 @@ public:
                                const unsigned int origindex);
        ~RAS_TexVert() {};
 
-       const float* getUV1 () const { 
-               return m_uv1;
-       };
-
-       const float* getUV2 () const { 
-               return m_uv2;
+       const float* getUV (int unit) const {
+               return m_uvs[unit];
        };
 
        const float* getXYZ() const { 
@@ -123,10 +116,8 @@ public:
 
        void                            SetXYZ(const MT_Point3& xyz);
        void                            SetXYZ(const float xyz[3]);
-       void                            SetUV1(const MT_Point2& uv);
-       void                            SetUV2(const MT_Point2& uv);
-       void                            SetUV1(const float uv[2]);
-       void                            SetUV2(const float uv[2]);
+       void                            SetUV(int index, const MT_Point2& uv);
+       void                            SetUV(int index, const float uv[2]);
 
        void                            SetRGBA(const unsigned int rgba);
        void                            SetNormal(const MT_Vector3& normal);
@@ -139,8 +130,7 @@ public:
 
        void                            Transform(const class MT_Matrix4x4& mat,
                                      const class MT_Matrix4x4& nmat);
-       void                            TransformUV1(const MT_Matrix4x4& mat);
-       void                            TransformUV2(const MT_Matrix4x4& mat);
+       void                            TransformUV(int index, const MT_Matrix4x4& mat);
 
        // compare two vertices, to test if they can be shared, used for
        // splitting up based on uv's, colors, etc
index d335a38171fe9fed84b9c6b2fd6745dbc5e9d6fc..3203fcf9d6baa89da47794db0dc6b433f3a4e9ee 100644 (file)
@@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve
        MT_Scalar d = -p[0].xyz().dot(normal);
        
 
-       MT_Matrix3x3 mat3(      p[0].getUV1()[0],p[0].getUV1()[1],      1,
-                                               p[1].getUV1()[0],p[1].getUV1()[1],      1,
-                                               p[2].getUV1()[0],p[2].getUV1()[1],      1);
+       MT_Matrix3x3 mat3(      p[0].getUV(0)[0],p[0].getUV(0)[1],      1,
+                                               p[1].getUV(0)[0],p[1].getUV(0)[1],      1,
+                                               p[2].getUV(0)[0],p[2].getUV(0)[1],      1);
 
 
        MT_Matrix3x3 mat3inv = mat3.inverse();