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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c122
-rw-r--r--source/blender/blenkernel/intern/customdata.c7
-rw-r--r--source/blender/blenloader/intern/readfile.c53
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h4
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/src/buttons_editing.c1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp114
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h99
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp1
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp637
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp85
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.h14
-rw-r--r--source/gameengine/Ketsji/BL_Material.h5
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp121
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h9
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h3
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp22
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp43
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.h3
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp14
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp24
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h7
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp186
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h29
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp48
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_Polygon.cpp18
36 files changed, 859 insertions, 873 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index f61b300f708..7dc10c53e22 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index f76cdbc64b7..d951c8401e3 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -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
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 4d3f9143b85..67cf89d5ee2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 501293ecd81..9012adb09b7 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -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 =
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ad004dd5c82..ad19cde3c9b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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! */
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 72557145270..6c098e220bb 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -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 */
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 6d025839ac8..4e427ed733c 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -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
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 180fdc852ae..b26c52a92e2 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -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);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index ed6ea7c5f6a..da52be56d1b 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -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
index d173b1c66d9..00000000000
--- a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp
+++ /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
index 35823b2125b..00000000000
--- a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h
+++ /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
-
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 220d174d464..e4eff163d5b 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -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"
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 320921722e1..2cc5cfda84c 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -136,8 +136,12 @@
#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,
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index dd45d522b9f..a9a0771936c 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -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"
@@ -10,30 +14,51 @@
#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
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h
index b758d1a9cba..da9765dafa4 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.h
+++ b/source/gameengine/Ketsji/BL_BlenderShader.h
@@ -14,7 +14,10 @@
#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);
};
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index 568f7e171de..dcb66ea2579 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -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
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index f24ef4322f0..f0ef84032f7 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 0f445a9f32e..a67e5b26667 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -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()")
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index bf6d2095e7c..0d7657b8cdb 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -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;
};
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 3d9c7aafd70..df478be5ca2 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -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
{
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index db099d56b55..1d6cc975ab5 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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),
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index 93d6d5bb70d..144f74a1a4c 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -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;
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 19015494e06..11c8baa8b1f 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -64,7 +64,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
- bool transparant,
+ int transp,
+ bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 648a6ca31d5..ad476e492d0 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -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) {
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index b4492ca03a9..82bdce44519 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -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;
+ }
+ }
+ }
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h
index 010478b1d5b..08b67ed022f 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.h
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.h
@@ -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();
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 31bdd8638c2..4ee06d96603 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 6d90d260a23..8fc53e6b038 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -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;
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index d4a9177a85d..9e03212283e 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index e295d69e48e..0015b6a251f 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -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());
}
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
index 13d8a53714a..4eef889c533 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
@@ -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;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 5087f62500e..9c0460aad2d 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -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;
}
}
+
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 44ad508d1e8..99806666fa6 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index dcc36bf5a39..1dcc6e70934 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -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;
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 0d54552db05..02056cce446 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp
index 852c94def3f..b74cb9cfcac 100644
--- a/source/gameengine/Rasterizer/RAS_Polygon.cpp
+++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp
@@ -37,24 +37,6 @@
#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,