Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2012-12-19 00:56:25 +0400
committerMitchell Stokes <mogurijin@gmail.com>2012-12-19 00:56:25 +0400
commitef0473994b6b21aa49bbfab26a483d90d0fef004 (patch)
tree18d9dd7d2fbe6eddaf58f66b6b301c694cb43a50 /source/gameengine
parent6b2af22d37dc1a039104f2ca0b3b4b56aca7d41c (diff)
BGE: Some as of yet unmerged work I did in the Swiss branch. These changes include:
* 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.
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp15
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp726
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h5
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp55
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h14
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp3
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp15
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp12
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp25
-rw-r--r--source/gameengine/Ketsji/BL_Material.h8
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp16
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp55
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h19
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h3
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h2
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h2
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp86
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp18
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp7
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h3
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt9
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h62
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp38
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp298
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h12
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp310
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h68
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp320
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h (renamed from source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h)53
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp259
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h100
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp382
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp47
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h32
-rw-r--r--source/gameengine/Rasterizer/RAS_texmatrix.cpp6
43 files changed, 1835 insertions, 1288 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 6807f531f0a..9f788b29ac6 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -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();
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index ab0630bf398..15fc5ba76c7 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -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
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
index 2a7efaac898..f3a680929fb 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.h
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -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);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index d1684db0f5a..260ca9ede96 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -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;
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index 34a1117a0eb..eddb377dbc7 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -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);
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 06399642edd..695bf0c4dc8 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -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(
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 92db1fe790e..1dcc68c8e75 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -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);
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 23bfd7a111b..64e191fe960 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -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)
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 0954aa0f7ab..461a8c51a52 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -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 )
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index ef180ed2126..0383c0891b6 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -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
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 66423ed820e..98fff5c8b65 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -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()
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 20c36c2cc44..a55dd701826 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 7bc9c7c3863..c34a49e1bde 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index 18fb336dbe0..0dbfd7de2c6 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index a12e12ccef2..890b9d4c472 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 972594bd90f..92ffaf47aa4 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index d83e98d4712..57695df2782 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -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;
}
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index f157d9ed20a..5ce370ccdfe 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 2ce8f480c1c..89bfb4ff9fb 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -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
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 2354359af18..ab73ba1902a 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -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;
}
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 4247d138a66..8070825ad11 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -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);
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index f24e3397801..2b5b0aeac2a 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -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);
}
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 9fffc8bebc9..b267879611e 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -184,7 +184,7 @@ public:
/*
* PreCalculate texture gen
*/
- virtual void OnConstruction(int layer) {}
+ virtual void OnConstruction() {}
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index e6948025999..5a720857d50 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -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)
};
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 9fb47117f1d..54fe19a291f 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -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();
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 2ccb9453b3d..49b74895302 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -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;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 281eae8734a..d77d0483024 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -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,
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
index 189c4f78f77..11cb4b1d9f9 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
@@ -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
index 00000000000..f5c16bc8cd8
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index d74aa134779..3a60643e9e7 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index a8eb2d5ffdf..0eddde7c203 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -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);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 22a700c7d2b..1328a5521b4 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -43,6 +43,10 @@
#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)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 88bb0be531b..c156ee53ed3 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -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
index 00000000000..7b38b3b42f3
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
@@ -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
index 00000000000..de4ff30d394
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
@@ -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
index 00000000000..e0d580eff11
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -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;
+ }
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
index 6b159db05ed..da7766ec5ca 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
@@ -25,46 +25,53 @@
* ***** 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
index 00000000000..d40aa98295b
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -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
index 00000000000..d8d8192e482
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
@@ -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
index 076acb0d153..00000000000
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ /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;
- }
-}
-
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index 945644ff3e6..0a90054275b 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -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());
}
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 98ea4dd60aa..a91d2c7f848 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
index d335a38171f..3203fcf9d6b 100644
--- a/source/gameengine/Rasterizer/RAS_texmatrix.cpp
+++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
@@ -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();