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