Game Engine: alpha blending and sorting
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 29 Jul 2008 15:48:31 +0000 (15:48 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 29 Jul 2008 15:48:31 +0000 (15:48 +0000)
=======================================

Alpha blending + sorting was revised, to fix bugs and get it
to work more predictable.

* A new per texture face "Sort" setting defines if the face
  is alpha sorted or not, instead of abusing the "ZTransp"
  setting as it did before.
* Existing files are converted to hopefully match the old
  behavior as much as possible with a version patch.
* On new meshes the Sort flag is disabled by the default, to
  avoid unexpected and hard to find slowdowns.
* Alpha sorting for faces was incredibly slow. Sorting faces
  in a mesh with 600 faces lowered the framerate from 200 to
  70 fps in my test.. the sorting there case goes about 15x
  faster now, but it is still advised to use Clip Alpha if
  possible instead of regular Alpha.
* There still various limitations in the alpha sorting code,
  I've added some comments to the code about this.

Some docs at the bottom of the page:
http://www.blender.org/development/current-projects/changes-since-246/realtime-glsl-materials/

Merged some fixes from the apricot branch, most important
change is that  tangents are now exactly the same as the rest
of Blender, instead of being computed in the game engine with a
different algorithm.

Also, the subversion was bumped to 1.

36 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/src/buttons_editing.c
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp [deleted file]
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h [deleted file]
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/BL_BlenderShader.cpp
source/gameengine/Ketsji/BL_BlenderShader.h
source/gameengine/Ketsji/BL_Material.h
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_BucketManager.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/Rasterizer/RAS_Polygon.cpp

index f61b300f708e09dd3870a86f56a257d40a6742ed..7dc10c53e22909e1a3548259879112b2de818a03 100644 (file)
@@ -437,5 +437,7 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb);
 /* determines required DerivedMesh data according to view and edit modes */
 CustomDataMask get_viewedit_datamask();
 
+void DM_add_tangent_layer(DerivedMesh *dm);
+
 #endif
 
index f76cdbc64b7081778938a51de291a3a0fe2e66c9..d951c8401e3b27a60bbaa5f9109ff0d979f4cb8c 100644 (file)
@@ -41,7 +41,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        246
-#define BLENDER_SUBVERSION             0
+#define BLENDER_SUBVERSION             1
 
 #define BLENDER_MINVERSION             245
 #define BLENDER_MINSUBVERSION  15
index 4d3f9143b851699cb13e45f61795e768542895d7..67cf89d5ee26de6b964e499eedfd6975b05a9e83 100644 (file)
@@ -59,6 +59,7 @@
 #include "BLI_edgehash.h"
 #include "BLI_editVert.h"
 #include "BLI_linklist.h"
+#include "BLI_memarena.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_customdata.h"
@@ -2844,6 +2845,127 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo
        return numleft;
 }
 
+void DM_add_tangent_layer(DerivedMesh *dm)
+{
+       /* mesh vars */
+       MTFace *mtface, *tf;
+       MFace *mface, *mf;
+       MVert *mvert, *v1, *v2, *v3, *v4;
+       MemArena *arena= NULL;
+       VertexTangent **vtangents= NULL;
+       float (*orco)[3]= NULL, (*tangent)[3];
+       float *uv1, *uv2, *uv3, *uv4, *vtang;
+       float fno[3], tang[3], uv[4][2];
+       int i, j, len, mf_vi[4], totvert, totface;
+
+       if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
+               return;
+
+       /* check we have all the needed layers */
+       totvert= dm->getNumVerts(dm);
+       totface= dm->getNumFaces(dm);
+
+       mvert= dm->getVertArray(dm);
+       mface= dm->getFaceArray(dm);
+       mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+
+       if(!mtface) {
+               orco= dm->getVertDataArray(dm, CD_ORCO);
+               if(!orco)
+                       return;
+       }
+       
+       /* create tangent layer */
+       DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
+       tangent= DM_get_face_data_layer(dm, CD_TANGENT);
+       
+       /* allocate some space */
+       arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+       BLI_memarena_use_calloc(arena);
+       vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent");
+       
+       /* sum tangents at connected vertices */
+       for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) {
+               v1= &mvert[mf->v1];
+               v2= &mvert[mf->v2];
+               v3= &mvert[mf->v3];
+
+               if (mf->v4) {
+                       v4= &mvert[mf->v4];
+                       CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, fno);
+               }
+               else {
+                       v4= NULL;
+                       CalcNormFloat(v3->co, v2->co, v1->co, fno);
+               }
+               
+               if(mtface) {
+                       uv1= tf->uv[0];
+                       uv2= tf->uv[1];
+                       uv3= tf->uv[2];
+                       uv4= tf->uv[3];
+               }
+               else {
+                       uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+                       spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+                       spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+                       spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+                       if(v4)
+                               spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+               }
+               
+               tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+               
+               if(mf->v4) {
+                       v4= &mvert[mf->v4];
+                       
+                       tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4);
+               }
+       }
+       
+       /* write tangent to layer */
+       for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) {
+               len= (mf->v4)? 4 : 3; 
+               
+               if(mtface) {
+                       uv1= tf->uv[0];
+                       uv2= tf->uv[1];
+                       uv3= tf->uv[2];
+                       uv4= tf->uv[3];
+               }
+               else {
+                       uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+                       spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+                       spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+                       spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+                       if(len==4)
+                               spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+               }
+               
+               mf_vi[0]= mf->v1;
+               mf_vi[1]= mf->v2;
+               mf_vi[2]= mf->v3;
+               mf_vi[3]= mf->v4;
+               
+               for(j=0; j<len; j++) {
+                       vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]);
+
+                       VECCOPY(tangent[j], vtang);
+                       Normalize(tangent[j]);
+               }
+       }
+       
+       BLI_memarena_free(arena);
+       MEM_freeN(vtangents);
+}
+
+
 /* ************************* fluidsim bobj file handling **************************** */
 
 #ifndef DISABLE_ELBEEM
index 501293ecd814970d8ddc9a4e2a64cd4edc08a439..9012adb09b7a4c428cd8c375bfd7533304b615f0 100644 (file)
@@ -532,13 +532,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
        {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
-       {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol} 
+       {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
+       {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
 };
 
 const char *LAYERTYPENAMES[CD_NUMTYPES] = {
        "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
        "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
-       "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
+       "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"};
 
 const CustomDataMask CD_MASK_BAREMESH =
        CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -552,7 +553,7 @@ const CustomDataMask CD_MASK_EDITMESH =
 const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
-       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
+       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT;
 const CustomDataMask CD_MASK_BMESH = 
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 const CustomDataMask CD_MASK_FACECORNERS =
index ad004dd5c8216509e59c967dec8cadf947351978..ad19cde3c9ba963ad5700bd4cdb848b396056286 100644 (file)
@@ -4870,6 +4870,49 @@ void idproperties_fix_group_lengths(ListBase idlist)
        }
 }
 
+void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
+{
+       Material *ma;
+       MFace *mf;
+       MTFace *tf;
+       int a, b, texalpha;
+
+       /* verify we have a tface layer */
+       for(b=0; b<me->fdata.totlayer; b++)
+               if(me->fdata.layers[b].type == CD_MTFACE)
+                       break;
+       
+       if(b == me->fdata.totlayer)
+               return;
+
+       /* if we do, set alpha sort if the game engine did it before */
+       for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+               if(mf->mat_nr < me->totcol) {
+                       ma= newlibadr(fd, lib, me->mat[mf->mat_nr]);
+                       texalpha = 0;
+
+                       for(b=0; ma && b<MAX_MTEX; b++)
+                               if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
+                                       texalpha = 1;
+               }
+               else {
+                       ma= NULL;
+                       texalpha = 0;
+               }
+
+               for(b=0; b<me->fdata.totlayer; b++) {
+                       if(me->fdata.layers[b].type == CD_MTFACE) {
+                               tf = ((MTFace*)me->fdata.layers[b].data) + a;
+
+                               tf->mode &= ~TF_ALPHASORT;
+                               if(ma && (ma->mode & MA_ZTRA))
+                                       if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
+                                               tf->mode |= TF_ALPHASORT;
+                       }
+               }
+       }
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7714,8 +7757,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
 
        /* sun/sky */
-       if ((main->versionfile < 246) ){
+       if(main->versionfile < 246) {
                Lamp *la;
+
                for(la=main->lamp.first; la; la= la->id.next) {
                        la->sun_effect_type = 0;
                        la->horizon_brightness = 1.0;
@@ -7731,6 +7775,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       if(main->versionfile <= 246 && main->subversionfile < 1){
+               Mesh *me;
+
+               for(me=main->mesh.first; me; me= me->id.next)
+                       alphasort_version_246(fd, lib, me);
+       }
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index 72557145270427b75c28c44365355b576224311f..6c098e220bbbd316e6f9579461eacbcadfa789a0 100644 (file)
@@ -71,7 +71,8 @@ typedef struct CustomData {
 #define CD_MTEXPOLY            15
 #define CD_MLOOPUV             16
 #define CD_MLOOPCOL            17
-#define CD_NUMTYPES            18
+#define CD_TANGENT             18
+#define CD_NUMTYPES            19
 
 /* Bits for CustomDataMask */
 #define CD_MASK_MVERT          (1 << CD_MVERT)
@@ -92,6 +93,7 @@ typedef struct CustomData {
 #define CD_MASK_MTEXPOLY       (1 << CD_MTEXPOLY)
 #define CD_MASK_MLOOPUV                (1 << CD_MLOOPUV)
 #define CD_MASK_MLOOPCOL       (1 << CD_MLOOPCOL)
+#define CD_MASK_TANGENT                (1 << CD_TANGENT)
 
 
 /* CustomData.flag */
index 6d025839ac8bc5e324ecac9824de743de0f1574f..4e427ed733ce1dfb5682f3fcf33647f5ae627526 100644 (file)
@@ -228,7 +228,7 @@ typedef struct PartialVisibility {
 
 /* mtface->mode */
 #define TF_DYNAMIC             1
-#define TF_DEPRECATED  2
+#define TF_ALPHASORT   2
 #define TF_TEX                 4
 #define TF_SHAREDVERT  8
 #define TF_LIGHT               16
index 180fdc852aea68c160bcb28ddf676ad3043f0b0b..b26c52a92e2dcbec6f68479ff8fa6455fcba1044 100644 (file)
@@ -6189,6 +6189,7 @@ static void editing_panel_mesh_texface(void)
                uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
                uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
                uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
+               uiDefButBitS(block, TOG, TF_ALPHASORT, REDRAWVIEW3D, "Sort", 840,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)");
 
                uiBlockBeginAlign(block);
                uiBlockSetCol(block, TH_BUT_SETTING1);
index ed6ea7c5f6ae6b2bc52b59cc2e6751ba70183a29..da52be56d1b415525c83ad1cee11377a45abbb45 100644 (file)
@@ -170,6 +170,7 @@ void BL_RenderText(int mode,const char* textstr,int textlen,struct MTFace* tface
 void DisableForText()
 {
        if(glIsEnabled(GL_BLEND)) glDisable(GL_BLEND);
+       if(glIsEnabled(GL_ALPHA_TEST)) glDisable(GL_ALPHA_TEST);
 
        if(glIsEnabled(GL_LIGHTING)) {
                glDisable(GL_LIGHTING);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp
deleted file mode 100644 (file)
index d173b1c..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * $Id$
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 "KX_BlenderPolyMaterial.h"
-#include "BKE_mesh.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#if 0
-KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
-                                                                                          bool ba,
-                                                                                          const STR_String& matname,
-                                                                                          int tile,
-                                                                                          int tilexrep,
-                                                                                          int tileyrep,
-                                                                                          int mode,
-                                                                                          bool transparant,
-                                                                                          bool zsort,
-                                                                                          int lightlayer,
-                                                                                          bool bIsTriangle,
-                                                                                          void* clientobject,
-                                                                                          struct MTFace* tface)
-               : RAS_IPolyMaterial(texname,
-                                                       false,
-                                                       matname,
-                                                       tile,
-                                                       tilexrep,
-                                                       tileyrep,
-                                                       mode,
-                                                       transparant,
-                                                       zsort,
-                                                       lightlayer,
-                                                       bIsTriangle,
-                                                       clientobject),
-               m_tface(tface)
-{
-}
-
-void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const 
-{
-
-       
-       if (GetCachingInfo() != cachingInfo)
-       {
-               if (!cachingInfo)
-               {
-                       set_tpage(NULL);
-               }
-               cachingInfo = GetCachingInfo();
-
-               if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
-               {
-                       update_realtime_texture((struct MTFace*) m_tface, rasty->GetTime());
-                       set_tpage(m_tface);
-                       rasty->EnableTextures(true);
-               }
-               else
-               {
-                       set_tpage(NULL);
-                       rasty->EnableTextures(false);
-               }
-               
-               if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE)
-               {
-                       rasty->SetCullFace(false);
-               }
-               else
-               {
-                       rasty->SetCullFace(true);
-               }
-
-               if (m_drawingmode & RAS_IRasterizer::KX_LINES) {
-                       rasty->SetLines(true);
-               }
-               else {
-                       rasty->SetLines(false);
-               }
-       }
-
-       rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
-       rasty->SetShinyness(m_shininess);
-       rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
-}
-
-
-#endif
-
-
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h
deleted file mode 100644 (file)
index 35823b2..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_BLENDERPOLYMATERIAL
-#define __KX_BLENDERPOLYMATERIAL
-
-#include "RAS_MaterialBucket.h"
-#include "RAS_IRasterizer.h"
-
-struct MTFace;
-extern "C" int set_tpage(MTFace* tface);               /* Worst hack ever */
-
-#if 0
-class KX_BlenderPolyMaterial : public RAS_IPolyMaterial
-{
-       /** Blender texture face structure. */
-       MTFace* m_tface;
-
-public:
-       
-       KX_BlenderPolyMaterial(const STR_String &texname,
-               bool ba,
-               const STR_String& matname,
-               int tile,
-               int tilexrep,
-               int tileyrep,
-               int mode,
-               bool transparant,
-               bool zsort,
-               int lightlayer,
-               bool bIsTriangle,
-               void* clientobject,
-               struct MTFace* tface);  
-       
-       /**
-        * Returns the caching information for this material,
-        * This can be used to speed up the rasterizing process.
-        * @return The caching information.
-        */
-       virtual TCachingInfo GetCachingInfo(void) const;
-
-       /**
-        * Activates the material in the (OpenGL) rasterizer.
-        * On entry, the cachingInfo contains info about the last activated material.
-        * On exit, the cachingInfo should contain updated info about this material.
-        * @param rasty                 The rasterizer in which the material should be active.
-        * @param cachingInfo   The information about the material used to speed up rasterizing.
-        */
-       virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
-
-       /**
-        * Returns the Blender texture face structure that is used for this material.
-        * @return The material's texture face.
-        */
-       MTFace* GetMTFace(void) const;
-protected:
-private:
-};
-
-
-inline MTFace* KX_BlenderPolyMaterial::GetMTFace(void) const
-{
-       return m_tface;
-}
-
-inline RAS_IPolyMaterial::TCachingInfo KX_BlenderPolyMaterial::GetCachingInfo(void) const
-{
-       return GetMTFace();
-}
-
-#endif
-
-#endif // __KX_BLENDERPOLYMATERIAL
-
index 220d174d464c00966be6991a3a28a749cf6a3374..e4eff163d5b61f8dd50c4b8488024ba2fd03691b 100644 (file)
@@ -40,7 +40,6 @@
 // it needs the gameobject and the sumo physics scene for a raycast
 #include "KX_GameObject.h"
 
-#include "KX_BlenderPolyMaterial.h"
 #include "KX_PolygonMaterial.h"
 #include "KX_BlenderMaterial.h"
 
index 320921722e149fed742bb3adb1884b6a5483bce2..2cc5cfda84c37feaab7900a14007fc6e0d0ebce8 100644 (file)
 #include "BKE_mesh.h"
 #include "MT_Point3.h"
 
+#include "BLI_arithb.h"
+
 extern "C" {
-       #include "BKE_customdata.h"
+#include "BKE_customdata.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_DerivedMesh.h"
 }
 
 #include "BKE_material.h" /* give_current_material */
@@ -309,7 +313,6 @@ typedef struct MTF_localLayer
 
 // ------------------------------------
 BL_Material* ConvertMaterial(
-       Mesh* mesh, 
        Material *mat, 
        MTFace* tface,  
        const char *tfaceName,
@@ -323,15 +326,16 @@ BL_Material* ConvertMaterial(
        //this needs some type of manager
        BL_Material *material = new BL_Material();
 
-       int numchan =   -1;
+       int numchan =   -1, texalpha = 0;
        bool validmat   = (mat!=0);
-       bool validface  = (mesh->mtface && tface);
+       bool validface  = (tface!=0);
        
        short type = 0;
        if( validmat )
                type = 1; // material color 
        
        material->IdMode = DEFAULT_BLENDER;
+       material->glslmat = (validmat)? glslmat: false;
 
        // --------------------------------
        if(validmat) {
@@ -367,12 +371,13 @@ BL_Material* ConvertMaterial(
 
                        if(i==0 && facetex ) {
                                Image*tmp = (Image*)(tface->tpage);
+
                                if(tmp) {
                                        material->img[i] = tmp;
                                        material->texname[i] = material->img[i]->id.name;
                                        material->flag[i] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
                                        material->flag[i] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
-                                       material->ras_mode|= ( tface->transp  &(TF_ADD | TF_ALPHA))?TRANSP:0;
+
                                        if(material->img[i]->flag & IMA_REFLECT)
                                                material->mapping[i].mapping |= USEREFL;
                                        else
@@ -430,6 +435,8 @@ BL_Material* ConvertMaterial(
                                                        material->flag[i] |= ( mttmp->mapto  & MAP_ALPHA                )?TEXALPHA:0;
                                                        material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE    )?TEXNEG:0;
 
+                                                       if(!glslmat && (material->flag[i] & TEXALPHA))
+                                                               texalpha = 1;
                                                }
                                        }
                                        else if(mttmp->tex->type == TEX_ENVMAP) {
@@ -546,17 +553,7 @@ BL_Material* ConvertMaterial(
                material->ref                   = mat->ref;
                material->amb                   = mat->amb;
 
-               // set alpha testing without z-sorting
-               if( ( validface && (!(tface->transp &~ TF_CLIP))) && mat->mode & MA_ZTRA) {
-                       // sets the RAS_IPolyMaterial::m_flag |RAS_FORCEALPHA
-                       // this is so we don't have the overhead of the z-sorting code
-                       material->ras_mode|=ALPHA_TEST;
-               }
-               else{
-                       // use regular z-sorting
-                       material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0;
-               }
-               material->ras_mode |= ((mat->mode & MA_WIRE) != 0)?WIRE:0;
+               material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0;
        }
        else {
                int valid = 0;
@@ -574,7 +571,6 @@ BL_Material* ConvertMaterial(
                                material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
                                material->flag[0] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
                                material->flag[0] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
-                               material->ras_mode|= ( tface->transp  & (TF_ADD|TF_ALPHA))?TRANSP:0;
                                valid++;
                        }
                }
@@ -607,10 +603,6 @@ BL_Material* ConvertMaterial(
 
                material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0;
                material->transp = tface->transp;
-               
-               if(tface->transp&~TF_CLIP)
-                       material->ras_mode |= TRANSP;
-
                material->tile  = tface->tile;
                material->mode  = tface->mode;
                        
@@ -631,7 +623,15 @@ BL_Material* ConvertMaterial(
                material->tile          = 0;
        }
 
+       // with ztransp enabled, enforce alpha blending mode
+       if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID))
+               material->transp = TF_ALPHA;
 
+       // always zsort alpha + add
+       if(material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) {
+               material->ras_mode |= ALPHA;
+               material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
+       }
 
        // get uv sets
        if(validmat) 
@@ -711,132 +711,54 @@ BL_Material* ConvertMaterial(
 }
 
 
-static void BL_ComputeTriTangentSpace(const MT_Vector3 &v1, const MT_Vector3 &v2, const MT_Vector3 &v3, 
-       const MT_Vector2 &uv1, const MT_Vector2 &uv2, const MT_Vector2 &uv3, 
-       MFace* mface, MT_Vector3 *tan1, MT_Vector3 *tan2)
-{
-               MT_Vector3 dx1(v2 - v1), dx2(v3 - v1);
-               MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
-               
-               MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
-               duv1 *= r;
-               duv2 *= r;
-               MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
-               MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
-               
-               tan1[mface->v1] += sdir;
-               tan1[mface->v2] += sdir;
-               tan1[mface->v3] += sdir;
-               
-               tan2[mface->v1] += tdir;
-               tan2[mface->v2] += tdir;
-               tan2[mface->v3] += tdir;
-}
-
-static MT_Vector4*  BL_ComputeMeshTangentSpace(Mesh* mesh)
-{
-       MFace* mface = static_cast<MFace*>(mesh->mface);
-       MTFace* tface = static_cast<MTFace*>(mesh->mtface);
-
-       MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert];
-       MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert];
-       
-       int v;
-       for (v = 0; v < mesh->totvert; v++)
-       {
-               tan1[v] = MT_Vector3(0.0, 0.0, 0.0);
-               tan2[v] = MT_Vector3(0.0, 0.0, 0.0);
-       }
-       
-       for (int p = 0; p < mesh->totface; p++, mface++, tface++)
-       {
-               MT_Vector3      v1(mesh->mvert[mface->v1].co),
-                               v2(mesh->mvert[mface->v2].co),
-                               v3(mesh->mvert[mface->v3].co);
-                               
-               MT_Vector2      uv1(tface->uv[0]),
-                               uv2(tface->uv[1]),
-                               uv3(tface->uv[2]);
-                               
-               BL_ComputeTriTangentSpace(v1, v2, v3, uv1, uv2, uv3, mface, tan1, tan2);
-               if (mface->v4)
-               {
-                       MT_Vector3 v4(mesh->mvert[mface->v4].co);
-                       MT_Vector2 uv4(tface->uv[3]);
-                       
-                       BL_ComputeTriTangentSpace(v1, v3, v4, uv1, uv3, uv4, mface, tan1, tan2);
-               }
-       }
-       
-       MT_Vector4 *tangent = new MT_Vector4[mesh->totvert];
-       for (v = 0; v < mesh->totvert; v++)
-       {
-               const MT_Vector3 no(mesh->mvert[v].no[0]/32767.0, 
-                                       mesh->mvert[v].no[1]/32767.0, 
-                                       mesh->mvert[v].no[2]/32767.0);
-               // Gram-Schmidt orthogonalize
-               MT_Vector3 t(tan1[v] - no.cross(no.cross(tan1[v])));
-               if (!MT_fuzzyZero(t))
-                       t /= t.length();
-
-               tangent[v].x() = t.x();
-               tangent[v].y() = t.y();
-               tangent[v].z() = t.z();
-               // Calculate handedness
-               tangent[v].w() = no.dot(tan1[v].cross(tan2[v])) < 0.0 ? -1.0 : 1.0;
-       }
-       
-       delete [] tan1;
-       delete [] tan2;
-       
-       return tangent;
-}
-
 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
 {
        RAS_MeshObject *meshobj;
-       bool    skinMesh = false;
-       
+       bool skinMesh = false;
        int lightlayer = blenderobj->lay;
-       
-       MFace* mface = static_cast<MFace*>(mesh->mface);
-       MTFace* tface = static_cast<MTFace*>(mesh->mtface);
+
+       // Get DerivedMesh data
+       DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
+
+       MVert *mvert = dm->getVertArray(dm);
+       int totvert = dm->getNumVerts(dm);
+
+       MFace *mface = dm->getFaceArray(dm);
+       MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
+       MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
+       float (*tangent)[3] = NULL;
+       int totface = dm->getNumFaces(dm);
        const char *tfaceName = "";
-       MCol* mmcol = mesh->mcol;
-       MT_assert(mface || mesh->totface == 0);
 
+       if(tface) {
+               DM_add_tangent_layer(dm);
+               tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
+       }
 
        // Determine if we need to make a skinned mesh
-       if (mesh->dvert || mesh->key){
+       if (mesh->dvert || mesh->key) {
                meshobj = new BL_SkinMeshObject(mesh, lightlayer);
                skinMesh = true;
        }
-       else {
+       else
                meshobj = new RAS_MeshObject(mesh, lightlayer);
-       }
-       MT_Vector4 *tangent = 0;
-       if (tface)
-               tangent = BL_ComputeMeshTangentSpace(mesh);
-       
 
        // Extract avaiable layers
        MTF_localLayer *layers =  new MTF_localLayer[MAX_MTFACE];
-       for (int lay=0; lay<MAX_MTFACE; lay++)
-       {
+       for (int lay=0; lay<MAX_MTFACE; lay++) {
                layers[lay].face = 0;
                layers[lay].name = "";
        }
 
-
        int validLayers = 0;
-       for (int i=0; i<mesh->fdata.totlayer; i++)
+       for (int i=0; i<dm->faceData.totlayer; i++)
        {
-               if (mesh->fdata.layers[i].type == CD_MTFACE)
+               if (dm->faceData.layers[i].type == CD_MTFACE)
                {
                        assert(validLayers <= 8);
 
-                       layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;;
-                       layers[validLayers].name = mesh->fdata.layers[i].name;
+                       layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
+                       layers[validLayers].name = dm->faceData.layers[i].name;
                        if(tface == layers[validLayers].face)
                                tfaceName = layers[validLayers].name;
                        validLayers++;
@@ -844,271 +766,269 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
        }
 
        meshobj->SetName(mesh->id.name);
-       meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
-       for (int f=0;f<mesh->totface;f++,mface++)
+       meshobj->m_xyz_index_to_vertex_index_mapping.resize(totvert);
+
+       for (int f=0;f<totface;f++,mface++)
        {
-               
+               Material* ma = 0;
                bool collider = true;
-               
-               // only add valid polygons
-               if (mface->v3)
-               {
-                       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);
-                       // rgb3 is set from the adjoint face in a square
-                       unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
-                       MT_Vector3      no0(mesh->mvert[mface->v1].no[0], mesh->mvert[mface->v1].no[1], mesh->mvert[mface->v1].no[2]),
-                                       no1(mesh->mvert[mface->v2].no[0], mesh->mvert[mface->v2].no[1], mesh->mvert[mface->v2].no[2]),
-                                       no2(mesh->mvert[mface->v3].no[0], mesh->mvert[mface->v3].no[1], mesh->mvert[mface->v3].no[2]),
-                                       no3(0.0, 0.0, 0.0);
-                       MT_Point3       pt0(mesh->mvert[mface->v1].co),
-                                       pt1(mesh->mvert[mface->v2].co),
-                                       pt2(mesh->mvert[mface->v3].co),
-                                       pt3(0.0, 0.0, 0.0);
-                       MT_Vector4      tan0(0.0, 0.0, 0.0, 0.0),
-                                       tan1(0.0, 0.0, 0.0, 0.0),
-                                       tan2(0.0, 0.0, 0.0, 0.0),
-                                       tan3(0.0, 0.0, 0.0, 0.0);
-
-                       no0 /= 32767.0;
-                       no1 /= 32767.0;
-                       no2 /= 32767.0;
-                       if (mface->v4)
-                       {
-                               pt3 = MT_Point3(mesh->mvert[mface->v4].co);
-                               no3 = MT_Vector3(mesh->mvert[mface->v4].no[0], mesh->mvert[mface->v4].no[1], mesh->mvert[mface->v4].no[2]);
-                               no3 /= 32767.0;
+               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;
+
+               MT_Vector3 no0, no1, no2, no3;
+               MT_Point3 pt0, pt1, pt2, pt3;
+               MT_Vector4 tan0, tan1, tan2, tan3;
+
+               /* get coordinates, normals and tangents */
+               pt0 = MT_Point3(mvert[mface->v1].co);
+               pt1 = MT_Point3(mvert[mface->v2].co);
+               pt2 = MT_Point3(mvert[mface->v3].co);
+               pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0);
+
+               if(mface->flag & ME_SMOOTH) {
+                       float n0[3], n1[3], n2[3], n3[3];
+
+                       NormalShortToFloat(n0, mvert[mface->v1].no);
+                       NormalShortToFloat(n1, mvert[mface->v2].no);
+                       NormalShortToFloat(n2, mvert[mface->v3].no);
+                       no0 = n0;
+                       no1 = n1;
+                       no2 = n2;
+
+                       if(mface->v4) {
+                               NormalShortToFloat(n3, mvert[mface->v4].no);
+                               no3 = n3;
                        }
+                       else
+                               no3 = MT_Vector3(0.0, 0.0, 0.0);
+               }
+               else {
+                       float fno[3];
+
+                       if(mface->v4)
+                               CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
+                                       mvert[mface->v3].co, mvert[mface->v4].co, fno);
+                       else
+                               CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
+                                       mvert[mface->v3].co, fno);
+
+                       no0 = no1 = no2 = no3 = MT_Vector3(fno);
+               }
+
+               if(tangent) {
+                       tan0 = tangent[f*4 + 0];
+                       tan1 = tangent[f*4 + 1];
+                       tan2 = tangent[f*4 + 2];
+
+                       if (mface->v4)
+                               tan3 = tangent[f*4 + 3];
+               }
+
+               /* get material */
+               ma = give_current_material(blenderobj, mface->mat_nr+1);
        
-                       if(!(mface->flag & ME_SMOOTH))
-                       {
-                               MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
-                               norm[0] = ((int) (10*norm[0]))/10.0;
-                               norm[1] = ((int) (10*norm[1]))/10.0;
-                               norm[2] = ((int) (10*norm[2]))/10.0;
-                               no0=no1=no2=no3= norm;
-       
+               {
+                       bool polyvisible = true;
+                       RAS_IPolyMaterial* polymat = NULL;
+                       BL_Material *bl_mat = NULL;
+
+                       if(converter->GetMaterials()) {
+                               /* do Blender Multitexture and Blender GLSL materials */
+                               unsigned int rgb[4];
+                               MT_Point2 uv[4];
+
+                               /* first is the BL_Material */
+                               bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
+                                       lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
+
+                               bl_mat->material_index =  (int)mface->mat_nr;
+
+                               polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
+                               collider = ((bl_mat->ras_mode & COLLIDER)!=0);
+
+                               /* vertex colors and uv's were stored in bl_mat temporarily */
+                               bl_mat->GetConversionRGB(rgb);
+                               rgb0 = rgb[0]; rgb1 = rgb[1];
+                               rgb2 = rgb[2]; rgb3 = rgb[3];
+
+                               bl_mat->GetConversionUV(uv);
+                               uv0 = uv[0]; uv1 = uv[1];
+                               uv2 = uv[2]; uv3 = uv[3];
+
+                               bl_mat->GetConversionUV2(uv);
+                               uv20 = uv[0]; uv21 = uv[1];
+                               uv22 = uv[2]; uv23 = uv[3];
+                               
+                               /* then the KX_BlenderMaterial */
+                               polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
                        }
+                       else {
+                               /* do Texture Face materials */
+                               Image* bima = (tface)? (Image*)tface->tpage: NULL;
+                               STR_String imastr =  (tface)? (bima? (bima)->id.name : "" ) : "";
                
-                       {
-                               Material* ma = 0;
-                               bool polyvisible = true;
-                               RAS_IPolyMaterial* polymat = NULL;
-                               BL_Material *bl_mat = NULL;
-
-                               if(converter->GetMaterials()) 
-                               {       
-                                       if(mesh->totcol > 1)
-                                               ma = mesh->mat[mface->mat_nr];
-                                       else 
-                                               ma = give_current_material(blenderobj, 1);
-
-                                       bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
-                                       // set the index were dealing with
-                                       bl_mat->material_index =  (int)mface->mat_nr;
-
-                                       polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
-                                       collider = ((bl_mat->ras_mode & COLLIDER)!=0);
+                               char transp=0;
+                               short mode=0, tile=0;
+                               int     tilexrep=4,tileyrep = 4;
+                               
+                               if (bima) {
+                                       tilexrep = bima->xrep;
+                                       tileyrep = bima->yrep;
+                               }
+
+                               /* get tface properties if available */
+                               if(tface) {
+                                       /* TF_DYNAMIC means the polygon is a collision face */
+                                       collider = ((tface->mode & TF_DYNAMIC) != 0);
+                                       transp = tface->transp;
+                                       tile = tface->tile;
+                                       mode = tface->mode;
                                        
-                                       polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
+                                       polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
                                        
-                                       unsigned int rgb[4];
-                                       bl_mat->GetConversionRGB(rgb);
-                                       rgb0 = rgb[0]; rgb1 = rgb[1];
-                                       rgb2 = rgb[2]; rgb3 = rgb[3];
-                                       MT_Point2 uv[4];
-                                       bl_mat->GetConversionUV(uv);
-                                       uv0 = uv[0]; uv1 = uv[1];
-                                       uv2 = uv[2]; uv3 = uv[3];
-
-                                       bl_mat->GetConversionUV2(uv);
-                                       uv20 = uv[0]; uv21 = uv[1];
-                                       uv22 = uv[2]; uv23 = uv[3];
-
-                                       if(tangent){
-                                               tan0 = tangent[mface->v1];
-                                               tan1 = tangent[mface->v2];
-                                               tan2 = tangent[mface->v3];
-                                               if (mface->v4)
-                                                       tan3 = tangent[mface->v4];
-                                       }
+                                       uv0 = MT_Point2(tface->uv[0]);
+                                       uv1 = MT_Point2(tface->uv[1]);
+                                       uv2 = MT_Point2(tface->uv[2]);
+       
+                                       if (mface->v4)
+                                               uv3 = MT_Point2(tface->uv[3]);
+                               } 
+                               else {
+                                       /* no texfaces, set COLLSION true and everything else FALSE */
+                                       mode = default_face_mode;       
+                                       transp = TF_SOLID;
+                                       tile = 0;
                                }
-                               else
-                               {
-                                       ma = give_current_material(blenderobj, 1);
 
-                                       Image* bima = ((mesh->mtface && tface) ? (Image*) tface->tpage : NULL);
-               
-                                       STR_String imastr = 
-                                               ((mesh->mtface && tface) ? 
-                                               (bima? (bima)->id.name : "" ) : "" );
-                       
-                                       char transp=0;
-                                       short mode=0, tile=0;
-                                       int     tilexrep=4,tileyrep = 4;
+                               /* 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 (bima)
-                                       {
-                                               tilexrep = bima->xrep;
-                                               tileyrep = bima->yrep;
-                               
-                                       }
+                                       if (mface->v4)
+                                               rgb3 = KX_Mcol2uint_new(mcol[3]);
+                               }
+                               else {
+                                       /* no vertex colors, take from material, otherwise white */
+                                       unsigned int color = 0xFFFFFFFFL;
 
-                                       if (mesh->mtface && tface)
+                                       if (ma)
                                        {
-                                               // Use texface colors if available
-                                               //TF_DYNAMIC means the polygon is a collision face
-                                               collider = ((tface->mode & TF_DYNAMIC) != 0);
-                                               transp = tface->transp &~ TF_CLIP;
-                                               tile = tface->tile;
-                                               mode = tface->mode;
-                                               
-                                               polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
+                                               union
+                                               {
+                                                       unsigned char cp[4];
+                                                       unsigned int integer;
+                                               } col_converter;
                                                
-                                               uv0 = MT_Point2(tface->uv[0]);
-                                               uv1 = MT_Point2(tface->uv[1]);
-                                               uv2 = MT_Point2(tface->uv[2]);
-               
-                                               if (mface->v4)
-                                                       uv3 = MT_Point2(tface->uv[3]);
-                                       } 
-                                       else
-                                       {
-                                               // no texfaces, set COLLSION true and everything else FALSE
+                                               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);
                                                
-                                               mode = default_face_mode;       
-                                               transp = TF_SOLID;
-                                               tile = 0;
+                                               color = col_converter.integer;
                                        }
 
-                                       if (mmcol)
-                                       {
-                                               // Use vertex colors
-                                               rgb0 = KX_Mcol2uint_new(mmcol[0]);
-                                               rgb1 = KX_Mcol2uint_new(mmcol[1]);
-                                               rgb2 = KX_Mcol2uint_new(mmcol[2]);
-                                               
-                                               if (mface->v4)
-                                                       rgb3 = KX_Mcol2uint_new(mmcol[3]);
-                                       }
-                                       else {
-                                               // no vertex colors: take from material if we have one,
-                                               // otherwise set to white
-                                               unsigned int color = 0xFFFFFFFFL;
+                                       rgb0 = KX_rgbaint2uint_new(color);
+                                       rgb1 = KX_rgbaint2uint_new(color);
+                                       rgb2 = KX_rgbaint2uint_new(color);      
+                                       
+                                       if (mface->v4)
+                                               rgb3 = KX_rgbaint2uint_new(color);
+                               }
+                               
+                               bool istriangle = (mface->v4==0);
 
-                                               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;
-                                               }
+                               // only zsort alpha + add
+                               bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
+                               bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
+
+                               polymat = new KX_PolygonMaterial(imastr, ma,
+                                       tile, tilexrep, tileyrep, 
+                                       mode, transp, alpha, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mcol);
        
-                                               rgb0 = KX_rgbaint2uint_new(color);
-                                               rgb1 = KX_rgbaint2uint_new(color);
-                                               rgb2 = KX_rgbaint2uint_new(color);      
-                                               
-                                               if (mface->v4)
-                                                       rgb3 = KX_rgbaint2uint_new(color);
-                                       }
-                                       
-                                       bool istriangle = (mface->v4==0);
-                                       bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
-                                       
-                                       polymat = new KX_PolygonMaterial(imastr, ma,
-                                               tile, tilexrep, tileyrep, 
-                                               mode, transp, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mmcol);
-               
-                                       if (ma)
-                                       {
-                                               polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
-                                               polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
-                                               polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+                               if (ma) {
+                                       polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+                                       polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
+                                       polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+                               }
+                               else {
+                                       polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
+                                       polymat->m_shininess = 35.0;
+                               }
+                       }
 
-                                       } else
-                                       {
-                                               polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
-                                               polymat->m_shininess = 35.0;
-                                       }
+                       // 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);
                                }
-       
-                               // 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);
-                                       }
-                               } else {
-                                       // delete the material objects since they are no longer needed
-                                       // from now on, use the polygon material from the material bucket
-                                       delete polymat;
-                                       if(converter->GetMaterials()) {
-                                               delete bl_mat;
-                                       }
-                                       polymat = bucket->GetPolyMaterial();
+                       } else {
+                               // delete the material objects since they are no longer needed
+                               // from now on, use the polygon material from the material bucket
+                               delete polymat;
+                               if(converter->GetMaterials()) {
+                                       delete bl_mat;
                                }
-                                                        
-                               int nverts = mface->v4?4:3;
-                               int vtxarray = meshobj->FindVertexArray(nverts,polymat);
-                               RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
+                               polymat = bucket->GetPolyMaterial();
+                       }
+                                                
+                       int nverts = mface->v4?4:3;
+                       int vtxarray = meshobj->FindVertexArray(nverts,polymat);
+                       RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
 
-                               bool flat;
+                       bool flat;
 
-                               if (skinMesh) {
-                                       /* If the face is set to solid, all fnors are the same */
-                                       if (mface->flag & ME_SMOOTH)
-                                               flat = false;
-                                       else
-                                               flat = true;
-                               }
-                               else
+                       if (skinMesh) {
+                               /* If the face is set to solid, all fnors are the same */
+                               if (mface->flag & ME_SMOOTH)
                                        flat = false;
+                               else
+                                       flat = true;
+                       }
+                       else
+                               flat = false;
 
-                               poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
-                               poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
-                               poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
-                               if (nverts==4)
-                                       poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
+                       poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
+                       poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
+                       poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
+                       if (nverts==4)
+                               poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
 
-                               meshobj->AddPolygon(poly);
-                               if (poly->IsCollider())
+                       meshobj->AddPolygon(poly);
+                       if (poly->IsCollider())
+                       {
+                               RAS_TriangleIndex idx;
+                               idx.m_index[0] = mface->v1;
+                               idx.m_index[1] = mface->v2;
+                               idx.m_index[2] = mface->v3;
+                               idx.m_collider = collider;
+                               meshobj->m_triangle_indices.push_back(idx);
+                               if (nverts==4)
                                {
-                                       RAS_TriangleIndex idx;
-                                       idx.m_index[0] = mface->v1;
-                                       idx.m_index[1] = mface->v2;
-                                       idx.m_index[2] = mface->v3;
-                                       idx.m_collider = collider;
-                                       meshobj->m_triangle_indices.push_back(idx);
-                                       if (nverts==4)
-                                       {
-                                       idx.m_index[0] = mface->v1;
-                                       idx.m_index[1] = mface->v3;
-                                       idx.m_index[2] = mface->v4;
-                                       idx.m_collider = collider;
-                                       meshobj->m_triangle_indices.push_back(idx);
-                                       }
+                               idx.m_index[0] = mface->v1;
+                               idx.m_index[1] = mface->v3;
+                               idx.m_index[2] = mface->v4;
+                               idx.m_collider = collider;
+                               meshobj->m_triangle_indices.push_back(idx);
                                }
-                               
-//                             poly->SetVisibleWireframeEdges(mface->edcode);
-                               poly->SetCollider(collider);
                        }
+                       
+//                             poly->SetVisibleWireframeEdges(mface->edcode);
+                       poly->SetCollider(collider);
                }
+
                if (tface) 
                        tface++;
-               if (mmcol)
-                       mmcol+=4;
+               if (mcol)
+                       mcol+=4;
 
                for (int lay=0; lay<MAX_MTFACE; lay++)
                {
@@ -1127,11 +1047,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                (*mit)->GetPolyMaterial()->OnConstruction();
        }
 
-       if(tangent)
-               delete [] tangent;
-
        if (layers)
                delete []layers;
+       
+       dm->release(dm);
 
        return meshobj;
 }
@@ -1819,7 +1738,7 @@ KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
        return 0;
 
 }
-#include "BLI_arithb.h"
+
 // convert blender objects into ketsji gameobjects
 void BL_ConvertBlenderObjects(struct Main* maggie,
                                                          const STR_String& scenename,
index dd45d522b9ffee3e0c65ceca3e4b959ea00e2f37..a9a0771936c7f502671b0f7ef77058887ab8fcc3 100644 (file)
@@ -1,6 +1,10 @@
 
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
 
 #include "BL_BlenderShader.h"
 #include "BL_Material.h"
 #include "GPU_material.h"
 #endif
 
+#include "RAS_BucketManager.h"
 #include "RAS_MeshObject.h"
 #include "RAS_IRasterizer.h"
+ /* this is evil, but we need the scene to create materials with
+  * lights from the correct scene .. */
+static struct Scene *GetSceneForName(const STR_String& scenename)
+{
+       Scene *sce;
+
+       for (sce= (Scene*)G.main->scene.first; sce; sce= (Scene*)sce->id.next)
+               if (scenename == (sce->id.name+2))
+                       return sce;
 
-const bool BL_BlenderShader::Ok()const
+       return (Scene*)G.main->scene.first;
+}
+
+bool BL_BlenderShader::Ok()
 {
 #ifdef BLENDER_GLSL
-       return (mGPUMat != 0);
+       VerifyShader();
+
+       return (mMat && mMat->gpumaterial);
 #else
        return 0;
 #endif
 }
 
-BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
+BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
 :
 #ifdef BLENDER_GLSL
-       mGPUMat(0),
+       mScene(scene),
+       mMat(ma),
+       mGPUMat(NULL),
 #endif
        mBound(false),
        mLightLayer(lightlayer)
 {
 #ifdef BLENDER_GLSL
-       if(ma) {
-               GPU_material_from_blender(ma);
-               mGPUMat = ma->gpumaterial;
+       mBlenderScene = GetSceneForName(scene->GetName());
+       mBlendMode = GPU_BLEND_SOLID;
+
+       if(mMat) {
+               GPU_material_from_blender(mBlenderScene, mMat);
+               mGPUMat = mMat->gpumaterial;
        }
 #endif
 }
@@ -41,17 +66,29 @@ BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
 BL_BlenderShader::~BL_BlenderShader()
 {
 #ifdef BLENDER_GLSL
-       if(mGPUMat) {
-               GPU_material_unbind(mGPUMat);
-               mGPUMat = 0;
-       }
+       if(mMat && mMat->gpumaterial)
+               GPU_material_unbind(mMat->gpumaterial);
+#endif
+}
+
+bool BL_BlenderShader::VerifyShader()
+{
+#ifdef BLENDER_GLSL
+       if(mMat && !mMat->gpumaterial)
+               GPU_material_from_blender(mBlenderScene, mMat);
+
+       mGPUMat = mMat->gpumaterial;
+       
+       return (mMat && mGPUMat);
+#else
+       return false;
 #endif
 }
 
 void BL_BlenderShader::SetProg(bool enable)
 {
 #ifdef BLENDER_GLSL
-       if(mGPUMat) {
+       if(VerifyShader()) {
                if(enable) {
                        GPU_material_bind(mGPUMat, mLightLayer);
                        mBound = true;
@@ -70,7 +107,7 @@ int BL_BlenderShader::GetAttribNum()
        GPUVertexAttribs attribs;
        int i, enabled = 0;
 
-       if(!mGPUMat)
+       if(!VerifyShader())
                return enabled;
 
        GPU_material_vertex_attributes(mGPUMat, &attribs);
@@ -96,7 +133,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
 
        ras->SetAttribNum(0);
 
-       if(!mGPUMat)
+       if(!VerifyShader())
                return;
 
        if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
@@ -142,9 +179,11 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
 void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
 {
 #ifdef BLENDER_GLSL
-       float obmat[4][4], viewmat[4][4], viewinvmat[4][4];
+       float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
+
+       VerifyShader();
 
-       if(!mGPUMat || !mBound)
+       if(!mGPUMat) // || !mBound)
                return;
 
        MT_Matrix4x4 model;
@@ -158,10 +197,22 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
        view.invert();
        view.getValue((float*)viewinvmat);
 
-       GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat);
+       if(ms.m_bObjectColor)
+               ms.m_RGBAcolor.getValue((float*)obcol);
+       else
+               obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
+
+       GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat, obcol);
+
+       mBlendMode = GPU_material_blend_mode(mGPUMat, obcol);
 #endif
 }
 
+int BL_BlenderShader::GetBlendMode()
+{
+       return mBlendMode;
+}
+
 bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
 {
 #ifdef BLENDER_GLSL
index b758d1a9cba313e0c75be0916ad75726e0f601f4..da9765dafa474bb29cb2d094d7a60c1e2a718f08 100644 (file)
 
 #include "RAS_IPolygonMaterial.h"
 
+#include "KX_Scene.h"
+
 struct Material;
+struct Scene;
 class BL_Material;
 
 #define BL_MAX_ATTRIB  16
@@ -27,21 +30,28 @@ class BL_BlenderShader
 {
 private:
 #ifdef BLENDER_GLSL
+       KX_Scene                *mScene;
+       struct Scene    *mBlenderScene;
+       struct Material *mMat;
        GPUMaterial             *mGPUMat;
 #endif
        bool                    mBound;
        int                             mLightLayer;
+       int                             mBlendMode;
+
+       bool                    VerifyShader();
 
 public:
-       BL_BlenderShader(struct Material *ma, int lightlayer);
+       BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer);
        virtual ~BL_BlenderShader();
 
-       const bool                      Ok()const;
+       bool                            Ok();
        void                            SetProg(bool enable);
 
        int GetAttribNum();
        void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
        void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty);
+       int GetBlendMode();
 
        bool Equals(BL_BlenderShader *blshader);
 };
index 568f7e171de0d88d47ea98d99c626ae842504c9a..dcb66ea25790c35a0af4d8c6059529f59740a770 100644 (file)
@@ -129,8 +129,7 @@ enum BL_flag
        TEXALPHA=8,             // use alpha combiner functions
        TEXNEG=16,              // negate blending
        HASIPO=32,
-       USENEGALPHA=64,
-       ALPHA_TEST=128
+       USENEGALPHA=64
 };
 
 // BL_Material::ras_mode
@@ -139,7 +138,7 @@ enum BL_ras_mode
        POLY_VIS=1,
        COLLIDER=2,
        ZSORT=4,
-       TRANSP=8,
+       ALPHA=8,
        TRIANGLE=16,
        USE_LIGHT=32,
        WIRE=64
index f24ef4322f09060d342ea10da66b980be804995d..f0ef84032f7bc07eb165381beec73dfa0aa4b3a6 100644 (file)
@@ -384,8 +384,6 @@ void BL_Texture::DisableUnit()
 
 void BL_Texture::DisableAllTextures()
 {
-       glDisable(GL_BLEND);
-
        for(int i=0; i<MAXTEX; i++) {
                if(GLEW_ARB_multitexture)
                        glActiveTextureARB(GL_TEXTURE0_ARB+i);
index 0f445a9f32e97d044fc93ca519ba26949f45470e..a67e5b26667719db72b2264db5fb7bf6d8c60eee 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 // ------------------------------------
 #define spit(x) std::cout << x << std::endl;
 
+BL_Shader *KX_BlenderMaterial::mLastShader = NULL;
 BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
 
 //static PyObject *gTextureDict = 0;
@@ -58,7 +59,8 @@ KX_BlenderMaterial::KX_BlenderMaterial(
                data->tilexrep[0],
                data->tileyrep[0],
                data->mode,
-               ((data->ras_mode &TRANSP)!=0),
+               data->transp,
+               ((data->ras_mode &ALPHA)!=0),
                ((data->ras_mode &ZSORT)!=0),
                lightlayer,
                ((data->ras_mode &TRIANGLE)!=0),
@@ -79,7 +81,6 @@ KX_BlenderMaterial::KX_BlenderMaterial(
        m_flag |=RAS_BLENDERMAT;
        m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
        m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
-       m_flag |=(mMaterial->ras_mode &ALPHA_TEST)!=0?RAS_FORCEALPHA:0;
 
        // figure max
        int enabled = mMaterial->num_enabled;
@@ -158,12 +159,29 @@ void KX_BlenderMaterial::OnConstruction()
        mConstructed = true;
 }
 
+void KX_BlenderMaterial::EndFrame()
+{
+       if(mLastBlenderShader) {
+               mLastBlenderShader->SetProg(false);
+               mLastBlenderShader = NULL;
+       }
+
+       if(mLastShader) {
+               mLastShader->SetProg(false);
+               mLastShader = NULL;
+       }
+}
+
 void KX_BlenderMaterial::OnExit()
 {
        if( mShader ) {
-                //note, the shader here is allocated, per unique material
-                //and this function is called per face
-               mShader->SetProg(false);
+               //note, the shader here is allocated, per unique material
+               //and this function is called per face
+               if(mShader == mLastShader) {
+                       mShader->SetProg(false);
+                       mLastShader = NULL;
+               }
+
                delete mShader;
                mShader = 0;
        }
@@ -197,13 +215,19 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
        int i;
        if( !enable || !mShader->Ok() ) {
                // frame cleanup.
-               mShader->SetProg(false);
+               if(mShader == mLastShader) {
+                       mShader->SetProg(false);
+                       mLastShader = NULL;
+               }
+
+               ras->SetBlendingMode(TF_SOLID);
                BL_Texture::DisableAllTextures();
                return;
        }
 
        BL_Texture::DisableAllTextures();
        mShader->SetProg(true);
+       mLastShader = mShader;
        
        BL_Texture::ActivateFirst();
 
@@ -217,9 +241,12 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
        }
 
        if(!mUserDefBlend) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
        }
        else {
+               ras->SetBlendingMode(TF_SOLID);
+               ras->SetBlendingMode(-1); // indicates custom mode
+
                // tested to be valid enums
                glEnable(GL_BLEND);
                glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
@@ -234,11 +261,14 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
                        mLastBlenderShader->SetProg(false);
                        mLastBlenderShader= NULL;
                }
+
+               ras->SetBlendingMode(TF_SOLID);
                BL_Texture::DisableAllTextures();
                return;
        }
 
        if(!mBlenderShader->Equals(mLastBlenderShader)) {
+               ras->SetBlendingMode(mMaterial->transp);
                BL_Texture::DisableAllTextures();
 
                if(mLastBlenderShader)
@@ -251,17 +281,17 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
 
 void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
 {
-       if(GLEW_ARB_shader_objects && mShader) 
-               mShader->SetProg(false);
-
        BL_Texture::DisableAllTextures();
-       if( !enable )
+
+       if( !enable ) {
+               ras->SetBlendingMode(TF_SOLID);
                return;
+       }
 
        BL_Texture::ActivateFirst();
 
        if( mMaterial->IdMode == DEFAULT_BLENDER ) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
                return;
        }
 
@@ -271,7 +301,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
                        mTextures[0].ActivateTexture();
                        mTextures[0].setTexEnv(0, true);
                        mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
-                       setDefaultBlending(); 
+                       ras->SetBlendingMode(mMaterial->transp);
                }
                return;
        }
@@ -294,9 +324,12 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
        }
 
        if(!mUserDefBlend) {
-               setDefaultBlending();
+               ras->SetBlendingMode(mMaterial->transp);
        }
        else {
+               ras->SetBlendingMode(TF_SOLID);
+               ras->SetBlendingMode(-1); // indicates custom mode
+
                glEnable(GL_BLEND);
                glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
        }
@@ -356,6 +389,11 @@ KX_BlenderMaterial::ActivateBlenderShaders(
 {
        KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 
+       if(mLastShader) {
+               mLastShader->SetProg(false);
+               mLastShader= NULL;
+       }
+
        // reset... 
        if(tmp->mMaterial->IsShared()) 
                cachingInfo =0;
@@ -402,6 +440,11 @@ KX_BlenderMaterial::ActivateMat(
 {
        KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 
+       if(mLastShader) {
+               mLastShader->SetProg(false);
+               mLastShader= NULL;
+       }
+
        if(mLastBlenderShader) {
                mLastBlenderShader->SetProg(false);
                mLastBlenderShader= NULL;
@@ -451,7 +494,10 @@ KX_BlenderMaterial::Activate(
                        return dopass;
                }
                else {
-                       mShader->SetProg(false);
+                       if(mShader == mLastShader) {
+                               mShader->SetProg(false);
+                               mLastShader = NULL;
+                       }
                        mPass = 0;
                        dopass = false;
                        return dopass;
@@ -499,10 +545,22 @@ bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
 
 void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
 {
-       if(mShader && GLEW_ARB_shader_objects)
+       if(mShader && GLEW_ARB_shader_objects) {
                mShader->Update(ms, rasty);
-       else if(mBlenderShader && GLEW_ARB_shader_objects)
+       }
+       else if(mBlenderShader && GLEW_ARB_shader_objects) {
+               int blendmode;
+
                mBlenderShader->Update(ms, rasty);
+
+               /* we do blend modes here, because they can change per object
+                * with the same material due to obcolor */
+               blendmode = mBlenderShader->GetBlendMode();
+               if((blendmode == TF_SOLID || blendmode == TF_ALPHA) && mMaterial->transp != TF_SOLID)
+                       blendmode = mMaterial->transp;
+
+               rasty->SetBlendingMode(blendmode);
+       }
 }
 
 void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
@@ -582,31 +640,6 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
                ras->EnableTextures(false);
 }
 
-bool KX_BlenderMaterial::setDefaultBlending()
-{
-       if( mMaterial->transp &TF_ADD) {
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_ONE, GL_ONE);
-               glDisable ( GL_ALPHA_TEST );
-               return true;
-       }
-       
-       if( mMaterial->transp & TF_ALPHA ) {
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-               glDisable ( GL_ALPHA_TEST );
-               return true;
-       }
-       
-       if( mMaterial->transp & TF_CLIP ) {
-               glDisable(GL_BLEND); 
-               glEnable ( GL_ALPHA_TEST );
-               glAlphaFunc(GL_GREATER, 0.5f);
-               return false;
-       }
-       return false;
-}
-
 void KX_BlenderMaterial::setTexMatrixData(int i)
 {
        glMatrixMode(GL_TEXTURE);
@@ -831,12 +864,14 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
 void KX_BlenderMaterial::SetBlenderGLSLShader(void)
 {
        if(!mBlenderShader)
-               mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer);
+               mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer);
 
        if(!mBlenderShader->Ok()) {
                delete mBlenderShader;
                mBlenderShader = 0;
        }
+       else
+               m_flag |= RAS_BLENDERGLSL;
 }
 
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
index bf6d2095e7c9b4e35c9dce144860be562d3576ef..0d7657b8cdbaf7d1e388bb68d925bc7e1ff55e9a 100644 (file)
@@ -90,11 +90,13 @@ public:
        // --------------------------------
        // pre calculate to avoid pops/lag at startup
        virtual void OnConstruction( );
+
+       static void     EndFrame();
+
 private:
        BL_Material*            mMaterial;
        BL_Shader*                      mShader;
        BL_BlenderShader*       mBlenderShader;
-       static BL_BlenderShader *mLastBlenderShader;
        KX_Scene*               mScene;
        BL_Texture              mTextures[MAXTEX];              // texture array
        bool                    mUserDefBlend;
@@ -114,7 +116,6 @@ private:
        void    setBlenderShaderData( bool enable, RAS_IRasterizer *ras);
        void    setShaderData( bool enable, RAS_IRasterizer *ras);
 
-       bool    setDefaultBlending();
        void    setObjectMatrixData(int i, RAS_IRasterizer *ras);
        void    setTexMatrixData(int i);
 
@@ -123,6 +124,10 @@ private:
        // cleanup stuff
        void    OnExit();
 
+       // shader chacing
+       static BL_BlenderShader *mLastBlenderShader;
+       static BL_Shader                *mLastShader;
+
        mutable int     mPass;
 };
 
index 3d9c7aafd70f1183479b117b680e13f6a2157d52..df478be5ca21e563b78b151a4c9cd2cd560e8f94 100644 (file)
@@ -77,10 +77,10 @@ KX_GameObject::KX_GameObject(
        SCA_IObject(T),
        m_bDyna(false),
        m_layer(0),
+       m_pBlenderObject(NULL),
        m_bSuspendDynamics(false),
        m_bUseObjectColor(false),
        m_bIsNegativeScaling(false),
-       m_pBlenderObject(NULL),
        m_bVisible(true),
        m_pPhysicsController1(NULL),
        m_pPhysicsEnvironment(NULL),
@@ -96,12 +96,9 @@ KX_GameObject::KX_GameObject(
        KX_NormalParentRelation * parent_relation = 
                KX_NormalParentRelation::New();
        m_pSGNode->SetParentRelation(parent_relation);
-       
-
 };
 
 
-
 KX_GameObject::~KX_GameObject()
 {
        // is this delete somewhere ?
@@ -165,6 +162,7 @@ STR_String KX_GameObject::GetName()
 void KX_GameObject::SetName(STR_String name)
 {
        m_name = name;
+
 };                                                             // Set the name of the value
 
 
@@ -454,12 +452,13 @@ KX_GameObject::UpdateMaterialData(
        )
 {
        int mesh = 0;
+
        if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0) {
                RAS_MaterialBucket::Set::iterator mit = m_meshes[mesh]->GetFirstMaterial();
                for(; mit != m_meshes[mesh]->GetLastMaterial(); ++mit)
                {
                        RAS_IPolyMaterial* poly = (*mit)->GetPolyMaterial();
-                       if(poly->GetFlag() & RAS_BLENDERMAT )
+                       if(poly->GetFlag() & RAS_BLENDERMAT)
                        {
                                KX_BlenderMaterial *m =  static_cast<KX_BlenderMaterial*>(poly);
                                
@@ -467,7 +466,8 @@ KX_GameObject::UpdateMaterialData(
                                {
                                        m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
                                        // if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance)
-                                       SetObjectColor(rgba);
+                                       if(!(poly->GetFlag() & RAS_BLENDERGLSL))
+                                               SetObjectColor(rgba);
                                }
                                else
                                {
index db099d56b558f6c0f469a75f4cdcc2fb46b8429d..1d6cc975ab558076a2fbb359eb0ea509c9b2d313 100644 (file)
@@ -118,7 +118,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
        m_bInitialized(false),
        m_activecam(0),
        m_bFixedTime(false),
-       m_game2ipo(false),
        
        m_firstframe(true),
        
@@ -148,6 +147,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
        m_showBackground(false),
        m_show_debug_properties(false),
 
+       m_game2ipo(false),
+
        // Default behavior is to hide the cursor every frame.
        m_hideCursor(false),
 
index 93d6d5bb70d10abc647bec8037ab86282d16aae0..144f74a1a4c82af20934df563a3177846cd2b8b1 100644 (file)
@@ -59,7 +59,8 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
                                                                                           int tilexrep,
                                                                                           int tileyrep,
                                                                                           int mode,
-                                                                                          bool transparant,
+                                                                                          int transp,
+                                                                                          bool alpha,
                                                                                           bool zsort,
                                                                                           int lightlayer,
                                                                                           bool bIsTriangle,
@@ -74,7 +75,8 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
                                                        tilexrep,
                                                        tileyrep,
                                                        mode,
-                                                       transparant,
+                                                       transp,
+                                                       alpha,
                                                        zsort,
                                                        lightlayer,
                                                        bIsTriangle,
@@ -245,7 +247,7 @@ PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr)
        if (attr == "drawingmode")
                return PyInt_FromLong(m_drawingmode);
        if (attr == "transparent")
-               return PyInt_FromLong(m_transparant);
+               return PyInt_FromLong(m_alpha);
        if (attr == "zsort")
                return PyInt_FromLong(m_zsort);
        if (attr == "lightlayer")
@@ -312,7 +314,7 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue)
                
                if (attr == "transparent")
                {
-                       m_transparant = value;
+                       m_alpha = value;
                        return 0;
                }
                
index 19015494e06ea3fd5f1cdb952b81553457254bbd..11c8baa8b1f1bbab3584e4f128dbf68377feb7ca 100644 (file)
@@ -64,7 +64,8 @@ public:
                int tilexrep,
                int tileyrep,
                int mode,
-               bool transparant,
+               int transp,
+               bool alpha,
                bool zsort,
                int lightlayer,
                bool bIsTriangle,
index 648a6ca31d57ca673719521843fadf4944d23a75..ad476e492d0bf75b191b2722fc1f0b5014a87841 100644 (file)
@@ -37,6 +37,7 @@
 #include "MT_assert.h"
 
 #include "KX_KetsjiEngine.h"
+#include "KX_BlenderMaterial.h"
 #include "RAS_IPolygonMaterial.h"
 #include "ListValue.h"
 #include "SCA_LogicManager.h"
@@ -116,13 +117,13 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
        PyObjectPlus(&KX_Scene::Type),
        m_keyboardmgr(NULL),
        m_mousemgr(NULL),
+       m_sceneConverter(NULL),
        m_physicsEnvironment(0),
        m_sceneName(sceneName),
        m_adi(adi),
        m_networkDeviceInterface(ndi),
        m_active_camera(NULL),
-       m_ueberExecutionPriority(0),
-       m_sceneConverter(NULL)
+       m_ueberExecutionPriority(0)
 {
        m_suspendedtime = 0.0;
        m_suspendeddelta = 0.0;
@@ -984,6 +985,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
                //m_active_camera->Release();
                m_active_camera = NULL;
        }
+
        // in case this is a camera
        m_cameras.remove((KX_Camera*)newobj);
 
@@ -1240,14 +1242,10 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
                        if (visible)
                        {
                                int nummeshes = gameobj->GetMeshCount();
-                               MT_Transform t( cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
-       
                                
+                               // this adds the vertices to the display list
                                for (int m=0;m<nummeshes;m++)
-                               {
-                                       // this adds the vertices to the display list
-                                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
-                               }
+                                       (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
                        }
                        gameobj->MarkVisible(visible);
                }
@@ -1304,12 +1302,11 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
        if (vis)
        {
                int nummeshes = gameobj->GetMeshCount();
-               MT_Transform t(cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
                
                for (int m=0;m<nummeshes;m++)
                {
                        // this adds the vertices to the display list
-                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
+                       (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
                }
                // Visibility/ non-visibility are marked
                // elsewhere now.
@@ -1422,7 +1419,7 @@ void KX_Scene::UpdateParents(double curtime)
 
 RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated)
 {
-       return m_bucketmanager->RAS_BucketManagerFindBucket(polymat, bucketCreated);
+       return m_bucketmanager->FindBucket(polymat, bucketCreated);
 }
 
 
@@ -1432,10 +1429,9 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
                                                         class RAS_IRenderTools* rendertools)
 {
        m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
+       KX_BlenderMaterial::EndFrame();
 }
 
-
-
 void KX_Scene::UpdateObjectActivity(void) 
 {
        if (m_activity_culling) {
index b4492ca03a9703dab0b9d1a8f7e14930af44ac0c..82bdce44519b0f8980fb01891f1ea3c99f669bf6 100644 (file)
@@ -94,7 +94,6 @@ void RAS_BucketManager::RenderAlphaBuckets(
        const MT_Scalar cam_origin = cameratrans.getOrigin()[2];
        for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit)
        {
-               (*bit)->ClearScheduledPolygons();
                for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
                {
                        if ((*mit).m_bVisible)
@@ -133,28 +132,15 @@ void RAS_BucketManager::Renderbuckets(
        rasty->ClearCachingInfo();
 
        RAS_MaterialBucket::StartFrame();
-       for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
-       {
-               (*bucket)->ClearScheduledPolygons();
-       }
        
        for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
-       {
-               RAS_IPolyMaterial *tmp = (*bucket)->GetPolyMaterial();
-               if(tmp->IsZSort() || tmp->GetFlag() &RAS_FORCEALPHA )
-                       rasty->SetAlphaTest(true);
-               else
-                       rasty->SetAlphaTest(false);
-
                (*bucket)->Render(cameratrans,rasty,rendertools);
-       }
-       rasty->SetAlphaTest(false);
 
        RenderAlphaBuckets(cameratrans, rasty, rendertools);    
        RAS_MaterialBucket::EndFrame();
 }
 
-RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
+RAS_MaterialBucket* RAS_BucketManager::FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
 {
        bucketCreated = false;
        BucketList::iterator it;
@@ -172,7 +158,7 @@ RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMate
        
        RAS_MaterialBucket *bucket = new RAS_MaterialBucket(material);
        bucketCreated = true;
-       if (bucket->IsTransparant())
+       if (bucket->IsAlpha())
                m_AlphaBuckets.push_back(bucket);
        else
                m_MaterialBuckets.push_back(bucket);
@@ -195,3 +181,28 @@ void RAS_BucketManager::RAS_BucketManagerClearAll()
        m_MaterialBuckets.clear();
        m_AlphaBuckets.clear();
 }
+
+void RAS_BucketManager::ReleaseDisplayLists()
+{
+       BucketList::iterator bit;
+       RAS_MaterialBucket::T_MeshSlotList::iterator mit;
+
+       for (bit = m_MaterialBuckets.begin(); bit != m_MaterialBuckets.end(); ++bit) {
+               for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+                       if(mit->m_DisplayList) {
+                               mit->m_DisplayList->Release();
+                               mit->m_DisplayList = NULL;
+                       }
+               }
+       }
+       
+       for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+               for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+                       if(mit->m_DisplayList) {
+                               mit->m_DisplayList->Release();
+                               mit->m_DisplayList = NULL;
+                       }
+               }
+       }
+}
+
index 010478b1d5bc16e177d03a2abb9dced82a3fe1a7..08b67ed022f84abc62a7005eb16f444a43e73d13 100644 (file)
@@ -58,8 +58,9 @@ public:
                                                        RAS_IRasterizer* rasty,
                                                        class RAS_IRenderTools* rendertools);
 
-       RAS_MaterialBucket* RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
+       RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
        
+       void ReleaseDisplayLists();
 
 private:
        void RAS_BucketManagerClearAll();
index 31bdd8638c273153f2959f5dd3843ce99f63fc0f..4ee06d966039d3c7463a17ff206fc337dd7e57d1 100644 (file)
@@ -39,7 +39,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
                                                                         int tilexrep,
                                                                         int tileyrep,
                                                                         int mode,
-                                                                        bool transparant,
+                                                                        int transp,
+                                                                        bool alpha,
                                                                         bool zsort,
                                                                         int lightlayer,
                                                                         bool bIsTriangle,
@@ -51,7 +52,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
                m_tilexrep(tilexrep),
                m_tileyrep(tileyrep),
                m_drawingmode (mode),
-               m_transparant(transparant),
+               m_transp(transp),
+               m_alpha(alpha),
                m_zsort(zsort),
                m_lightlayer(lightlayer),
                m_bIsTriangle(bIsTriangle),
@@ -74,6 +76,7 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
                        this->m_multimode                       ==              lhs.m_multimode &&
                        this->m_flag                            ==              lhs.m_flag              &&
                        this->m_drawingmode                     ==              lhs.m_drawingmode &&
+                       this->m_transp                          ==              lhs.m_transp &&
                        this->m_lightlayer                      ==              lhs.m_lightlayer &&
                        this->m_texturename.hash()      ==              lhs.m_texturename.hash() &&
                        this->m_materialname.hash() ==          lhs.m_materialname.hash()
@@ -85,7 +88,8 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
                                this->m_tile            ==              lhs.m_tile &&
                                this->m_tilexrep        ==              lhs.m_tilexrep &&
                                this->m_tileyrep        ==              lhs.m_tileyrep &&
-                               this->m_transparant     ==              lhs.m_transparant &&
+                               this->m_transp          ==              lhs.m_transp &&
+                               this->m_alpha           ==              lhs.m_alpha &&
                                this->m_zsort           ==              lhs.m_zsort &&
                                this->m_drawingmode     ==              lhs.m_drawingmode &&
                                this->m_bIsTriangle     ==              lhs.m_bIsTriangle &&
@@ -109,9 +113,9 @@ int RAS_IPolyMaterial::GetLightLayer() const
        return m_lightlayer;
 }
 
-bool RAS_IPolyMaterial::IsTransparant() const
+bool RAS_IPolyMaterial::IsAlpha() const
 {
-       return m_transparant;
+       return m_alpha || m_zsort;
 }
 
 bool RAS_IPolyMaterial::IsZSort() const
index 6d90d260a231ae3094f0a0cb67b00a148dafd70a..8fc53e6b03880abcf708a6e65aa73dd4a73b7430 100644 (file)
@@ -52,7 +52,7 @@ enum MaterialProps
        RAS_AUTOGEN             =128,
        RAS_NORMAL              =256,
        RAS_DEFMULTI    =512,
-       RAS_FORCEALPHA  =1024
+       RAS_BLENDERGLSL =1024
 };
 
 /**
@@ -67,7 +67,8 @@ protected:
        int                                             m_tile;
        int                                             m_tilexrep,m_tileyrep;
        int                                             m_drawingmode;  // tface->mode
-       bool                                    m_transparant;
+       int                                             m_transp;
+       bool                                    m_alpha;
        bool                                    m_zsort;
        int                                             m_lightlayer;
        bool                                    m_bIsTriangle;
@@ -102,7 +103,8 @@ public:
                                          int tilexrep,
                                          int tileyrep,
                                          int mode,
-                                         bool transparant,
+                                         int transp,
+                                         bool alpha,
                                          bool zsort,
                                          int lightlayer,
                                          bool bIsTriangle,
@@ -132,7 +134,7 @@ public:
        virtual bool                            Equals(const RAS_IPolyMaterial& lhs) const;
        bool                            Less(const RAS_IPolyMaterial& rhs) const;
        int                                     GetLightLayer() const;
-       bool                            IsTransparant() const;
+       bool                            IsAlpha() const;
        bool                            IsZSort() const;
        bool                            UsesTriangles() const;
        unsigned int            hash() const;
index d4a9177a85d993d55de8ce7664a4b4832c02155e..9e03212283e9c0c4211b4deb584e5f6b89ef02ab 100644 (file)
@@ -372,10 +372,6 @@ public:
        
        virtual void    SetAmbientColor(float red, float green, float blue)=0;
        virtual void    SetAmbient(float factor)=0;
-       /**
-        * Sets alpha testing
-        */
-       virtual void    SetAlphaTest(bool enable)=0;
 
        /**
         * Sets a polygon offset.  z depth will be: z1 = mult*z0 + add
@@ -398,8 +394,10 @@ public:
        virtual void    DisableMotionBlur()=0;
        
        virtual float   GetMotionBlurValue()=0;
-       virtual int     GetMotionBlurState()=0;
-       virtual void SetMotionBlurState(int newstate)=0;
+       virtual int             GetMotionBlurState()=0;
+       virtual void    SetMotionBlurState(int newstate)=0;
+
+       virtual void    SetBlendingMode(int blendmode)=0;
 };
 
 #endif //__RAS_IRASTERIZER
index e295d69e48e25b9b983cb710908a6516c13a3e96..0015b6a251f9743ed6413ca2674c700a48b05f91 100644 (file)
@@ -76,26 +76,11 @@ KX_MeshSlot::~KX_MeshSlot()
 RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
        :m_bModified(true)
 {
-       m_bScheduled=true;
        m_material = mat;
 }
 
 
 
-void RAS_MaterialBucket::SchedulePolygons(int drawingmode)
-{ 
-       m_bScheduled = true;
-}
-
-
-
-void RAS_MaterialBucket::ClearScheduledPolygons()
-{ 
-       m_bScheduled = false;
-}
-
-       
-
 RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() const
 { 
        return m_material;
@@ -134,9 +119,14 @@ void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms,
        (*it).m_RGBAcolor= rgbavec;
 }
 
-bool RAS_MaterialBucket::IsTransparant() const
+bool RAS_MaterialBucket::IsAlpha() const
+{      
+       return (m_material->IsAlpha());
+}
+
+bool RAS_MaterialBucket::IsZSort() const
 {      
-       return (m_material->IsTransparant());
+       return (m_material->IsZSort());
 }
 
 
index 13d8a53714a42012034c0692b9e128d3d1c5e538..4eef889c5336fa4987109a28bd729459c5847612 100644 (file)
@@ -125,11 +125,9 @@ public:
                                           class RAS_IRasterizer* rasty,
                                           class RAS_IRenderTools* rendertools);
        
-       void    SchedulePolygons(int drawingmode);
-       void    ClearScheduledPolygons();
-       
        RAS_IPolyMaterial*              GetPolyMaterial() const;
-       bool    IsTransparant() const;
+       bool    IsAlpha() const;
+       bool    IsZSort() const;
                
        static void     StartFrame();
        static void EndFrame();
@@ -162,7 +160,6 @@ public:
 private:
        
        T_MeshSlotList                          m_meshSlots;
-       bool                                            m_bScheduled;
        bool                                            m_bModified;
        RAS_IPolyMaterial*                      m_material;
        double*                                         m_pOGLMatrix;
index 5087f62500eea037c46ba895729db1edea1822d7..9c0460aad2daf5ddd9edd22b07fb222530901fa6 100644 (file)
@@ -203,7 +203,6 @@ void RAS_MeshObject::DebugColor(unsigned int abgr)
 
 void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
 {
-       RAS_TexVert* vertex = NULL;
        const vecVertexArray & vertexvec = GetVertexCache(mat);
                        
        for (vector<KX_VertexArray*>::const_iterator it = vertexvec.begin(); it != vertexvec.end(); ++it)
@@ -220,22 +219,17 @@ void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
                                                                  int numverts,
                                                                  RAS_IPolyMaterial* mat)
 {
-       //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
-       //m_IndexArrayCount[idx.m_vtxarray] = indexpos + 3;
-       
        KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+
        ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[0]);
        ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[1]);
        ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[2]);
-       if (!mat->UsesTriangles()) //if (!m_bUseTriangles)
-       {       
-               //m_IndexArrayCount[idx.m_vtxarray] = indexpos+4;
+
+       if (!mat->UsesTriangles())
                ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
-       }
 }
 
 
-
 void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
                                                                                   int numverts,
                                                                                   int edgecode,
@@ -422,7 +416,6 @@ void RAS_MeshObject::Bucketize(double* oglmatrix,
        for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
        {
                RAS_MaterialBucket* bucket = *it;
-               bucket->SchedulePolygons(0);
 //             KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
                bucket->SetMeshSlot(ms);
        }
@@ -447,7 +440,6 @@ void RAS_MeshObject::MarkVisible(double* oglmatrix,
        for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
        {
                RAS_MaterialBucket* bucket = *it;
-               bucket->SchedulePolygons(0);
 //             KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
                bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
        }
@@ -466,7 +458,6 @@ void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
        {
                RAS_MaterialBucket* bucket = *it;
 //             RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
-               bucket->SchedulePolygons(0);
                //KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
                bucket->RemoveMeshSlot(ms);
        }
@@ -585,31 +576,36 @@ void RAS_MeshObject::UpdateMaterialList()
 
 struct RAS_MeshObject::polygonSlot
 {
-       float        m_z;
-       RAS_Polygon *m_poly;
-               
-       polygonSlot(float z, RAS_Polygon* poly) :
-               m_z(z),
-               m_poly(poly)
-       {}
-       /**
-        * pnorm and pval form the plane equation that the distance from is used to
-        * sort against.
-        */
-        polygonSlot(const MT_Vector3 &pnorm, const MT_Scalar &pval, RAS_MeshObject *mesh, RAS_Polygon* poly) :
-                       m_poly(poly)
+       float m_z;
+       int m_index[4];
+       
+       polygonSlot() {}
+
+       /* pnorm is the normal from the plane equation that the distance from is
+        * used to sort again. */
+       void get(const KX_VertexArray& vertexarray, const KX_IndexArray& indexarray,
+               int offset, int nvert, const MT_Vector3& pnorm)
        {
-               const KX_VertexIndex &base = m_poly->GetIndexBase();
-               RAS_TexVert *vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[0], poly->GetMaterial()->GetPolyMaterial());
-               m_z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
-               
-               for(int i = 1; i < m_poly->VertexCount(); i++)
-               {
-                       vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[i], poly->GetMaterial()->GetPolyMaterial());
-                       float z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
-                       m_z += z;
+               MT_Vector3 center(0, 0, 0);
+               int i;
+
+               for(i=0; i<nvert; i++) {
+                       m_index[i] = indexarray[offset+i];
+                       center += vertexarray[m_index[i]].getLocalXYZ();
                }
-               m_z /= m_poly->VertexCount();
+
+               /* note we don't divide center by the number of vertices, since all
+                * polygons have the same number of vertices, and that we leave out
+                * the 4-th component of the plane equation since it is constant. */
+               m_z = MT_dot(pnorm, center);
+       }
+
+       void set(KX_IndexArray& indexarray, int offset, int nvert)
+       {
+               int i;
+
+               for(i=0; i<nvert; i++)
+                       indexarray[offset+i] = m_index[i];
        }
 };
        
@@ -629,100 +625,100 @@ struct RAS_MeshObject::fronttoback
        }
 };
 
-
 void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
 {
+       // Limitations: sorting is quite simple, and handles many
+       // cases wrong, partially due to polygons being sorted per
+       // bucket.
+       // 
+       // a) mixed triangles/quads are sorted wrong
+       // b) mixed materials are sorted wrong
+       // c) more than 65k faces are sorted wrong
+       // d) intersecting objects are sorted wrong
+       // e) intersecting polygons are sorted wrong
+       //
+       // a) can be solved by making all faces either triangles or quads
+       // if they need to be z-sorted. c) could be solved by allowing
+       // larger buckets, b) and d) cannot be solved easily if we want
+       // to avoid excessive state changes while drawing. e) would
+       // require splitting polygons.
+
        if (!m_zsort)
                return;
-               
+
        // Extract camera Z plane...
        const MT_Vector3 pnorm(transform.getBasis()[2]);
-       const MT_Scalar pval = transform.getOrigin()[2];
-       
-       unsigned int numpolys = m_Polygons.size();
-       std::multiset<polygonSlot, backtofront> alphapolyset;
-       std::multiset<polygonSlot, fronttoback> solidpolyset;
-       
-       for (unsigned int p = 0; p < numpolys; p++)
-       {
-               RAS_Polygon* poly = m_Polygons[p];
-               if (poly->IsVisible())
-               {
-                       if (poly->GetMaterial()->GetPolyMaterial()->IsTransparant())
-                       {
-                               alphapolyset.insert(polygonSlot(pnorm, pval, this, poly));
-                       } else {
-                               solidpolyset.insert(polygonSlot(pnorm, pval, this, poly));
-                       }
-               }
-       }
-       
-       // Clear current array data.
+       // unneeded: const MT_Scalar pval = transform.getOrigin()[2];
+
        for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
        {
-               vector<KX_IndexArray*> *indexcache = &GetArrayOptimizer((*it)->GetPolyMaterial())->m_IndexArrayCache1;
-               for (vector<KX_IndexArray*>::iterator iit = indexcache->begin(); iit != indexcache->end(); ++iit)
-                       (*iit)->clear();
-       }
+               if(!(*it)->IsZSort())
+                       continue;
 
-       std::multiset<polygonSlot, fronttoback>::iterator sit = solidpolyset.begin();
-       for (; sit != solidpolyset.end(); ++sit)
-               SchedulePoly((*sit).m_poly->GetVertexIndexBase(), (*sit).m_poly->VertexCount(), (*sit).m_poly->GetMaterial()->GetPolyMaterial());
-       
-       std::multiset<polygonSlot, backtofront>::iterator ait = alphapolyset.begin();
-       for (; ait != alphapolyset.end(); ++ait)
-               SchedulePoly((*ait).m_poly->GetVertexIndexBase(), (*ait).m_poly->VertexCount(), (*ait).m_poly->GetMaterial()->GetPolyMaterial());
+               RAS_IPolyMaterial *mat = (*it)->GetPolyMaterial();
+               KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+
+               vecIndexArrays& indexarrays = ao->m_IndexArrayCache1;
+               vecVertexArray& vertexarrays = ao->m_VertexArrayCache1;
+               unsigned int i, j, nvert = (mat->UsesTriangles())? 3: 4;
+
+               for(i=0; i<indexarrays.size(); i++) {
+                       KX_IndexArray& indexarray = *indexarrays[i];
+                       KX_VertexArray& vertexarray = *vertexarrays[i];
+
+                       unsigned int totpoly = indexarray.size()/nvert;
+                       vector<polygonSlot> slots(totpoly);
+
+                       /* get indices and z into temporary array */
+                       for(j=0; j<totpoly; j++)
+                               slots[j].get(vertexarray, indexarray, j*nvert, nvert, pnorm);
+
+                       /* sort (stable_sort might be better, if flickering happens?) */
+                       sort(slots.begin(), slots.end(), backtofront());
+
+                       /* get indices from temporary array again */
+                       for(j=0; j<totpoly; j++)
+                               slots[j].set(indexarray, j*nvert, nvert);
+               }
+       }
 }
 
 
-void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode)
+void RAS_MeshObject::SchedulePolygons(int drawingmode)
 {
-//     int nummaterials = m_materials.size();
-       int i;
-
        if (m_bModified)
        {
-               for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
-               {
-                       RAS_MaterialBucket* bucket = *it;
+               int i, numpolys = m_Polygons.size();
 
-                       bucket->SchedulePolygons(drawingmode);
-                       if (bucket->GetPolyMaterial()->IsZSort())
+               for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
+                       if ((*it)->IsZSort())
                                m_zsort = true;
-               }
-
-               int numpolys = m_Polygons.size();
                
-               if ((drawingmode > RAS_IRasterizer::KX_BOUNDINGBOX) && 
-                       (drawingmode < RAS_IRasterizer::KX_SOLID))
+               if (drawingmode == RAS_IRasterizer::KX_WIREFRAME)
                {
                        for (i=0;i<numpolys;i++)
                        {
                                RAS_Polygon* poly = m_Polygons[i];
                                if (poly->IsVisible())
-                                       ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode()
-                                       ,poly->GetMaterial()->GetPolyMaterial());
+                                       ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode(),
+                                               poly->GetMaterial()->GetPolyMaterial());
                                
                        }
                        m_zsort = false;
                }
                else
                {
-                       if (!m_zsort)
+                       for (i=0;i<numpolys;i++)
                        {
-                               for (i=0;i<numpolys;i++)
-                               {
-                                       RAS_Polygon* poly = m_Polygons[i];
-                                       if (poly->IsVisible())
-                                       {
-                                               SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
-                                       }
-                               }
+                               RAS_Polygon* poly = m_Polygons[i];
+                               if (poly->IsVisible())
+                                       SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),
+                                               poly->GetMaterial()->GetPolyMaterial());
                        }
                }
 
                m_bModified = false;
-
                m_MeshMod = true;
        } 
 }
+
index 44ad508d1e8fc900a765cbf3184c78fc23425552..99806666fa646d4d6bf7d1ecd9b73fac5e1708c6 100644 (file)
@@ -137,6 +137,18 @@ class RAS_MeshObject
        struct backtofront;
        struct fronttoback;
 
+       void                            SchedulePoly(
+                                                       const KX_VertexIndex& idx,
+                                                       int numverts,
+                                                       RAS_IPolyMaterial* mat
+                                               );
+
+       void                            ScheduleWireframePoly(
+                                                       const KX_VertexIndex& idx,
+                                                       int numverts,
+                                                       int edgecode,
+                                                       RAS_IPolyMaterial* mat
+                                               );
        
 protected:
        enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192};
@@ -196,10 +208,7 @@ public:
         */
        void                            SortPolygons(const MT_Transform &transform);
 
-       void                            SchedulePolygons(
-                                                       const MT_Transform &transform,
-                                                       int drawingmode
-                                               );
+       void                            SchedulePolygons(int drawingmode);
 
        void                            ClearArrayData();
        
@@ -216,19 +225,7 @@ public:
                                                        int numverts,
                                                        RAS_IPolyMaterial* polymat
                                                );
-       
-       void                            SchedulePoly(
-                                                       const KX_VertexIndex& idx,
-                                                       int numverts,
-                                                       RAS_IPolyMaterial* mat
-                                               );
 
-       void                            ScheduleWireframePoly(
-                                                       const KX_VertexIndex& idx,
-                                                       int numverts,
-                                                       int edgecode,
-                                                       RAS_IPolyMaterial* mat
-                                               );
        
        // find (and share) or add vertices
        // for some speedup, only the last 20 added vertices are searched for equality
index dcc36bf5a390b9683419f3e7019eef00b489c980..1dcc6e7093438f8fc72e47501d9901413e889aa5 100644 (file)
@@ -67,6 +67,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        m_motionblurvalue(-1.0),
        m_texco_num(0),
        m_attrib_num(0),
+       m_last_blendmode(0),
        m_materialCachingInfo(0)
 {
        m_viewmatrix.Identity();
@@ -171,6 +172,8 @@ bool RAS_OpenGLRasterizer::Init()
        m_ambg = 0.0f;
        m_ambb = 0.0f;
 
+       SetBlendingMode(0);
+
        glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -189,18 +192,6 @@ void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
 }
 
 
-void RAS_OpenGLRasterizer::SetAlphaTest(bool enable)
-{
-       if (enable)
-       {
-               glEnable(GL_ALPHA_TEST);
-               glAlphaFunc(GL_GREATER, 0.6f);
-       }
-       else glDisable(GL_ALPHA_TEST);
-}
-
-
-
 void RAS_OpenGLRasterizer::SetAmbient(float factor)
 {
        float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
@@ -353,6 +344,8 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
                glEnable (GL_CULL_FACE);
        }
 
+       SetBlendingMode(0);
+
        glShadeModel(GL_SMOOTH);
 
        m_2DCanvas->BeginFrame();
@@ -1389,3 +1382,34 @@ void RAS_OpenGLRasterizer::DisableMotionBlur()
        m_motionblur = 0;
        m_motionblurvalue = -1.0;
 }
+
+void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
+{
+       if(blendmode == m_last_blendmode)
+               return;
+
+       if(blendmode == 0) {
+               glDisable(GL_BLEND);
+               glDisable(GL_ALPHA_TEST);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       }
+       else if(blendmode == 1) {
+               glBlendFunc(GL_ONE, GL_ONE);
+               glEnable(GL_BLEND);
+               glDisable(GL_ALPHA_TEST);
+       }
+       else if(blendmode == 2) {
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               glEnable(GL_BLEND);
+               glEnable(GL_ALPHA_TEST);
+               glAlphaFunc(GL_GREATER, 0.0f);
+       }
+       else if(blendmode == 4) {
+               glDisable(GL_BLEND); 
+               glEnable(GL_ALPHA_TEST);
+               glAlphaFunc(GL_GREATER, 0.5f);
+       }
+
+       m_last_blendmode = blendmode;
+}
+
index 0d54552db05badb8ba767df8d63447882b9b9b1d..02056cce446acdda64aa611717a8497df477fe31 100644 (file)
@@ -99,6 +99,7 @@ protected:
        TexCoGen                m_attrib[RAS_MAX_ATTRIB];
        int                             m_texco_num;
        int                             m_attrib_num;
+       int                             m_last_blendmode;
 
        /** Stores the caching information for the last material activated. */
        RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
@@ -142,8 +143,6 @@ public:
        virtual void    SetFocalLength(const float focallength);
        virtual float   GetFocalLength();
 
-       virtual void    SetAlphaTest(bool enable);
-
        virtual void    SwapBuffers();
        virtual void    IndexPrimitives(
                                                const vecVertexArray& vertexarrays,
@@ -282,8 +281,8 @@ public:
        virtual void    EnableMotionBlur(float motionblurvalue);
        virtual void    DisableMotionBlur();
        virtual float   GetMotionBlurValue(){return m_motionblurvalue;};
-       virtual int     GetMotionBlurState(){return m_motionblur;};
-       virtual void SetMotionBlurState(int newstate)
+       virtual int             GetMotionBlurState(){return m_motionblur;};
+       virtual void    SetMotionBlurState(int newstate)
        {
                if(newstate<0) 
                        m_motionblur = 0;
@@ -292,6 +291,8 @@ public:
                else 
                        m_motionblur = newstate;
        };
+
+       virtual void    SetBlendingMode(int blendmode);
 };
 
 #endif //__RAS_OPENGLRASTERIZER
index 852c94def3f9c49d6d88c70471d9d74923e8fd02..b74cb9cfcace5ab95064cce7ab8dc039fbc35ce7 100644 (file)
 
 #include "RAS_Polygon.h"
 
-/*
-RAS_TexVert*   RAS_Polygon::GetVertex(int index)
-{ 
-               if (m_bucket)
-                       return m_bucket->GetVertex(m_vertexindexbase.m_vtxarray, m_vertexindexbase.m_indexarray[index]);
-               else
-                       return NULL;
-}
-*/
-
-/*void RAS_Polygon::Bucketize(double* oglmatrix)
-{
-               //Transform(trans);
-               if (m_bucket)
-                       m_bucket->AddPolygon(this,oglmatrix);
-}
-*/
-
 RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket,
                                bool visible,
                                int numverts,