Game Engine: alpha blending and sorting

=======================================

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.
This commit is contained in:
Brecht Van Lommel 2008-07-29 15:48:31 +00:00
parent b0c513e83a
commit 908337bee1
36 changed files with 868 additions and 882 deletions

View 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

View 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

View 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

View 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 =

View 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! */

View 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 */

View 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

View 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);

View 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);

View File

@ -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

View File

@ -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

View 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"

View File

@ -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);
const char *tfaceName = "";
MCol* mmcol = mesh->mcol;
MT_assert(mface || mesh->totface == 0);
// 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 = "";
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);
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];
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;
}
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;
}
{
Material* ma = 0;
bool polyvisible = true;
RAS_IPolyMaterial* polymat = NULL;
BL_Material *bl_mat = NULL;
{
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);
if(converter->GetMaterials()) {
/* do Blender Multitexture and Blender GLSL materials */
unsigned int rgb[4];
MT_Point2 uv[4];
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;
/* first is the BL_Material */
bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
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->material_index = (int)mface->mat_nr;
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
if(tangent){
tan0 = tangent[mface->v1];
tan1 = tangent[mface->v2];
tan2 = tangent[mface->v3];
if (mface->v4)
tan3 = tangent[mface->v4];
}
}
else
{
ma = give_current_material(blenderobj, 1);
/* 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];
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;
if (bima)
{
tilexrep = bima->xrep;
tileyrep = bima->yrep;
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 (mesh->mtface && tface)
{
// 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));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
/* 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 : "" ) : "";
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;
}
char transp=0;
short mode=0, tile=0;
int tilexrep=4,tileyrep = 4;
if (bima) {
tilexrep = bima->xrep;
tileyrep = bima->yrep;
}
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;
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;
}
/* 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;
polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
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;
}
/* 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]);
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 (mface->v4)
rgb3 = KX_Mcol2uint_new(mcol[3]);
}
else {
/* no vertex colors, take from material, otherwise white */
unsigned int color = 0xFFFFFFFFL;
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;
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;
}
}
// 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();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
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
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));
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)
{
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);
}
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
// poly->SetVisibleWireframeEdges(mface->edcode);
poly->SetCollider(collider);
bool istriangle = (mface->v4==0);
// 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);
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;
}
}
// 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();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
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
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));
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)
{
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);
}
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,

View 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"
@ -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;
const bool BL_BlenderShader::Ok()const
for (sce= (Scene*)G.main->scene.first; sce; sce= (Scene*)sce->id.next)
if (scenename == (sce->id.name+2))
return sce;
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];
if(!mGPUMat || !mBound)
VerifyShader();
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

View File

@ -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);
};

View 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

View 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);

View 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()")

View 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;
};

View 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
{

View 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),

View 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;
}

View File

@ -64,7 +64,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
bool transparant,
int transp,
bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,

View 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) {

View 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;
}
}
}
}

View 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();

View 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

View 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;

View 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

View 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->IsTransparant());
return (m_material->IsAlpha());
}
bool RAS_MaterialBucket::IsZSort() const
{
return (m_material->IsZSort());
}

View 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;

View 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,20 +219,15 @@ 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;
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
}
}
if (!mat->UsesTriangles())
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
}
void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
@ -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)
{
int i, numpolys = m_Polygons.size();
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
bucket->SchedulePolygons(drawingmode);
if (bucket->GetPolyMaterial()->IsZSort())
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;
}
}

View 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

View 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;
}

View 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

View File

@ -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,