diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp index cf9a088072c..df96ae55691 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp @@ -35,7 +35,7 @@ #ifdef HAVE_CONFIG_H #include #endif - +#if 0 KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname, bool ba, const STR_String& matname, @@ -65,7 +65,6 @@ KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname, { } - void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const { @@ -113,5 +112,6 @@ void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cach } +#endif diff --git a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h index 582e9b39358..fd6d39cc8e3 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h @@ -38,7 +38,7 @@ struct TFace; extern "C" int set_tpage(TFace* tface); /* Worst hack ever */ - +#if 0 class KX_BlenderPolyMaterial : public RAS_IPolyMaterial { /** Blender texture face structure. */ @@ -96,5 +96,7 @@ inline RAS_IPolyMaterial::TCachingInfo KX_BlenderPolyMaterial::GetCachingInfo(vo return GetTFace(); } +#endif + #endif // __KX_BLENDERPOLYMATERIAL diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 6ff91f480a7..b84239d1a65 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -57,6 +57,7 @@ #include "KX_GameObject.h" #include "KX_BlenderPolyMaterial.h" +#include "KX_PolygonMaterial.h" #include "Value.h" #include "KX_BlenderGL.h" // for text printing @@ -258,7 +259,7 @@ void KX_BlenderRenderTools::RenderText(int mode,RAS_IPolyMaterial* polymat,float STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text"); - KX_BlenderPolyMaterial* blenderpoly = (KX_BlenderPolyMaterial*)polymat; + KX_PolygonMaterial* blenderpoly = static_cast(polymat); struct TFace* tface = blenderpoly->GetTFace(); BL_RenderText( mode,mytext,mytext.Length(),tface,v1,v2,v3,v4); @@ -435,11 +436,12 @@ RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial( bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,bool transparant,bool zsort, int lightlayer ,bool bIsTriangle,void* clientobject,void* tface) { - return new KX_BlenderPolyMaterial( + assert(!"Deprecated"); +/* return new KX_BlenderPolyMaterial( texname, ba,matname,tile,tilexrep,tileyrep,mode,transparant,zsort, lightlayer - ,bIsTriangle,clientobject,(struct TFace*)tface); + ,bIsTriangle,clientobject,(struct TFace*)tface);*/ } unsigned int KX_BlenderRenderTools::m_numgllights; diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index 69813b51cf4..785c01f9113 100755 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -7,7 +7,6 @@ kx_blenderhook_env = library_env.Copy () source_files = ['KX_BlenderSystem.cpp', 'KX_BlenderRenderTools.cpp', - 'KX_BlenderPolyMaterial.cpp', 'KX_BlenderMouseDevice.cpp', 'KX_BlenderKeyboardDevice.cpp', 'KX_BlenderInputDevice.cpp', diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 612e78cf871..ba5bf173e12 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -46,6 +46,7 @@ #include "KX_BlenderScalarInterpolator.h" #include "RAS_IPolygonMaterial.h" +#include "KX_PolygonMaterial.h" // Expressions #include "ListValue.h" @@ -235,7 +236,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MFace* mface = static_cast(mesh->mface); TFace* tface = static_cast(mesh->tface); - assert(mface); + MT_assert(mface && "Mesh has no faces!"); MCol* mmcol = mesh->mcol; meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert); @@ -383,7 +384,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool istriangle = (mface->v4==0); bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false; - RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr, false, matnameptr, + RAS_IPolyMaterial* polymat = new KX_PolygonMaterial(imastr, ma, tile, tilexrep, tileyrep, mode, transp, zsort, lightlayer, istriangle, blenderobj, tface); @@ -484,13 +485,13 @@ static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blender { PHY_MaterialProps *materialProps = new PHY_MaterialProps; - assert(materialProps); + MT_assert(materialProps && "Create physics material properties failed"); Material* blendermat = give_current_material(blenderobject, 0); if (blendermat) { - assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f); + MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f); materialProps->m_restitution = blendermat->reflect; materialProps->m_friction = blendermat->friction; @@ -511,7 +512,7 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero { PHY_ShapeProps *shapeProps = new PHY_ShapeProps; - assert(shapeProps); + MT_assert(shapeProps); shapeProps->m_mass = blenderobject->mass; @@ -521,8 +522,8 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero // the sphere radius shapeProps->m_inertia = blenderobject->formfactor; - assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f); - assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f); + MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f); + MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f); shapeProps->m_lin_drag = 1.0 - blenderobject->damping; shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping; diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp index c4715c5f060..dc714fb5fb6 100644 --- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp @@ -114,8 +114,9 @@ static void my_make_repbind(Image *ima) } } +extern "C" int set_tpage(TFace *tface); -static int my_set_tpage(TFace *tface) +int set_tpage(TFace *tface) { static TFace *lasttface= 0; Image *ima; @@ -361,7 +362,7 @@ static int my_set_tpage(TFace *tface) return 1; } - +#if 0 GPC_PolygonMaterial::GPC_PolygonMaterial(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, void* tpage) : @@ -415,7 +416,7 @@ void GPC_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& caching rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); } - +#endif void GPC_PolygonMaterial::SetMipMappingEnabled(bool enabled) { fDoMipMap = enabled ? 1 : 0; diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h index 0a9c32eae46..a091ec6eea4 100644 --- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.h @@ -35,6 +35,12 @@ #include "RAS_IPolygonMaterial.h" +namespace GPC_PolygonMaterial +{ + void SetMipMappingEnabled(bool enabled = false); +}; + +#if 0 class GPC_PolygonMaterial : public RAS_IPolyMaterial { struct TFace* m_tface; @@ -81,6 +87,6 @@ inline GPC_PolygonMaterial::TCachingInfo GPC_PolygonMaterial::GetCachingInfo(voi { return GetTFace(); } - +#endif #endif // __GPC_POLYGONMATERIAL_H diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 514a73c4d77..03aabf10cf1 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -34,6 +34,8 @@ #include #endif +#include + #ifdef WIN32 #pragma warning (disable : 4786) #include @@ -59,6 +61,7 @@ #include "KX_GameObject.h" #include "GPC_PolygonMaterial.h" +#include "KX_PolygonMaterial.h" #include "Value.h" //#include "KX_BlenderGL.h" // for text printing @@ -220,8 +223,15 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, glPopMatrix(); // Restore OpenGL Settings - fog ? ::glEnable(GL_FOG) : ::glDisable(GL_FOG); - texture2D ? ::glEnable(GL_TEXTURE_2D) : ::glDisable(GL_TEXTURE_2D); + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + if (texture2D) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); } /** @@ -236,7 +246,7 @@ void GPC_RenderTools::RenderText( { STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text"); - GPC_PolygonMaterial* blenderpoly = (GPC_PolygonMaterial*)polymat; + KX_PolygonMaterial* blenderpoly = static_cast(polymat); struct TFace* tface = blenderpoly->GetTFace(); BL_RenderText(mode, mytext, mytext.Length(), tface, v1, v2, v3, v4); @@ -324,8 +334,10 @@ RAS_IPolyMaterial* GPC_RenderTools::CreateBlenderPolyMaterial( bool ba,const STR_String& matname,int tile,int tilexrep,int tileyrep,int mode,bool transparant, bool zsort, int lightlayer,bool bIsTriangle,void* clientobject,void* tface) { - return new GPC_PolygonMaterial(texname, ba,matname,tile,tilexrep,tileyrep, + assert(!"Deprecated"); +/* return new GPC_PolygonMaterial(texname, ba,matname,tile,tilexrep,tileyrep, mode,transparant,zsort,lightlayer,bIsTriangle,clientobject,tface); + */ } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index ec0ddddafed..66306a44aba 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -39,6 +39,10 @@ #include "KX_VertexProxy.h" +#include "KX_PolygonMaterial.h" + +#include "KX_PyMath.h" + PyTypeObject KX_MeshProxy::Type = { PyObject_HEAD_INIT(&PyType_Type) 0, @@ -79,7 +83,16 @@ PyMethodDef KX_MeshProxy::Methods[] = { PyObject* KX_MeshProxy::_getattr(const STR_String& attr) { - _getattr_up(SCA_IObject); + if (attr == "materials") + { + PyObject *materials = PyList_New(0); /* new ref */ + RAS_MaterialBucket::Set::iterator mit = m_meshobj->GetFirstMaterial(); + for(; mit != m_meshobj->GetLastMaterial(); ++mit) + PyList_Append(materials, static_cast((*mit)->GetPolyMaterial())); + return materials; + } + + _getattr_up(SCA_IObject); } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp new file mode 100644 index 00000000000..81ff5ca6a3a --- /dev/null +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -0,0 +1,332 @@ +/** + * $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 ***** + */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "KX_PolygonMaterial.h" + +#include "BKE_mesh.h" +#include "BKE_global.h" +#include "BKE_image.h" + +extern "C" { +#include "BDR_drawmesh.h" +} + +#include "DNA_material_types.h" +#include "DNA_texture_types.h" +#include "DNA_image_types.h" +#include "DNA_mesh_types.h" + +#include "IMB_imbuf_types.h" + +#include "MEM_guardedalloc.h" + +#include "RAS_LightObject.h" +#include "RAS_MaterialBucket.h" + +#include "KX_PyMath.h" + +KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname, + Material *material, + int tile, + int tilexrep, + int tileyrep, + int mode, + bool transparant, + bool zsort, + int lightlayer, + bool bIsTriangle, + void* clientobject, + struct TFace* tface, + PyTypeObject *T) + : PyObjectPlus(T), + RAS_IPolyMaterial(texname, + material?STR_String(material->id.name):"", + tile, + tilexrep, + tileyrep, + mode, + transparant, + zsort, + lightlayer, + bIsTriangle, + clientobject), + m_tface(tface), + m_material(material), + m_pymaterial(0), + m_pass(0) +{ +} + +KX_PolygonMaterial::~KX_PolygonMaterial() +{ + if (m_pymaterial) + { + Py_DECREF(m_pymaterial); + } +} + +bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const +{ + bool dopass = false; + if (m_pymaterial) + { + PyObject *pyRasty = PyCObject_FromVoidPtr((void*)rasty, NULL); /* new reference */ + PyObject *pyCachingInfo = PyCObject_FromVoidPtr((void*) &cachingInfo, NULL); /* new reference */ + + PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this); + if (ret) + { + bool value = PyInt_AsLong(ret); + Py_DECREF(ret); + dopass = value; + } + else + { + PyErr_Print(); + } + } + else + { + switch (m_pass++) + { + case 0: + DefaultActivate(rasty, cachingInfo); + dopass = true; + break; + default: + m_pass = 0; + dopass = false; + break; + } + } + + return dopass; +} + +void KX_PolygonMaterial::DefaultActivate(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 TFace*) 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); + if (m_material) + rasty->SetPolygonOffset(-m_material->zoffs, 0.0); +} + +//---------------------------------------------------------------------------- +//Python + + +PyMethodDef KX_PolygonMaterial::Methods[] = { + KX_PYMETHODTABLE(KX_PolygonMaterial, setCustomMaterial), + KX_PYMETHODTABLE(KX_PolygonMaterial, updateTexture), + KX_PYMETHODTABLE(KX_PolygonMaterial, setTexture), + KX_PYMETHODTABLE(KX_PolygonMaterial, activate), +// KX_PYMETHODTABLE(KX_PolygonMaterial, setPerPixelLights), + + {NULL,NULL} //Sentinel +}; + + +PyTypeObject KX_PolygonMaterial::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_PolygonMaterial", + sizeof(KX_PolygonMaterial), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0 //&cvalue_as_number, +}; + +PyParentObject KX_PolygonMaterial::Parents[] = { + &PyObjectPlus::Type, + &KX_PolygonMaterial::Type, + NULL +}; + +PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr) +{ + if (attr == "texture") + return PyString_FromString(m_texturename.ReadPtr()); + if (attr == "material") + return PyString_FromString(m_materialname.ReadPtr()); + + if (attr == "tface") + return PyCObject_FromVoidPtr(m_tface, NULL); + + if (attr == "gl_texture") + { + Image *ima = (Image*) m_tface->tpage; + int bind = 0; + if (ima) + bind = ima->bindcode; + + return PyInt_FromLong(bind); + } + + if (attr == "tile") + return PyInt_FromLong(m_tile); + if (attr == "tilexrep") + return PyInt_FromLong(m_tilexrep); + if (attr == "tileyrep") + return PyInt_FromLong(m_tileyrep); + + if (attr == "drawingmode") + return PyInt_FromLong(m_drawingmode); + if (attr == "transparent") + return PyInt_FromLong(m_transparant); + if (attr == "zsort") + return PyInt_FromLong(m_zsort); + if (attr == "lightlayer") + return PyInt_FromLong(m_lightlayer); + if (attr == "triangle") + return PyInt_FromLong(m_bIsTriangle); + + if (attr == "diffuse") + return PyObjectFrom(m_diffuse); + if (attr == "shininess") + return PyFloat_FromDouble(m_shininess); + if (attr == "specular") + return PyObjectFrom(m_specular); + if (attr == "specularity") + return PyFloat_FromDouble(m_specularity); + + _getattr_up(PyObjectPlus); +} + +int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue) +{ + return PyObjectPlus::_setattr(attr, pyvalue); +} + +KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(material)") +{ + PyObject *material; + if (PyArg_ParseTuple(args, "O", &material)) + { + if (m_pymaterial) + Py_DECREF(m_pymaterial); + + m_pymaterial = material; + Py_INCREF(m_pymaterial); + Py_Return; + } + + return NULL; +} + +KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rasty)") +{ + PyObject *pyrasty, *pytface; + if (PyArg_ParseTuple(args, "O!O!", &PyCObject_Type, &pytface, &PyCObject_Type, &pyrasty)) + { + TFace *tface = (TFace*) PyCObject_AsVoidPtr(pytface); + RAS_IRasterizer *rasty = (RAS_IRasterizer*) PyCObject_AsVoidPtr(pyrasty); + update_realtime_texture(tface, rasty->GetTime()); + Py_Return; + } + + return NULL; +} + +KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)") +{ + PyObject *pytface; + if (PyArg_ParseTuple(args, "O!", &PyCObject_Type, &pytface)) + { + TFace *tface = (TFace*) PyCObject_AsVoidPtr(pytface); + set_tpage(tface); + Py_Return; + } + + return NULL; +} + +KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") +{ + PyObject *pyrasty, *pyCachingInfo; + if (PyArg_ParseTuple(args, "O!O!", &PyCObject_Type, &pyrasty, &PyCObject_Type, &pyCachingInfo)) + { + RAS_IRasterizer *rasty = static_cast(PyCObject_AsVoidPtr(pyrasty)); + TCachingInfo *cachingInfo = static_cast(PyCObject_AsVoidPtr(pyCachingInfo)); + if (rasty && cachingInfo) + { + DefaultActivate(rasty, *cachingInfo); + Py_Return; + } + } + + return NULL; +} diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h new file mode 100644 index 00000000000..14071ae6fc5 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -0,0 +1,120 @@ +/** + * $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 ***** + */ +#ifndef __KX_POLYGONMATERIAL_H__ +#define __KX_POLYGONMATERIAL_H__ + +#include "PyObjectPlus.h" + +#include "RAS_MaterialBucket.h" +#include "RAS_IRasterizer.h" + +struct TFace; +struct Material; +struct MTex; + +/** + * Material class. + * + * This holds the shader, textures and python methods for setting the render state before + * rendering. + */ +class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial +{ + Py_Header; +private: + /** Blender texture face structure. */ + TFace* m_tface; + Material* m_material; + + PyObject* m_pymaterial; + + mutable int m_pass; +public: + + KX_PolygonMaterial(const STR_String &texname, + Material* ma, + int tile, + int tilexrep, + int tileyrep, + int mode, + bool transparant, + bool zsort, + int lightlayer, + bool bIsTriangle, + void* clientobject, + struct TFace* tface, + PyTypeObject *T = &Type); + virtual ~KX_PolygonMaterial(); + + /** + * 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 + { + return (void*) this; + } + + /** + * 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. + */ + void DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const; + virtual bool 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. + */ + TFace* GetTFace(void) const + { + return m_tface; + } + + + KX_PYMETHOD_DOC(KX_PolygonMaterial, updateTexture); + KX_PYMETHOD_DOC(KX_PolygonMaterial, setTexture); + KX_PYMETHOD_DOC(KX_PolygonMaterial, activate); + + KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial); + KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram); + + virtual PyObject* _getattr(const STR_String& attr); + virtual int _setattr(const STR_String& attr, PyObject *pyvalue); +}; + +#endif // __KX_POLYGONMATERIAL_H__ + diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 3afea847405..7683ce19f19 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -338,6 +338,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject*, m_vertex->SetRGBA(MT_Vector4(r, g, b, a)); Py_Return; } + PyErr_Clear(); int rgba; if (PyArg_ParseTuple(args,"i",&rgba)) @@ -345,7 +346,8 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject*, m_vertex->SetRGBA(rgba); Py_Return; } - Py_Return; + + return NULL; } diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 29fee7d6ae7..bf3e1982c8c 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -57,7 +57,7 @@ public: // stuff for python integration virtual PyObject* _getattr(const STR_String& attr); - virtual int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue); + virtual int _setattr(const STR_String& attr, PyObject *pyvalue); KX_PYMETHOD(KX_VertexProxy,GetXYZ); KX_PYMETHOD(KX_VertexProxy,SetXYZ); diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 05b81baec05..948e0135eef 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -31,6 +31,7 @@ source_files = ['KX_WorldIpoController.cpp', 'KX_PythonInit.cpp', 'KX_PyConstraintBinding.cpp', 'KX_PositionInterpolator.cpp', + 'KX_PolygonMaterial.cpp', 'KX_PhysicsObjectWrapper.cpp', 'KX_OrientationInterpolator.cpp', 'KX_ObjectActuator.cpp', diff --git a/source/gameengine/PyDoc/KX_PolygonMaterial.py b/source/gameengine/PyDoc/KX_PolygonMaterial.py new file mode 100644 index 00000000000..5968d3d356c --- /dev/null +++ b/source/gameengine/PyDoc/KX_PolygonMaterial.py @@ -0,0 +1,136 @@ +# $Id$ + +class KX_PolygonMaterial: + """ + This is the interface to materials in Blender. + + Materials define the render state to be applied to mesh objects. + + @bug: All attributes are read only. + + @ivar texture: Texture name + @type texture: string + + @ivar gl_texture: OpenGL texture handle (eg for glBindTexture(GL_TEXTURE_2D, gl_texture) + @type gl_texture: integer + + @ivar material: Material name + @type material: string + + @ivar tface: Texture face properties + @type tface: CObject + + @ivar tile: Texture is tiling + @type tile: boolean + @ivar tilexrep: Number of tile repetitions in x direction. + @type tilexrep: integer + @ivar tileyrep: Number of tile repetitions in y direction. + @type tileyrep: integer + + @ivar drawingmode: Drawing mode for the material. + - 2 (drawingmode & 4) Textured + - 4 (drawingmode & 16) Light + - 14 (drawingmode & 16384) 3d Polygon Text + @type drawingmode: bitfield + + @ivar transparent: This material is transparent. All meshes with this + material will be rendered after non transparent meshes from back + to front. + @type transparent: boolean + + @ivar zsort: Transparent polygons in meshes with this material will be sorted back to + front before rendering. + Non-Transparent polygons will be sorted front to back before rendering. + @type zsort: boolean + + @ivar lightlayer: Light layers this material affects. + @type lightlayer: bitfield. + + @ivar triangle: Mesh data with this material is triangles. + @type triangle: boolean + + @ivar diffuse: The diffuse colour of the material. black = [0.0, 0.0, 0.0, 1.0] white = [1.0, 1.0, 1.0, 1.0] + @type diffuse: list [r, g, b, a] + @ivar specular: The specular colour of the material. black = [0.0, 0.0, 0.0, 1.0] white = [1.0, 1.0, 1.0, 1.0] + @type specular: list [r, g, b, a] + @ivar shininess: The shininess (specular exponent) of the material. 0.0 <= shininess <= 128.0 + @type shininess: float + @ivar specularity: The amount of specular of the material. 0.0 <= specularity <= 1.0 + @type specularity: float + """ + def updateTexture(tface, rasty): + """ + Updates a realtime animation. + + @param tface: Texture face (eg mat.tface) + @type tface: CObject + @param rasty: Rasterizer + @type rasty: CObject + """ + def setTexture(tface): + """ + Sets texture render state. + + Example:: + mat.setTexture(mat.tface) + + @param tface: Texture face + @type tface: CObject + """ + def activate(rasty, cachingInfo): + """ + Sets material parameters for this object for rendering. + + Material Parameters set: + 1. Texture + 2. Backface culling + 3. Line drawing + 4. Specular Colour + 5. Shininess + 6. Diffuse Colour + 7. Polygon Offset. + + @param rasty: Rasterizer instance. + @type rasty: CObject + @param cachingInfo: Material cache instance. + @type cachingInfo: CObject + """ + def setCustomMaterial(material): + """ + Sets the material state setup object. + + Example:: + class PyMaterial: + def __init__(self): + self.pass_no = 0 + + def activate(self, rasty, cachingInfo, material): + # Activate the material here. + # + # The activate method will be called until it returns False. + # Every time the activate method returns True the mesh will + # be rendered. + # + # rasty is a CObject for passing to material.updateTexture() + # and material.activate() + # cachingInfo is a CObject for passing to material.activate() + # material is the KX_PolygonMaterial instance this material + # was added to + + # default material properties: + if self.pass_no == 0: + material.activate(rasty, cachingInfo) + self.pass_no = 1 + # Return True to do this pass + return True + + self.pass_no = 0 + return False + + # Create a new Python Material and pass it to the renderer. + mat.setCustomMaterial(PyMaterial()) + + @param material: The material object. + @type material: instance + """ + diff --git a/source/gameengine/PyDoc/WhatsNew.py b/source/gameengine/PyDoc/WhatsNew.py index 023d568a052..64bef7ee1c8 100644 --- a/source/gameengine/PyDoc/WhatsNew.py +++ b/source/gameengine/PyDoc/WhatsNew.py @@ -7,6 +7,7 @@ This document lists what has been changed in the Game Engine Python API. Blender CVS - Added L{KX_GameObject}.getDistanceTo() method. (thanks Charlie C) + - Added L{KX_PolygonMaterial} module Blender 2.36 ------------ diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index fd2f3a55f1d..4ce072dd7cc 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -112,11 +112,12 @@ void RAS_BucketManager::RenderAlphaBuckets( // it is needed for compatibility. rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED); + int drawingmode; std::multiset< alphamesh, backtofront>::iterator msit = alphameshset.begin(); for (; msit != alphameshset.end(); ++msit) { - (*msit).m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(*msit).m_ms, - (*msit).m_bucket->ActivateMaterial(cameratrans, rasty, rendertools)); + while ((*msit).m_bucket->ActivateMaterial(cameratrans, rasty, rendertools, drawingmode)) + (*msit).m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(*msit).m_ms, drawingmode); } rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index babecdd585a..330f964de7b 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -36,7 +36,6 @@ #endif RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, - bool ba, const STR_String& matname, int tile, int tilexrep, @@ -77,7 +76,7 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const this->m_zsort == lhs.m_zsort && this->m_drawingmode == lhs.m_drawingmode && this->m_bIsTriangle == lhs.m_bIsTriangle && - this->m_lightlayer == lhs.m_lightlayer && + this->m_lightlayer == lhs.m_lightlayer && this->m_texturename.hash() == lhs.m_texturename.hash() && this->m_materialname.hash() == lhs.m_materialname.hash() ); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 648a8b63464..b039b51dd8b 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -83,7 +83,6 @@ public: }; RAS_IPolyMaterial(const STR_String& texname, - bool ba, const STR_String& matname, int tile, int tilexrep, @@ -110,9 +109,12 @@ public: * @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 {} + virtual bool Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const + { + return false; + } - bool Equals(const RAS_IPolyMaterial& lhs) const; + virtual bool Equals(const RAS_IPolyMaterial& lhs) const; bool Less(const RAS_IPolyMaterial& rhs) const; int GetLightLayer() const; bool IsTransparant() const; diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index bd7f10e32a7..48991566fa5 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -116,7 +116,7 @@ public: * to be rendered with. * The material will be cached. */ - virtual void SetMaterial(const RAS_IPolyMaterial& mat)=0; + virtual bool SetMaterial(const RAS_IPolyMaterial& mat)=0; /** * Init initialises the renderer. */ @@ -328,6 +328,10 @@ public: float difY, float difZ, float diffuse)=0; + /** + * Sets a polygon offset. z depth will be: z1 = mult*z0 + add + */ + virtual void SetPolygonOffset(float mult, float add) = 0; }; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index f2dc7535010..a9934df1d02 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -169,12 +169,13 @@ RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msEnd() return m_meshSlots.end(); } -int RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools) +bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, + RAS_IRenderTools *rendertools, int &drawmode) { rendertools->SetViewMat(cameratrans); - rasty->SetMaterial(*m_material); + if (!rasty->SetMaterial(*m_material)) + return false; bool dolights = m_material->GetDrawingMode()&16; @@ -187,8 +188,10 @@ int RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IR bool bUseLights = rendertools->ProcessLighting(m_material->GetLightLayer()); } - return (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ? + drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ? 1: (m_material->UsesTriangles() ? 0 : 2)); + + return true; } void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, @@ -272,12 +275,13 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, rendertools->SetClientObject((*m_meshSlots.begin()).m_clientObj); } - int drawmode = ActivateMaterial(cameratrans, rasty, rendertools); + int drawmode; for (T_MeshSlotList::const_iterator it = m_meshSlots.begin(); ! (it == m_meshSlots.end()); ++it) { - RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode); + while (ActivateMaterial(cameratrans, rasty, rendertools, drawmode)) + RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode); } } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 83cb06b3c2b..52f835a4575 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -56,7 +56,10 @@ struct KX_VertexIndex { public: KX_VertexIndex(int size); void SetIndex(short loc,unsigned int index); + + // The vertex array short m_vtxarray; + // An index into the vertex array for up to 4 verticies unsigned short m_indexarray[4]; short m_size; }; @@ -124,8 +127,8 @@ public: void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode); - int ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools); + bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, + RAS_IRenderTools *rendertools, int &drawmode); unsigned int NumMeshSlots(); T_MeshSlotList::iterator msBegin(); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 78666b6936d..95688580fa3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -42,8 +42,10 @@ #endif // WIN32 #ifdef __APPLE__ #include +#include #else #include +#include #endif #include "RAS_Rect.h" @@ -157,6 +159,10 @@ static void Myinit_gl_stuff(void) } glPolygonStipple(patc); + + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); } @@ -270,12 +276,9 @@ void RAS_OpenGLRasterizer::DisplayFog() -void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) +bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) { - if (mat.GetCachingInfo() != m_materialCachingInfo) - { - mat.Activate(this, m_materialCachingInfo); - } + return mat.Activate(this, m_materialCachingInfo); } @@ -1329,4 +1332,14 @@ double RAS_OpenGLRasterizer::GetTime() return m_time; } - +void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add) +{ + glPolygonOffset(mult, add); + GLint mode = GL_POLYGON_OFFSET_FILL; + if (m_drawingmode < KX_SHADED) + mode = GL_POLYGON_OFFSET_LINE; + if (mult != 0.0f || add != 0.0f) + glEnable(mode); + else + glDisable(mode); +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index d5a0e7ff551..2571cee1333 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -105,7 +105,7 @@ public: };*/ virtual void SetDepthMask(DepthMask depthmask); - virtual void SetMaterial(const RAS_IPolyMaterial& mat); + virtual bool SetMaterial(const RAS_IPolyMaterial& mat); virtual bool Init(); virtual void Exit(); virtual bool BeginFrame(int drawingmode, double time); @@ -224,6 +224,7 @@ public: float difZ, float diffuse ); + virtual void SetPolygonOffset(float mult, float add); };