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