Blender V2.61 - r43446
|
00001 00005 // ------------------------------------ 00006 // ... 00007 // ------------------------------------ 00008 #include "GL/glew.h" 00009 00010 #include "KX_BlenderMaterial.h" 00011 #include "BL_Material.h" 00012 #include "KX_Scene.h" 00013 #include "KX_Light.h" 00014 #include "KX_GameObject.h" 00015 #include "KX_MeshProxy.h" 00016 00017 #include "MT_Vector3.h" 00018 #include "MT_Vector4.h" 00019 #include "MT_Matrix4x4.h" 00020 00021 #include "RAS_BucketManager.h" 00022 #include "RAS_MeshObject.h" 00023 #include "RAS_IRasterizer.h" 00024 #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" 00025 00026 #include "GPU_draw.h" 00027 00028 #include "STR_HashedString.h" 00029 00030 // ------------------------------------ 00031 #include "DNA_object_types.h" 00032 #include "DNA_material_types.h" 00033 #include "DNA_image_types.h" 00034 #include "DNA_meshdata_types.h" 00035 #include "BKE_mesh.h" 00036 // ------------------------------------ 00037 #include "BLI_utildefines.h" 00038 00039 #define spit(x) std::cout << x << std::endl; 00040 00041 BL_Shader *KX_BlenderMaterial::mLastShader = NULL; 00042 BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; 00043 00044 //static PyObject *gTextureDict = 0; 00045 00046 KX_BlenderMaterial::KX_BlenderMaterial() 00047 : PyObjectPlus(), 00048 RAS_IPolyMaterial(), 00049 mMaterial(NULL), 00050 mShader(0), 00051 mBlenderShader(0), 00052 mScene(NULL), 00053 mUserDefBlend(0), 00054 mModified(0), 00055 mConstructed(false), 00056 mPass(0) 00057 { 00058 } 00059 00060 void KX_BlenderMaterial::Initialize( 00061 KX_Scene *scene, 00062 BL_Material *data, 00063 GameSettings *game) 00064 { 00065 RAS_IPolyMaterial::Initialize( 00066 data->texname[0], 00067 data->matname, 00068 data->materialindex, 00069 data->tile, 00070 data->tilexrep[0], 00071 data->tileyrep[0], 00072 data->alphablend, 00073 ((data->ras_mode &ALPHA)!=0), 00074 ((data->ras_mode &ZSORT)!=0), 00075 ((data->ras_mode &USE_LIGHT)!=0), 00076 ((data->ras_mode &TEX)), 00077 game 00078 ); 00079 mMaterial = data; 00080 mShader = 0; 00081 mBlenderShader = 0; 00082 mScene = scene; 00083 mUserDefBlend = 0; 00084 mModified = 0; 00085 mConstructed = false; 00086 mPass = 0; 00087 // -------------------------------- 00088 // RAS_IPolyMaterial variables... 00089 m_flag |= RAS_BLENDERMAT; 00090 m_flag |= (mMaterial->IdMode>=ONETEX)? RAS_MULTITEX: 0; 00091 m_flag |= ((mMaterial->ras_mode & USE_LIGHT)!=0)? RAS_MULTILIGHT: 0; 00092 m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0; 00093 m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0; 00094 00095 // figure max 00096 int enabled = mMaterial->num_enabled; 00097 int max = BL_Texture::GetMaxUnits(); 00098 mMaterial->num_enabled = enabled>=max?max:enabled; 00099 00100 // test the sum of the various modes for equality 00101 // so we can ether accept or reject this material 00102 // as being equal, this is rather important to 00103 // prevent material bleeding 00104 for(int i=0; i<mMaterial->num_enabled; i++) { 00105 m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]); 00106 } 00107 m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT)); 00108 } 00109 00110 KX_BlenderMaterial::~KX_BlenderMaterial() 00111 { 00112 // cleanup work 00113 if (mConstructed) 00114 // clean only if material was actually used 00115 OnExit(); 00116 } 00117 00118 MTFace* KX_BlenderMaterial::GetMTFace(void) const 00119 { 00120 // fonts on polys 00121 MT_assert(mMaterial->tface); 00122 return mMaterial->tface; 00123 } 00124 00125 unsigned int* KX_BlenderMaterial::GetMCol(void) const 00126 { 00127 // fonts on polys 00128 return mMaterial->rgb; 00129 } 00130 00131 void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const 00132 { 00133 if (mMaterial) { 00134 *rgba++ = (unsigned char) (mMaterial->matcolor[0]*255.0); 00135 *rgba++ = (unsigned char) (mMaterial->matcolor[1]*255.0); 00136 *rgba++ = (unsigned char) (mMaterial->matcolor[2]*255.0); 00137 *rgba++ = (unsigned char) (mMaterial->matcolor[3]*255.0); 00138 } else 00139 RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); 00140 } 00141 00142 Material *KX_BlenderMaterial::GetBlenderMaterial() const 00143 { 00144 return mMaterial->material; 00145 } 00146 00147 Scene* KX_BlenderMaterial::GetBlenderScene() const 00148 { 00149 return mScene->GetBlenderScene(); 00150 } 00151 00152 void KX_BlenderMaterial::ReleaseMaterial() 00153 { 00154 if (mBlenderShader) 00155 mBlenderShader->ReloadMaterial(); 00156 } 00157 00158 void KX_BlenderMaterial::OnConstruction(int layer) 00159 { 00160 if (mConstructed) 00161 // when material are reused between objects 00162 return; 00163 00164 if(mMaterial->glslmat) 00165 SetBlenderGLSLShader(layer); 00166 00167 // for each unique material... 00168 int i; 00169 for(i=0; i<mMaterial->num_enabled; i++) { 00170 if( mMaterial->mapping[i].mapping & USEENV ) { 00171 if(!GLEW_ARB_texture_cube_map) { 00172 spit("CubeMap textures not supported"); 00173 continue; 00174 } 00175 if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) 00176 spit("unable to initialize image("<<i<<") in "<< 00177 mMaterial->matname<< ", image will not be available"); 00178 } 00179 00180 else { 00181 if( mMaterial->img[i] ) { 00182 if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) 00183 spit("unable to initialize image("<<i<<") in "<< 00184 mMaterial->matname<< ", image will not be available"); 00185 } 00186 } 00187 } 00188 00189 mBlendFunc[0] =0; 00190 mBlendFunc[1] =0; 00191 mConstructed = true; 00192 } 00193 00194 void KX_BlenderMaterial::EndFrame() 00195 { 00196 if(mLastBlenderShader) { 00197 mLastBlenderShader->SetProg(false); 00198 mLastBlenderShader = NULL; 00199 } 00200 00201 if(mLastShader) { 00202 mLastShader->SetProg(false); 00203 mLastShader = NULL; 00204 } 00205 } 00206 00207 void KX_BlenderMaterial::OnExit() 00208 { 00209 if( mShader ) { 00210 //note, the shader here is allocated, per unique material 00211 //and this function is called per face 00212 if(mShader == mLastShader) { 00213 mShader->SetProg(false); 00214 mLastShader = NULL; 00215 } 00216 00217 delete mShader; 00218 mShader = 0; 00219 } 00220 00221 if( mBlenderShader ) { 00222 if(mBlenderShader == mLastBlenderShader) { 00223 mBlenderShader->SetProg(false); 00224 mLastBlenderShader = NULL; 00225 } 00226 00227 delete mBlenderShader; 00228 mBlenderShader = 0; 00229 } 00230 00231 BL_Texture::ActivateFirst(); 00232 for(int i=0; i<mMaterial->num_enabled; i++) { 00233 BL_Texture::ActivateUnit(i); 00234 mTextures[i].DeleteTex(); 00235 mTextures[i].DisableUnit(); 00236 } 00237 00238 if( mMaterial->tface ) 00239 GPU_set_tpage(mMaterial->tface, 1, mMaterial->alphablend); 00240 } 00241 00242 00243 void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) 00244 { 00245 MT_assert(GLEW_ARB_shader_objects && mShader); 00246 00247 int i; 00248 if( !enable || !mShader->Ok() ) { 00249 // frame cleanup. 00250 if(mShader == mLastShader) { 00251 mShader->SetProg(false); 00252 mLastShader = NULL; 00253 } 00254 00255 ras->SetAlphaBlend(TF_SOLID); 00256 BL_Texture::DisableAllTextures(); 00257 return; 00258 } 00259 00260 BL_Texture::DisableAllTextures(); 00261 mShader->SetProg(true); 00262 mLastShader = mShader; 00263 00264 BL_Texture::ActivateFirst(); 00265 00266 mShader->ApplyShader(); 00267 00268 // for each enabled unit 00269 for(i=0; i<mMaterial->num_enabled; i++) { 00270 if(!mTextures[i].Ok()) continue; 00271 mTextures[i].ActivateTexture(); 00272 mTextures[0].SetMapping(mMaterial->mapping[i].mapping); 00273 } 00274 00275 if(!mUserDefBlend) { 00276 ras->SetAlphaBlend(mMaterial->alphablend); 00277 } 00278 else { 00279 ras->SetAlphaBlend(TF_SOLID); 00280 ras->SetAlphaBlend(-1); // indicates custom mode 00281 00282 // tested to be valid enums 00283 glEnable(GL_BLEND); 00284 glBlendFunc(mBlendFunc[0], mBlendFunc[1]); 00285 } 00286 } 00287 00288 void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras) 00289 { 00290 if( !enable || !mBlenderShader->Ok() ) { 00291 ras->SetAlphaBlend(TF_SOLID); 00292 00293 // frame cleanup. 00294 if(mLastBlenderShader) { 00295 mLastBlenderShader->SetProg(false); 00296 mLastBlenderShader= NULL; 00297 } 00298 else 00299 BL_Texture::DisableAllTextures(); 00300 00301 return; 00302 } 00303 00304 if(!mBlenderShader->Equals(mLastBlenderShader)) { 00305 ras->SetAlphaBlend(mMaterial->alphablend); 00306 00307 if(mLastBlenderShader) 00308 mLastBlenderShader->SetProg(false); 00309 else 00310 BL_Texture::DisableAllTextures(); 00311 00312 mBlenderShader->SetProg(true, ras->GetTime()); 00313 mLastBlenderShader= mBlenderShader; 00314 } 00315 } 00316 00317 void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) 00318 { 00319 BL_Texture::DisableAllTextures(); 00320 00321 if( !enable ) { 00322 ras->SetAlphaBlend(TF_SOLID); 00323 return; 00324 } 00325 00326 BL_Texture::ActivateFirst(); 00327 00328 if( mMaterial->IdMode == DEFAULT_BLENDER ) { 00329 ras->SetAlphaBlend(mMaterial->alphablend); 00330 return; 00331 } 00332 00333 if( mMaterial->IdMode == TEXFACE ) { 00334 // no material connected to the object 00335 if( mTextures[0].Ok() ) { 00336 mTextures[0].ActivateTexture(); 00337 mTextures[0].setTexEnv(0, true); 00338 mTextures[0].SetMapping(mMaterial->mapping[0].mapping); 00339 ras->SetAlphaBlend(mMaterial->alphablend); 00340 } 00341 return; 00342 } 00343 00344 int mode = 0,i=0; 00345 for(i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) { 00346 if( !mTextures[i].Ok() ) continue; 00347 00348 mTextures[i].ActivateTexture(); 00349 mTextures[i].setTexEnv(mMaterial); 00350 mode = mMaterial->mapping[i].mapping; 00351 00352 if(mode &USEOBJ) 00353 setObjectMatrixData(i, ras); 00354 else 00355 mTextures[i].SetMapping(mode); 00356 00357 if(!(mode &USEOBJ)) 00358 setTexMatrixData( i ); 00359 } 00360 00361 if(!mUserDefBlend) { 00362 ras->SetAlphaBlend(mMaterial->alphablend); 00363 } 00364 else { 00365 ras->SetAlphaBlend(TF_SOLID); 00366 ras->SetAlphaBlend(-1); // indicates custom mode 00367 00368 glEnable(GL_BLEND); 00369 glBlendFunc(mBlendFunc[0], mBlendFunc[1]); 00370 } 00371 } 00372 00373 void 00374 KX_BlenderMaterial::ActivatShaders( 00375 RAS_IRasterizer* rasty, 00376 TCachingInfo& cachingInfo)const 00377 { 00378 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); 00379 00380 // reset... 00381 if(tmp->mMaterial->IsShared()) 00382 cachingInfo =0; 00383 00384 if(mLastBlenderShader) { 00385 mLastBlenderShader->SetProg(false); 00386 mLastBlenderShader= NULL; 00387 } 00388 00389 if (GetCachingInfo() != cachingInfo) { 00390 00391 if (!cachingInfo) 00392 tmp->setShaderData(false, rasty); 00393 00394 cachingInfo = GetCachingInfo(); 00395 00396 if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) 00397 tmp->setShaderData(true, rasty); 00398 else 00399 tmp->setShaderData(false, rasty); 00400 00401 if (mMaterial->ras_mode &TWOSIDED) 00402 rasty->SetCullFace(false); 00403 else 00404 rasty->SetCullFace(true); 00405 00406 if ((mMaterial->ras_mode &WIRE) || 00407 (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) 00408 { 00409 if (mMaterial->ras_mode &WIRE) 00410 rasty->SetCullFace(false); 00411 rasty->SetLines(true); 00412 } 00413 else 00414 rasty->SetLines(false); 00415 ActivatGLMaterials(rasty); 00416 ActivateTexGen(rasty); 00417 } 00418 00419 //ActivatGLMaterials(rasty); 00420 //ActivateTexGen(rasty); 00421 } 00422 00423 void 00424 KX_BlenderMaterial::ActivateBlenderShaders( 00425 RAS_IRasterizer* rasty, 00426 TCachingInfo& cachingInfo)const 00427 { 00428 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); 00429 00430 if(mLastShader) { 00431 mLastShader->SetProg(false); 00432 mLastShader= NULL; 00433 } 00434 00435 if (GetCachingInfo() != cachingInfo) { 00436 if (!cachingInfo) 00437 tmp->setBlenderShaderData(false, rasty); 00438 00439 cachingInfo = GetCachingInfo(); 00440 00441 if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) 00442 tmp->setBlenderShaderData(true, rasty); 00443 else 00444 tmp->setBlenderShaderData(false, rasty); 00445 00446 if (mMaterial->ras_mode &TWOSIDED) 00447 rasty->SetCullFace(false); 00448 else 00449 rasty->SetCullFace(true); 00450 00451 if ((mMaterial->ras_mode &WIRE) || 00452 (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) 00453 { 00454 if (mMaterial->ras_mode &WIRE) 00455 rasty->SetCullFace(false); 00456 rasty->SetLines(true); 00457 } 00458 else 00459 rasty->SetLines(false); 00460 00461 ActivatGLMaterials(rasty); 00462 mBlenderShader->SetAttribs(rasty, mMaterial); 00463 } 00464 } 00465 00466 void 00467 KX_BlenderMaterial::ActivateMat( 00468 RAS_IRasterizer* rasty, 00469 TCachingInfo& cachingInfo 00470 )const 00471 { 00472 KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); 00473 00474 if(mLastShader) { 00475 mLastShader->SetProg(false); 00476 mLastShader= NULL; 00477 } 00478 00479 if(mLastBlenderShader) { 00480 mLastBlenderShader->SetProg(false); 00481 mLastBlenderShader= NULL; 00482 } 00483 00484 if (GetCachingInfo() != cachingInfo) { 00485 if (!cachingInfo) 00486 tmp->setTexData( false,rasty ); 00487 00488 cachingInfo = GetCachingInfo(); 00489 00490 if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) 00491 tmp->setTexData( true,rasty ); 00492 else 00493 tmp->setTexData( false,rasty); 00494 00495 if (mMaterial->ras_mode &TWOSIDED) 00496 rasty->SetCullFace(false); 00497 else 00498 rasty->SetCullFace(true); 00499 00500 if ((mMaterial->ras_mode &WIRE) || 00501 (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) 00502 { 00503 if (mMaterial->ras_mode &WIRE) 00504 rasty->SetCullFace(false); 00505 rasty->SetLines(true); 00506 } 00507 else 00508 rasty->SetLines(false); 00509 ActivatGLMaterials(rasty); 00510 ActivateTexGen(rasty); 00511 } 00512 00513 //ActivatGLMaterials(rasty); 00514 //ActivateTexGen(rasty); 00515 } 00516 00517 bool 00518 KX_BlenderMaterial::Activate( 00519 RAS_IRasterizer* rasty, 00520 TCachingInfo& cachingInfo 00521 )const 00522 { 00523 if(GLEW_ARB_shader_objects && (mShader && mShader->Ok())) { 00524 if((mPass++) < mShader->getNumPass() ) { 00525 ActivatShaders(rasty, cachingInfo); 00526 return true; 00527 } 00528 else { 00529 if(mShader == mLastShader) { 00530 mShader->SetProg(false); 00531 mLastShader = NULL; 00532 } 00533 mPass = 0; 00534 return false; 00535 } 00536 } 00537 else if( GLEW_ARB_shader_objects && (mBlenderShader && mBlenderShader->Ok() ) ) { 00538 if(mPass++ == 0) { 00539 ActivateBlenderShaders(rasty, cachingInfo); 00540 return true; 00541 } 00542 else { 00543 mPass = 0; 00544 return false; 00545 } 00546 } 00547 else { 00548 if(mPass++ == 0) { 00549 ActivateMat(rasty, cachingInfo); 00550 return true; 00551 } 00552 else { 00553 mPass = 0; 00554 return false; 00555 } 00556 } 00557 } 00558 00559 bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const 00560 { 00561 if(!RAS_IPolyMaterial::UsesLighting(rasty)) 00562 return false; 00563 00564 if(mShader && mShader->Ok()) 00565 return true; 00566 else if(mBlenderShader && mBlenderShader->Ok()) 00567 return false; 00568 else 00569 return true; 00570 } 00571 00572 void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty) const 00573 { 00574 if(mShader && GLEW_ARB_shader_objects) { 00575 mShader->Update(ms, rasty); 00576 } 00577 else if(mBlenderShader && GLEW_ARB_shader_objects) { 00578 int alphablend; 00579 00580 mBlenderShader->Update(ms, rasty); 00581 00582 /* we do blend modes here, because they can change per object 00583 * with the same material due to obcolor/obalpha */ 00584 alphablend = mBlenderShader->GetAlphaBlend(); 00585 if(ELEM3(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID) 00586 alphablend = mMaterial->alphablend; 00587 00588 rasty->SetAlphaBlend(alphablend); 00589 } 00590 } 00591 00592 void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const 00593 { 00594 if(mShader || !mBlenderShader) { 00595 rasty->SetSpecularity( 00596 mMaterial->speccolor[0]*mMaterial->spec_f, 00597 mMaterial->speccolor[1]*mMaterial->spec_f, 00598 mMaterial->speccolor[2]*mMaterial->spec_f, 00599 mMaterial->spec_f 00600 ); 00601 00602 rasty->SetShinyness( mMaterial->hard ); 00603 00604 rasty->SetDiffuse( 00605 mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 00606 mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, 00607 mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, 00608 1.0f); 00609 00610 rasty->SetEmissive( 00611 mMaterial->matcolor[0]*mMaterial->emit, 00612 mMaterial->matcolor[1]*mMaterial->emit, 00613 mMaterial->matcolor[2]*mMaterial->emit, 00614 1.0 ); 00615 00616 rasty->SetAmbient(mMaterial->amb); 00617 } 00618 00619 if (mMaterial->material) 00620 rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); 00621 } 00622 00623 00624 void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const 00625 { 00626 if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { 00627 ras->SetAttribNum(0); 00628 if(mShader && GLEW_ARB_shader_objects) { 00629 if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) { 00630 ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0); 00631 ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1); 00632 ras->SetAttribNum(2); 00633 } 00634 } 00635 00636 ras->SetTexCoordNum(mMaterial->num_enabled); 00637 00638 for(int i=0; i<mMaterial->num_enabled; i++) { 00639 int mode = mMaterial->mapping[i].mapping; 00640 00641 if (mode &USECUSTOMUV) 00642 { 00643 if (!mMaterial->mapping[i].uvCoName.IsEmpty()) 00644 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i); 00645 continue; 00646 } 00647 00648 if( mode &(USEREFL|USEOBJ)) 00649 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i); 00650 else if(mode &USEORCO) 00651 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_ORCO, i); 00652 else if(mode &USENORM) 00653 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i); 00654 else if(mode &USEUV) 00655 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i); 00656 else if(mode &USETANG) 00657 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i); 00658 else 00659 ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); 00660 } 00661 } 00662 } 00663 00664 void KX_BlenderMaterial::setTexMatrixData(int i) 00665 { 00666 glMatrixMode(GL_TEXTURE); 00667 glLoadIdentity(); 00668 00669 if( GLEW_ARB_texture_cube_map && 00670 mTextures[i].GetTextureType() == GL_TEXTURE_CUBE_MAP_ARB && 00671 mMaterial->mapping[i].mapping & USEREFL) { 00672 glScalef( 00673 mMaterial->mapping[i].scale[0], 00674 -mMaterial->mapping[i].scale[1], 00675 -mMaterial->mapping[i].scale[2] 00676 ); 00677 } 00678 else 00679 { 00680 glScalef( 00681 mMaterial->mapping[i].scale[0], 00682 mMaterial->mapping[i].scale[1], 00683 mMaterial->mapping[i].scale[2] 00684 ); 00685 } 00686 glTranslatef( 00687 mMaterial->mapping[i].offsets[0], 00688 mMaterial->mapping[i].offsets[1], 00689 mMaterial->mapping[i].offsets[2] 00690 ); 00691 00692 glMatrixMode(GL_MODELVIEW); 00693 00694 } 00695 00696 static void GetProjPlane(BL_Material *mat, int index,int num, float*param) 00697 { 00698 param[0]=param[1]=param[2]=param[3]=0.f; 00699 if( mat->mapping[index].projplane[num] == PROJX ) 00700 param[0] = 1.f; 00701 else if( mat->mapping[index].projplane[num] == PROJY ) 00702 param[1] = 1.f; 00703 else if( mat->mapping[index].projplane[num] == PROJZ) 00704 param[2] = 1.f; 00705 } 00706 00707 void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras) 00708 { 00709 KX_GameObject *obj = 00710 (KX_GameObject*) 00711 mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame); 00712 00713 if(!obj) return; 00714 00715 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); 00716 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); 00717 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); 00718 00719 GLenum plane = GL_EYE_PLANE; 00720 00721 // figure plane gen 00722 float proj[4]= {0.f,0.f,0.f,0.f}; 00723 GetProjPlane(mMaterial, i, 0, proj); 00724 glTexGenfv(GL_S, plane, proj); 00725 00726 GetProjPlane(mMaterial, i, 1, proj); 00727 glTexGenfv(GL_T, plane, proj); 00728 00729 GetProjPlane(mMaterial, i, 2, proj); 00730 glTexGenfv(GL_R, plane, proj); 00731 00732 glEnable(GL_TEXTURE_GEN_S); 00733 glEnable(GL_TEXTURE_GEN_T); 00734 glEnable(GL_TEXTURE_GEN_R); 00735 00736 const MT_Matrix4x4& mvmat = ras->GetViewMatrix(); 00737 00738 glMatrixMode(GL_TEXTURE); 00739 glLoadIdentity(); 00740 glScalef( 00741 mMaterial->mapping[i].scale[0], 00742 mMaterial->mapping[i].scale[1], 00743 mMaterial->mapping[i].scale[2] 00744 ); 00745 00746 MT_Point3 pos = obj->NodeGetWorldPosition(); 00747 MT_Vector4 matmul = MT_Vector4(pos[0], pos[1], pos[2], 1.f); 00748 MT_Vector4 t = mvmat*matmul; 00749 00750 glTranslatef( (float)(-t[0]), (float)(-t[1]), (float)(-t[2]) ); 00751 00752 glMatrixMode(GL_MODELVIEW); 00753 00754 } 00755 00756 // ------------------------------------ 00757 void KX_BlenderMaterial::UpdateIPO( 00758 MT_Vector4 rgba, 00759 MT_Vector3 specrgb, 00760 MT_Scalar hard, 00761 MT_Scalar spec, 00762 MT_Scalar ref, 00763 MT_Scalar emit, 00764 MT_Scalar alpha 00765 ) 00766 { 00767 // only works one deep now 00768 mMaterial->speccolor[0] = (float)(specrgb)[0]; 00769 mMaterial->speccolor[1] = (float)(specrgb)[1]; 00770 mMaterial->speccolor[2] = (float)(specrgb)[2]; 00771 mMaterial->matcolor[0] = (float)(rgba[0]); 00772 mMaterial->matcolor[1] = (float)(rgba[1]); 00773 mMaterial->matcolor[2] = (float)(rgba[2]); 00774 mMaterial->alpha = (float)(alpha); 00775 mMaterial->hard = (float)(hard); 00776 mMaterial->emit = (float)(emit); 00777 mMaterial->spec_f = (float)(spec); 00778 mMaterial->ref = (float)(ref); 00779 } 00780 00781 void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) 00782 { 00783 if(!mBlenderShader) 00784 mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer); 00785 00786 if(!mBlenderShader->Ok()) { 00787 delete mBlenderShader; 00788 mBlenderShader = 0; 00789 } 00790 } 00791 00792 #ifdef WITH_PYTHON 00793 00794 PyMethodDef KX_BlenderMaterial::Methods[] = 00795 { 00796 KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ), 00797 KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ), 00798 KX_PYMETHODTABLE( KX_BlenderMaterial, setBlending ), 00799 {NULL,NULL} //Sentinel 00800 }; 00801 00802 PyAttributeDef KX_BlenderMaterial::Attributes[] = { 00803 KX_PYATTRIBUTE_RO_FUNCTION("shader", KX_BlenderMaterial, pyattr_get_shader), 00804 KX_PYATTRIBUTE_RO_FUNCTION("material_index", KX_BlenderMaterial, pyattr_get_materialIndex), 00805 KX_PYATTRIBUTE_RW_FUNCTION("blending", KX_BlenderMaterial, pyattr_get_blending, pyattr_set_blending), 00806 { NULL } //Sentinel 00807 }; 00808 00809 PyTypeObject KX_BlenderMaterial::Type = { 00810 PyVarObject_HEAD_INIT(NULL, 0) 00811 "KX_BlenderMaterial", 00812 sizeof(PyObjectPlus_Proxy), 00813 0, 00814 py_base_dealloc, 00815 0, 00816 0, 00817 0, 00818 0, 00819 py_base_repr, 00820 0,0,0,0,0,0,0,0,0, 00821 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 00822 0,0,0,0,0,0,0, 00823 Methods, 00824 0, 00825 0, 00826 &PyObjectPlus::Type, 00827 0,0,0,0,0,0, 00828 py_base_new 00829 }; 00830 00831 PyObject* KX_BlenderMaterial::pyattr_get_shader(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00832 { 00833 KX_BlenderMaterial* self= static_cast<KX_BlenderMaterial*>(self_v); 00834 return self->PygetShader(NULL, NULL); 00835 } 00836 00837 PyObject* KX_BlenderMaterial::pyattr_get_materialIndex(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00838 { 00839 KX_BlenderMaterial* self= static_cast<KX_BlenderMaterial*>(self_v); 00840 return PyLong_FromSsize_t(self->GetMaterialIndex()); 00841 } 00842 00843 PyObject* KX_BlenderMaterial::pyattr_get_blending(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) 00844 { 00845 KX_BlenderMaterial* self= static_cast<KX_BlenderMaterial*>(self_v); 00846 unsigned int* bfunc = self->getBlendFunc(); 00847 return Py_BuildValue("(ll)", (long int)bfunc[0], (long int)bfunc[1]); 00848 } 00849 00850 int KX_BlenderMaterial::pyattr_set_blending(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) 00851 { 00852 KX_BlenderMaterial* self= static_cast<KX_BlenderMaterial*>(self_v); 00853 PyObject* obj = self->PysetBlending(value, NULL); 00854 if(obj) 00855 { 00856 Py_DECREF(obj); 00857 return 0; 00858 } 00859 return -1; 00860 } 00861 00862 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") 00863 { 00864 if( !GLEW_ARB_fragment_shader) { 00865 if(!mModified) 00866 spit("Fragment shaders not supported"); 00867 00868 mModified = true; 00869 Py_RETURN_NONE; 00870 } 00871 00872 if( !GLEW_ARB_vertex_shader) { 00873 if(!mModified) 00874 spit("Vertex shaders not supported"); 00875 00876 mModified = true; 00877 Py_RETURN_NONE; 00878 } 00879 00880 if(!GLEW_ARB_shader_objects) { 00881 if(!mModified) 00882 spit("GLSL not supported"); 00883 mModified = true; 00884 Py_RETURN_NONE; 00885 } 00886 else { 00887 // returns Py_None on error 00888 // the calling script will need to check 00889 00890 if(!mShader && !mModified) { 00891 mShader = new BL_Shader(); 00892 mModified = true; 00893 } 00894 00895 if(mShader && !mShader->GetError()) { 00896 m_flag &= ~RAS_BLENDERGLSL; 00897 mMaterial->SetSharedMaterial(true); 00898 mScene->GetBucketManager()->ReleaseDisplayLists(this); 00899 return mShader->GetProxy(); 00900 }else 00901 { 00902 // decref all references to the object 00903 // then delete it! 00904 // We will then go back to fixed functionality 00905 // for this material 00906 if(mShader) { 00907 delete mShader; /* will handle python de-referencing */ 00908 mShader=0; 00909 } 00910 } 00911 Py_RETURN_NONE; 00912 } 00913 PyErr_SetString(PyExc_ValueError, "material.getShader(): KX_BlenderMaterial, GLSL Error"); 00914 return NULL; 00915 } 00916 00917 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") 00918 { 00919 return PyLong_FromSsize_t( GetMaterialIndex() ); 00920 } 00921 00922 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" ) 00923 { 00924 // TODO: enable python switching 00925 return NULL; 00926 } 00927 00928 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)") 00929 { 00930 // TODO: enable python switching 00931 return NULL; 00932 } 00933 00934 static unsigned int GL_array[11] = { 00935 GL_ZERO, 00936 GL_ONE, 00937 GL_SRC_COLOR, 00938 GL_ONE_MINUS_SRC_COLOR, 00939 GL_DST_COLOR, 00940 GL_ONE_MINUS_DST_COLOR, 00941 GL_SRC_ALPHA, 00942 GL_ONE_MINUS_SRC_ALPHA, 00943 GL_DST_ALPHA, 00944 GL_ONE_MINUS_DST_ALPHA, 00945 GL_SRC_ALPHA_SATURATE 00946 }; 00947 00948 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( bge.logic.src, bge.logic.dest)") 00949 { 00950 unsigned int b[2]; 00951 if(PyArg_ParseTuple(args, "ii:setBlending", &b[0], &b[1])) 00952 { 00953 bool value_found[2] = {false, false}; 00954 for(int i=0; i<11; i++) 00955 { 00956 if(b[0] == GL_array[i]) { 00957 value_found[0] = true; 00958 mBlendFunc[0] = b[0]; 00959 } 00960 if(b[1] == GL_array[i]) { 00961 value_found[1] = true; 00962 mBlendFunc[1] = b[1]; 00963 } 00964 if(value_found[0] && value_found[1]) break; 00965 } 00966 if(!value_found[0] || !value_found[1]) { 00967 PyErr_SetString(PyExc_ValueError, "material.setBlending(int, int): KX_BlenderMaterial, invalid enum."); 00968 return NULL; 00969 } 00970 mUserDefBlend = true; 00971 Py_RETURN_NONE; 00972 } 00973 return NULL; 00974 } 00975 00976 #endif // WITH_PYTHON