diff options
Diffstat (limited to 'source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp')
-rw-r--r-- | source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp new file mode 100644 index 00000000000..77488597a70 --- /dev/null +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp @@ -0,0 +1,410 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include "GPC_PolygonMaterial.h" + +#include "MT_Vector3.h" + +#include "RAS_IRasterizer.h" + +/* This list includes only data type definitions */ +#include "DNA_object_types.h" +#include "DNA_material_types.h" +#include "DNA_image_types.h" +#include "DNA_lamp_types.h" +#include "DNA_group_types.h" +#include "DNA_scene_types.h" +#include "DNA_camera_types.h" +#include "DNA_property_types.h" +#include "DNA_text_types.h" +#include "DNA_sensor_types.h" +#include "DNA_controller_types.h" +#include "DNA_actuator_types.h" +#include "DNA_mesh_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_mesh.h" + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf_types.h" +/* end of blender include block */ + +#ifdef WIN32 +#include <windows.h> +#endif // WIN32 +#include "GL/gl.h" +#include "GL/glu.h" + +static Image *fCurpage=0; +static int fCurtile=0, fCurmode=0, fCurTileXRep=0, fCurTileYRep=0; +static short fTexWindx, fTexWindy, fTexWinsx, fTexWinsy; +static int fDoMipMap = 1; +static int fLinearMipMap=1; +static int fAlphamode= -1; + + /* (n&(n-1)) zeros the least significant bit of n */ +static int is_pow2(int num) { + return ((num)&(num-1))==0; +} +static int smaller_pow2(int num) { + while (!is_pow2(num)) + num= num&(num-1); + return num; +} + +static void my_make_repbind(Image *ima) +{ + if(ima==0 || ima->ibuf==0) return; + + if(ima->repbind) { + glDeleteTextures(ima->totbind, (GLuint*)ima->repbind); + delete (ima->repbind); + ima->repbind= 0; + } + ima->totbind= ima->xrep*ima->yrep; + if(ima->totbind>1) { + ima->repbind= (unsigned int *) malloc(sizeof(int)*ima->totbind); + for (int i=0;i<ima->totbind;i++) + ((int*)ima->repbind)[i] = 0; + } +} + + +int my_set_tpage(TFace *tface) +{ + static TFace *lasttface= 0; + Image *ima; + unsigned int *rect, *bind; + int tpx, tpy, tilemode, tileXRep,tileYRep; + + /* afschakelen */ + if(tface==0) { + if(lasttface==0) return 0; + + lasttface= 0; + fCurtile= 0; + fCurpage= 0; + if(fCurmode!=0) { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + } + fCurmode= 0; + fCurTileXRep=0; + fCurTileYRep=0; + fAlphamode= -1; + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + return 0; + } + lasttface= tface; + + if( fAlphamode != tface->transp) { + fAlphamode= tface->transp; + + if(fAlphamode) { + glEnable(GL_BLEND); + + if(fAlphamode==TF_ADD) { + glBlendFunc(GL_ONE, GL_ONE); + /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ + } + else if(fAlphamode==TF_ALPHA) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ + } + /* else { */ + /* glBlendFunc(GL_ONE, GL_ONE); */ + /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */ + /* } */ + } + else glDisable(GL_BLEND); + } + + ima= (struct Image *) tface->tpage; + + /* Enable or disable environment mapping */ + if (ima && (ima->flag & IMA_REFLECT)){ + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + else{ + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } + + tilemode= tface->mode & TF_TILES; + tileXRep = 0; + tileYRep = 0; + if (ima) + { + tileXRep = ima->xrep; + tileYRep = ima->yrep; + } + + + if(ima==fCurpage && fCurtile==tface->tile && tilemode==fCurmode && fCurTileXRep==tileXRep && fCurTileYRep == tileYRep) return ima!=0; + + if(tilemode!=fCurmode || fCurTileXRep!=tileXRep || fCurTileYRep != tileYRep) + { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + if(tilemode && ima!=0) + glScalef(ima->xrep, ima->yrep, 1.0); + + glMatrixMode(GL_MODELVIEW); + } + + if(ima==0 || ima->ok==0) { + glDisable(GL_TEXTURE_2D); + + fCurtile= tface->tile; + fCurpage= 0; + fCurmode= tilemode; + fCurTileXRep = tileXRep; + fCurTileYRep = tileYRep; + + return 0; + } + + if(ima->ibuf==0) { + load_image(ima, IB_rect, "", 0); + + if(ima->ibuf==0) { + ima->ok= 0; + + fCurtile= tface->tile; + fCurpage= 0; + fCurmode= tilemode; + fCurTileXRep = tileXRep; + fCurTileYRep = tileYRep; + + glDisable(GL_TEXTURE_2D); + return 0; + } + + } + + if(ima->tpageflag & IMA_TWINANIM) fCurtile= ima->lastframe; + else fCurtile= tface->tile; + + if(tilemode) { + + if(ima->repbind==0) my_make_repbind(ima); + + if(fCurtile>=ima->totbind) fCurtile= 0; + + /* this happens when you change repeat buttons */ + if(ima->repbind) bind= ima->repbind+fCurtile; + else bind= &ima->bindcode; + + if(*bind==0) { + + fTexWindx= ima->ibuf->x/ima->xrep; + fTexWindy= ima->ibuf->y/ima->yrep; + + if(fCurtile>=ima->xrep*ima->yrep) fCurtile= ima->xrep*ima->yrep-1; + + fTexWinsy= fCurtile / ima->xrep; + fTexWinsx= fCurtile - fTexWinsy*ima->xrep; + + fTexWinsx*= fTexWindx; + fTexWinsy*= fTexWindy; + + tpx= fTexWindx; + tpy= fTexWindy; + + rect= ima->ibuf->rect + fTexWinsy*ima->ibuf->x + fTexWinsx; + } + } + else { + bind= &ima->bindcode; + + if(*bind==0) { + tpx= ima->ibuf->x; + tpy= ima->ibuf->y; + rect= ima->ibuf->rect; + } + } + + if(*bind==0) { + int rectw= tpx, recth= tpy; + unsigned int *tilerect= NULL, *scalerect= NULL; + + /* + * Maarten: + * According to Ton this code is not needed anymore. It was used only + * in really old Blenders. + * Reevan: + * Actually it is needed for backwards compatibility. Simpledemo 6 does not display correctly without it. + */ +#if 1 + if (tilemode) { + int y; + + tilerect= (unsigned int*)MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect"); + for (y=0; y<recth; y++) { + unsigned int *rectrow= &rect[y*ima->ibuf->x]; + unsigned int *tilerectrow= &tilerect[y*rectw]; + + memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow)); + } + + rect= tilerect; + } +#endif + if (!is_pow2(rectw) || !is_pow2(recth)) { + rectw= smaller_pow2(rectw); + recth= smaller_pow2(recth); + + scalerect= (unsigned int *)MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect"); + gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect); + rect= scalerect; + } + + glGenTextures(1, (GLuint*)bind); + + /* + if(G.f & G_DEBUG) { + printf("var1: %s\n", ima->id.name+2); + printf("var1: %d, var2: %d\n", *bind, tpx); + printf("var1: %d, var2: %d\n", fCurtile, tilemode); + } + */ + glBindTexture( GL_TEXTURE_2D, *bind); + + if (!fDoMipMap) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else + { + int minfilter= fLinearMipMap?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST; + + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if (tilerect) + MEM_freeN(tilerect); + if (scalerect) + MEM_freeN(scalerect); + } + else glBindTexture( GL_TEXTURE_2D, *bind); + + + + glEnable(GL_TEXTURE_2D); + + fCurpage= ima; + fCurmode= tilemode; + fCurTileXRep = tileXRep; + fCurTileYRep = tileYRep; + + return 1; +} + + +GPC_PolygonMaterial::GPC_PolygonMaterial(const STR_String& texname, bool ba, const STR_String& matname, + int tile, int tileXrep, int tileYrep, int mode, int transparant, + int lightlayer, bool bIsTriangle, void* clientobject, void* tpage) : + RAS_IPolyMaterial(texname, ba, matname, tile, tileXrep, tileYrep, mode, + transparant, lightlayer, bIsTriangle, clientobject), m_tface((struct TFace*)tpage) +{ + // clear local caching info + my_set_tpage(0); +} + + +GPC_PolygonMaterial::~GPC_PolygonMaterial(void) +{ +} + + +void GPC_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const +{ + if (GetCachingInfo() != cachingInfo) + { + if (!cachingInfo) + { + my_set_tpage(0); + } + cachingInfo = GetCachingInfo(); + + if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) ) + { + update_realtime_texture((struct TFace*) m_tface, rasty->GetTime()); + my_set_tpage(m_tface); + rasty->EnableTextures(true); + } else + { + my_set_tpage(0); + rasty->EnableTextures(false); + } + + //TF_TWOSIDE == 512, todo, make this a ketsji enum + if(m_drawingmode & 512) { + rasty->SetCullFace(false); + } + + else + { + rasty->SetCullFace(true);;//glEnable(GL_CULL_FACE); + //else glDisable(GL_CULL_FACE); + } + } + 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); +} + + +void GPC_PolygonMaterial::SetMipMappingEnabled(bool enabled) +{ + fDoMipMap = enabled ? 1 : 0; +} |