|
Blender
V2.59
|
00001 /* 00002 * $Id: KX_PolygonMaterial.cpp 35390 2011-03-07 19:14:17Z dfelinto $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <stddef.h> 00035 00036 #include "KX_PolygonMaterial.h" 00037 00038 #include "BKE_mesh.h" 00039 #include "BKE_global.h" 00040 #include "BKE_image.h" 00041 00042 #include "DNA_material_types.h" 00043 #include "DNA_texture_types.h" 00044 #include "DNA_image_types.h" 00045 #include "DNA_meshdata_types.h" 00046 00047 #include "IMB_imbuf_types.h" 00048 00049 #include "GPU_draw.h" 00050 00051 #include "MEM_guardedalloc.h" 00052 00053 #include "RAS_LightObject.h" 00054 #include "RAS_MaterialBucket.h" 00055 00056 #include "KX_PyMath.h" 00057 00058 #define KX_POLYGONMATERIAL_CAPSULE_ID "KX_POLYGONMATERIAL_PTR" 00059 00060 KX_PolygonMaterial::KX_PolygonMaterial() 00061 : PyObjectPlus(), 00062 RAS_IPolyMaterial(), 00063 00064 m_tface(NULL), 00065 m_mcol(NULL), 00066 m_material(NULL), 00067 #ifdef WITH_PYTHON 00068 m_pymaterial(NULL), 00069 #endif 00070 m_pass(0) 00071 { 00072 } 00073 00074 void KX_PolygonMaterial::Initialize( 00075 const STR_String &texname, 00076 Material* ma, 00077 int materialindex, 00078 int tile, 00079 int tilexrep, 00080 int tileyrep, 00081 int mode, 00082 int transp, 00083 bool alpha, 00084 bool zsort, 00085 int lightlayer, 00086 struct MTFace* tface, 00087 unsigned int* mcol) 00088 { 00089 RAS_IPolyMaterial::Initialize( 00090 texname, 00091 ma?ma->id.name:"", 00092 materialindex, 00093 tile, 00094 tilexrep, 00095 tileyrep, 00096 mode, 00097 transp, 00098 alpha, 00099 zsort); 00100 m_tface = tface; 00101 m_mcol = mcol; 00102 m_material = ma; 00103 #ifdef WITH_PYTHON 00104 m_pymaterial = 0; 00105 #endif 00106 m_pass = 0; 00107 } 00108 00109 KX_PolygonMaterial::~KX_PolygonMaterial() 00110 { 00111 #ifdef WITH_PYTHON 00112 if (m_pymaterial) 00113 { 00114 Py_DECREF(m_pymaterial); 00115 } 00116 #endif // WITH_PYTHON 00117 } 00118 00119 Image *KX_PolygonMaterial::GetBlenderImage() const 00120 { 00121 return (m_tface) ? m_tface->tpage : NULL; 00122 } 00123 00124 bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const 00125 { 00126 bool dopass = false; 00127 00128 #ifdef WITH_PYTHON 00129 if (m_pymaterial) 00130 { 00131 PyObject *pyRasty = PyCapsule_New((void*)rasty, KX_POLYGONMATERIAL_CAPSULE_ID, NULL); /* new reference */ 00132 PyObject *pyCachingInfo = PyCapsule_New((void*) &cachingInfo, KX_POLYGONMATERIAL_CAPSULE_ID, NULL); /* new reference */ 00133 PyObject *ret = PyObject_CallMethod(m_pymaterial, (char *)"activate", (char *)"(NNO)", pyRasty, pyCachingInfo, (PyObject*) this->m_proxy); 00134 if (ret) 00135 { 00136 bool value = PyLong_AsSsize_t(ret); 00137 Py_DECREF(ret); 00138 dopass = value; 00139 } 00140 else 00141 { 00142 PyErr_Print(); 00143 PyErr_Clear(); 00144 PySys_SetObject( (char *)"last_traceback", NULL); 00145 } 00146 } 00147 else 00148 #endif // WITH_PYTHON 00149 { 00150 switch (m_pass++) 00151 { 00152 case 0: 00153 DefaultActivate(rasty, cachingInfo); 00154 dopass = true; 00155 break; 00156 default: 00157 m_pass = 0; 00158 dopass = false; 00159 break; 00160 } 00161 } 00162 00163 return dopass; 00164 } 00165 00166 void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const 00167 { 00168 if (GetCachingInfo() != cachingInfo) 00169 { 00170 if (!cachingInfo) 00171 GPU_set_tpage(NULL, 0); 00172 00173 cachingInfo = GetCachingInfo(); 00174 00175 if ((m_drawingmode & RAS_IRasterizer::KX_TEX)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)) 00176 { 00177 Image *ima = (Image*)m_tface->tpage; 00178 GPU_update_image_time(ima, rasty->GetTime()); 00179 GPU_set_tpage(m_tface, 1); 00180 } 00181 else 00182 GPU_set_tpage(NULL, 0); 00183 00184 if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE) 00185 rasty->SetCullFace(false); 00186 else 00187 rasty->SetCullFace(true); 00188 00189 if ((m_drawingmode & RAS_IRasterizer::KX_LINES) || 00190 (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) 00191 rasty->SetLines(true); 00192 else 00193 rasty->SetLines(false); 00194 rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity); 00195 rasty->SetShinyness(m_shininess); 00196 rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); 00197 if (m_material) 00198 rasty->SetPolygonOffset(-m_material->zoffs, 0.0); 00199 } 00200 00201 //rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity); 00202 //rasty->SetShinyness(m_shininess); 00203 //rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0); 00204 //if (m_material) 00205 // rasty->SetPolygonOffset(-m_material->zoffs, 0.0); 00206 } 00207 00208 void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const 00209 { 00210 if (m_material) { 00211 *rgba++ = (unsigned char) (m_material->r*255.0); 00212 *rgba++ = (unsigned char) (m_material->g*255.0); 00213 *rgba++ = (unsigned char) (m_material->b*255.0); 00214 *rgba++ = (unsigned char) (m_material->alpha*255.0); 00215 } else 00216 RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); 00217 } 00218 00219 #ifdef WITH_PYTHON 00220 00221 //---------------------------------------------------------------------------- 00222 //Python 00223 00224 00225 PyMethodDef KX_PolygonMaterial::Methods[] = { 00226 KX_PYMETHODTABLE(KX_PolygonMaterial, setCustomMaterial), 00227 KX_PYMETHODTABLE(KX_PolygonMaterial, updateTexture), 00228 KX_PYMETHODTABLE(KX_PolygonMaterial, setTexture), 00229 KX_PYMETHODTABLE(KX_PolygonMaterial, activate), 00230 // KX_PYMETHODTABLE(KX_PolygonMaterial, setPerPixelLights), 00231 00232 {NULL,NULL} //Sentinel 00233 }; 00234 00235 PyAttributeDef KX_PolygonMaterial::Attributes[] = { 00236 KX_PYATTRIBUTE_RO_FUNCTION("texture", KX_PolygonMaterial, pyattr_get_texture), 00237 KX_PYATTRIBUTE_RO_FUNCTION("material", KX_PolygonMaterial, pyattr_get_material), /* should probably be .name ? */ 00238 00239 KX_PYATTRIBUTE_INT_RW("tile", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tile), 00240 KX_PYATTRIBUTE_INT_RW("tilexrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tilexrep), 00241 KX_PYATTRIBUTE_INT_RW("tileyrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tileyrep), 00242 KX_PYATTRIBUTE_INT_RW("drawingmode", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_drawingmode), 00243 //KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer), 00244 00245 KX_PYATTRIBUTE_BOOL_RW("transparent", KX_PolygonMaterial, m_alpha), 00246 KX_PYATTRIBUTE_BOOL_RW("zsort", KX_PolygonMaterial, m_zsort), 00247 00248 KX_PYATTRIBUTE_FLOAT_RW("shininess", 0.0f, 1000.0f, KX_PolygonMaterial, m_shininess), 00249 KX_PYATTRIBUTE_FLOAT_RW("specularity", 0.0f, 1000.0f, KX_PolygonMaterial, m_specularity), 00250 00251 KX_PYATTRIBUTE_RW_FUNCTION("diffuse", KX_PolygonMaterial, pyattr_get_diffuse, pyattr_set_diffuse), 00252 KX_PYATTRIBUTE_RW_FUNCTION("specular",KX_PolygonMaterial, pyattr_get_specular, pyattr_set_specular), 00253 00254 KX_PYATTRIBUTE_RO_FUNCTION("tface", KX_PolygonMaterial, pyattr_get_tface), /* How the heck is this even useful??? - Campbell */ 00255 KX_PYATTRIBUTE_RO_FUNCTION("gl_texture", KX_PolygonMaterial, pyattr_get_gl_texture), /* could be called 'bindcode' */ 00256 00257 /* triangle used to be an attribute, removed for 2.49, nobody should be using it */ 00258 { NULL } //Sentinel 00259 }; 00260 00261 PyTypeObject KX_PolygonMaterial::Type = { 00262 PyVarObject_HEAD_INIT(NULL, 0) 00263 "KX_PolygonMaterial", 00264 sizeof(PyObjectPlus_Proxy), 00265 0, 00266 py_base_dealloc, 00267 0, 00268 0, 00269 0, 00270 0, 00271 py_base_repr, 00272 0,0,0,0,0,0,0,0,0, 00273 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 00274 0,0,0,0,0,0,0, 00275 Methods, 00276 0, 00277 0, 00278 &PyObjectPlus::Type, 00279 0,0,0,0,0,0, 00280 py_base_new 00281 }; 00282 00283 KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(material)") 00284 { 00285 PyObject *material; 00286 if (PyArg_ParseTuple(args, "O:setCustomMaterial", &material)) 00287 { 00288 if (m_pymaterial) { 00289 Py_DECREF(m_pymaterial); 00290 } 00291 m_pymaterial = material; 00292 Py_INCREF(m_pymaterial); 00293 Py_RETURN_NONE; 00294 } 00295 00296 return NULL; 00297 } 00298 00299 KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rasty)") 00300 { 00301 PyObject *pyrasty, *pytface; 00302 if (PyArg_ParseTuple(args, "O!O!:updateTexture", &PyCapsule_Type, &pytface, &PyCapsule_Type, &pyrasty)) 00303 { 00304 MTFace *tface = (MTFace*) PyCapsule_GetPointer(pytface, KX_POLYGONMATERIAL_CAPSULE_ID); 00305 RAS_IRasterizer *rasty = (RAS_IRasterizer*) PyCapsule_GetPointer(pyrasty, KX_POLYGONMATERIAL_CAPSULE_ID); 00306 Image *ima = (Image*)tface->tpage; 00307 GPU_update_image_time(ima, rasty->GetTime()); 00308 00309 Py_RETURN_NONE; 00310 } 00311 00312 return NULL; 00313 } 00314 00315 KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)") 00316 { 00317 PyObject *pytface; 00318 if (PyArg_ParseTuple(args, "O!:setTexture", &PyCapsule_Type, &pytface)) 00319 { 00320 MTFace *tface = (MTFace*) PyCapsule_GetPointer(pytface, KX_POLYGONMATERIAL_CAPSULE_ID); 00321 GPU_set_tpage(tface, 1); 00322 Py_RETURN_NONE; 00323 } 00324 00325 return NULL; 00326 } 00327 00328 KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") 00329 { 00330 PyObject *pyrasty, *pyCachingInfo; 00331 if (PyArg_ParseTuple(args, "O!O!:activate", &PyCapsule_Type, &pyrasty, &PyCapsule_Type, &pyCachingInfo)) 00332 { 00333 RAS_IRasterizer *rasty = static_cast<RAS_IRasterizer*>(PyCapsule_GetPointer(pyrasty, KX_POLYGONMATERIAL_CAPSULE_ID)); 00334 TCachingInfo *cachingInfo = static_cast<TCachingInfo*>(PyCapsule_GetPointer(pyCachingInfo, KX_POLYGONMATERIAL_CAPSULE_ID)); 00335 if (rasty && cachingInfo) 00336 { 00337 DefaultActivate(rasty, *cachingInfo); 00338 Py_RETURN_NONE; 00339 } 00340 } 00341 00342 return NULL; 00343 } 00344 00345 PyObject* KX_PolygonMaterial::pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00346 { 00347 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00348 return PyUnicode_FromString(self->m_texturename.ReadPtr()); 00349 } 00350 00351 PyObject* KX_PolygonMaterial::pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00352 { 00353 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00354 return PyUnicode_FromString(self->m_materialname.ReadPtr()); 00355 } 00356 00357 /* this does not seem useful */ 00358 PyObject* KX_PolygonMaterial::pyattr_get_tface(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00359 { 00360 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00361 return PyCapsule_New(self->m_tface, KX_POLYGONMATERIAL_CAPSULE_ID, NULL); 00362 } 00363 00364 PyObject* KX_PolygonMaterial::pyattr_get_gl_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00365 { 00366 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00367 int bindcode= 0; 00368 if (self->m_tface && self->m_tface->tpage) 00369 bindcode= self->m_tface->tpage->bindcode; 00370 00371 return PyLong_FromSsize_t(bindcode); 00372 } 00373 00374 00375 PyObject* KX_PolygonMaterial::pyattr_get_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00376 { 00377 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00378 return PyObjectFrom(self->m_diffuse); 00379 } 00380 00381 int KX_PolygonMaterial::pyattr_set_diffuse(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) 00382 { 00383 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00384 MT_Vector3 vec; 00385 00386 if (!PyVecTo(value, vec)) 00387 return PY_SET_ATTR_FAIL; 00388 00389 self->m_diffuse= vec; 00390 return PY_SET_ATTR_SUCCESS; 00391 } 00392 00393 PyObject* KX_PolygonMaterial::pyattr_get_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00394 { 00395 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00396 return PyObjectFrom(self->m_specular); 00397 } 00398 00399 int KX_PolygonMaterial::pyattr_set_specular(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) 00400 { 00401 KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v); 00402 MT_Vector3 vec; 00403 00404 if (!PyVecTo(value, vec)) 00405 return PY_SET_ATTR_FAIL; 00406 00407 self->m_specular= vec; 00408 return PY_SET_ATTR_SUCCESS; 00409 } 00410 00411 #endif // WITH_PYTHON