If a mesh doesn't have a material we don't initialize the mSavedData in KX_BlenderMaterial to avoid crash.
		
			
				
	
	
		
			1067 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1067 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * ***** BEGIN GPL 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.
 | 
						|
 *
 | 
						|
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
						|
 *
 | 
						|
 * ***** END GPL LICENSE BLOCK *****
 | 
						|
 */
 | 
						|
 | 
						|
/** \file gameengine/Ketsji/KX_BlenderMaterial.cpp
 | 
						|
 *  \ingroup ketsji
 | 
						|
 */
 | 
						|
 | 
						|
#include "glew-mx.h"
 | 
						|
 | 
						|
#include "KX_BlenderMaterial.h"
 | 
						|
#include "BL_Material.h"
 | 
						|
#include "KX_Scene.h"
 | 
						|
#include "KX_Light.h"
 | 
						|
#include "KX_GameObject.h"
 | 
						|
#include "KX_MeshProxy.h"
 | 
						|
 | 
						|
#include "MT_Vector3.h"
 | 
						|
#include "MT_Vector4.h"
 | 
						|
#include "MT_Matrix4x4.h"
 | 
						|
 | 
						|
#include "RAS_BucketManager.h"
 | 
						|
#include "RAS_MeshObject.h"
 | 
						|
#include "RAS_IRasterizer.h"
 | 
						|
#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
 | 
						|
 | 
						|
#include "GPU_draw.h"
 | 
						|
 | 
						|
#include "STR_HashedString.h"
 | 
						|
 | 
						|
// ------------------------------------
 | 
						|
#include "DNA_object_types.h"
 | 
						|
#include "DNA_material_types.h"
 | 
						|
#include "DNA_image_types.h"
 | 
						|
#include "DNA_meshdata_types.h"
 | 
						|
#include "BKE_mesh.h"
 | 
						|
// ------------------------------------
 | 
						|
#include "BLI_utildefines.h"
 | 
						|
 | 
						|
#define spit(x) std::cout << x << std::endl;
 | 
						|
 | 
						|
BL_Shader *KX_BlenderMaterial::mLastShader = NULL;
 | 
						|
BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
 | 
						|
 | 
						|
//static PyObject *gTextureDict = 0;
 | 
						|
 | 
						|
KX_BlenderMaterial::KX_BlenderMaterial()
 | 
						|
:	PyObjectPlus(),
 | 
						|
	RAS_IPolyMaterial(),
 | 
						|
	mMaterial(NULL),
 | 
						|
	mShader(0),
 | 
						|
	mBlenderShader(0),
 | 
						|
	mScene(NULL),
 | 
						|
	mUserDefBlend(0),
 | 
						|
	mModified(0),
 | 
						|
	mConstructed(false),
 | 
						|
	mPass(0)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::Initialize(
 | 
						|
	KX_Scene *scene,
 | 
						|
	BL_Material *data,
 | 
						|
	GameSettings *game,
 | 
						|
	int lightlayer)
 | 
						|
{
 | 
						|
	RAS_IPolyMaterial::Initialize(
 | 
						|
		data->texname[0],
 | 
						|
		data->matname,
 | 
						|
		data->materialindex,
 | 
						|
		data->tile,
 | 
						|
		data->tilexrep[0],
 | 
						|
		data->tileyrep[0],
 | 
						|
		data->alphablend,
 | 
						|
		((data->ras_mode &ALPHA)!=0),
 | 
						|
		((data->ras_mode &ZSORT)!=0),
 | 
						|
		((data->ras_mode &USE_LIGHT)!=0),
 | 
						|
		((data->ras_mode &TEX)),
 | 
						|
		game
 | 
						|
	);
 | 
						|
	Material *ma = data->material;
 | 
						|
 | 
						|
	if (ma) {
 | 
						|
		// Save material data to restore on exit
 | 
						|
		mSavedData.r = ma->r;
 | 
						|
		mSavedData.g = ma->g;
 | 
						|
		mSavedData.b = ma->b;
 | 
						|
		mSavedData.a = ma->alpha;
 | 
						|
		mSavedData.specr = ma->specr;
 | 
						|
		mSavedData.specg = ma->specg;
 | 
						|
		mSavedData.specb = ma->specb;
 | 
						|
		mSavedData.spec = ma->spec;
 | 
						|
		mSavedData.ref = ma->ref;
 | 
						|
		mSavedData.hardness = ma->har;
 | 
						|
		mSavedData.emit = ma->emit;
 | 
						|
	}
 | 
						|
 | 
						|
	mMaterial = data;
 | 
						|
	mShader = 0;
 | 
						|
	mBlenderShader = 0;
 | 
						|
	mScene = scene;
 | 
						|
	mUserDefBlend = 0;
 | 
						|
	mModified = 0;
 | 
						|
	mConstructed = false;
 | 
						|
	mPass = 0;
 | 
						|
	mLightLayer = lightlayer;
 | 
						|
	// --------------------------------
 | 
						|
	// RAS_IPolyMaterial variables...
 | 
						|
	m_flag |= RAS_BLENDERMAT;
 | 
						|
	m_flag |= (mMaterial->IdMode>=ONETEX)? RAS_MULTITEX: 0;
 | 
						|
	m_flag |= ((mMaterial->ras_mode & USE_LIGHT)!=0)? RAS_MULTILIGHT: 0;
 | 
						|
	m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
 | 
						|
	m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
 | 
						|
	m_flag |= ((mMaterial->ras_mode & ONLY_SHADOW)!=0)? RAS_ONLYSHADOW: 0;
 | 
						|
 | 
						|
	// test the sum of the various modes for equality
 | 
						|
	// so we can ether accept or reject this material
 | 
						|
	// as being equal, this is rather important to
 | 
						|
	// prevent material bleeding
 | 
						|
	for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
		m_multimode	+= (mMaterial->flag[i] + mMaterial->blend_mode[i]);
 | 
						|
	}
 | 
						|
	m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
 | 
						|
}
 | 
						|
 | 
						|
KX_BlenderMaterial::~KX_BlenderMaterial()
 | 
						|
{
 | 
						|
	Material *ma = mMaterial->material;
 | 
						|
 | 
						|
	if (ma) {
 | 
						|
		// Restore Blender material data
 | 
						|
		ma->r = mSavedData.r;
 | 
						|
		ma->g = mSavedData.g;
 | 
						|
		ma->b = mSavedData.b;
 | 
						|
		ma->alpha = mSavedData.a;
 | 
						|
		ma->specr = mSavedData.specr;
 | 
						|
		ma->specg = mSavedData.specg;
 | 
						|
		ma->specb = mSavedData.specb;
 | 
						|
		ma->spec = mSavedData.spec;
 | 
						|
		ma->ref = mSavedData.ref;
 | 
						|
		ma->har = mSavedData.hardness;
 | 
						|
		ma->emit = mSavedData.emit;
 | 
						|
	}
 | 
						|
 | 
						|
	// cleanup work
 | 
						|
	if (mConstructed)
 | 
						|
		// clean only if material was actually used
 | 
						|
		OnExit();
 | 
						|
}
 | 
						|
 | 
						|
MTFace* KX_BlenderMaterial::GetMTFace() const
 | 
						|
{
 | 
						|
	// fonts on polys
 | 
						|
	return &mMaterial->tface;
 | 
						|
}
 | 
						|
 | 
						|
unsigned int* KX_BlenderMaterial::GetMCol() const
 | 
						|
{
 | 
						|
	// fonts on polys
 | 
						|
	return mMaterial->rgb;
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
 | 
						|
{
 | 
						|
	if (mMaterial) {
 | 
						|
		*rgba++ = (unsigned char)(mMaterial->matcolor[0] * 255.0f);
 | 
						|
		*rgba++ = (unsigned char)(mMaterial->matcolor[1] * 255.0f);
 | 
						|
		*rgba++ = (unsigned char)(mMaterial->matcolor[2] * 255.0f);
 | 
						|
		*rgba++ = (unsigned char)(mMaterial->matcolor[3] * 255.0f);
 | 
						|
	} else
 | 
						|
		RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
 | 
						|
}
 | 
						|
 | 
						|
Material *KX_BlenderMaterial::GetBlenderMaterial() const
 | 
						|
{
 | 
						|
	return mMaterial->material;
 | 
						|
}
 | 
						|
 | 
						|
Image *KX_BlenderMaterial::GetBlenderImage() const
 | 
						|
{
 | 
						|
	return mMaterial->tface.tpage;
 | 
						|
}
 | 
						|
 | 
						|
Scene* KX_BlenderMaterial::GetBlenderScene() const
 | 
						|
{
 | 
						|
	return mScene->GetBlenderScene();
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::ReleaseMaterial()
 | 
						|
{
 | 
						|
	if (mBlenderShader)
 | 
						|
		mBlenderShader->ReloadMaterial();
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::InitTextures()
 | 
						|
{
 | 
						|
	// for each unique material...
 | 
						|
	int i;
 | 
						|
	for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
		if ( mMaterial->mapping[i].mapping & USEENV ) {
 | 
						|
			if (!GLEW_ARB_texture_cube_map) {
 | 
						|
				spit("CubeMap textures not supported");
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
			if (!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
 | 
						|
				spit("unable to initialize image("<<i<<") in "<<
 | 
						|
				     mMaterial->matname<< ", image will not be available");
 | 
						|
		}
 | 
						|
		/* If we're using glsl materials, the textures are handled by bf_gpu, so don't load them twice!
 | 
						|
		 * However, if we're using a custom shader, then we still need to load the textures ourselves. */
 | 
						|
		else if (!mMaterial->glslmat || mShader) {
 | 
						|
			if ( mMaterial->img[i] ) {
 | 
						|
				if ( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
 | 
						|
					spit("unable to initialize image("<<i<<") in "<< 
 | 
						|
						mMaterial->matname<< ", image will not be available");
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::OnConstruction()
 | 
						|
{
 | 
						|
	if (mConstructed)
 | 
						|
		// when material are reused between objects
 | 
						|
		return;
 | 
						|
	
 | 
						|
	if (mMaterial->glslmat)
 | 
						|
		SetBlenderGLSLShader();
 | 
						|
 | 
						|
	InitTextures();
 | 
						|
 | 
						|
	mBlendFunc[0] =0;
 | 
						|
	mBlendFunc[1] =0;
 | 
						|
	mConstructed = true;
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::EndFrame()
 | 
						|
{
 | 
						|
	if (mLastBlenderShader) {
 | 
						|
		mLastBlenderShader->SetProg(false);
 | 
						|
		mLastBlenderShader = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (mLastShader) {
 | 
						|
		mLastShader->SetProg(false);
 | 
						|
		mLastShader = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::OnExit()
 | 
						|
{
 | 
						|
	if ( mShader ) {
 | 
						|
		//note, the shader here is allocated, per unique material
 | 
						|
		//and this function is called per face
 | 
						|
		if (mShader == mLastShader) {
 | 
						|
			mShader->SetProg(false);
 | 
						|
			mLastShader = NULL;
 | 
						|
		}
 | 
						|
 | 
						|
		delete mShader;
 | 
						|
		mShader = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	if ( mBlenderShader ) {
 | 
						|
		if (mBlenderShader == mLastBlenderShader) {
 | 
						|
			mBlenderShader->SetProg(false);
 | 
						|
			mLastBlenderShader = NULL;
 | 
						|
		}
 | 
						|
 | 
						|
		delete mBlenderShader;
 | 
						|
		mBlenderShader = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	BL_Texture::ActivateFirst();
 | 
						|
	for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
		if (!mTextures[i].Ok()) continue;
 | 
						|
		BL_Texture::ActivateUnit(i);
 | 
						|
		mTextures[i].DeleteTex();
 | 
						|
		mTextures[i].DisableUnit();
 | 
						|
	}
 | 
						|
 | 
						|
	/* used to call with 'mMaterial->tface' but this can be a freed array,
 | 
						|
	 * see: [#30493], so just call with NULL, this is best since it clears
 | 
						|
	 * the 'lastface' pointer in GPU too - campbell */
 | 
						|
	GPU_set_tpage(NULL, 1, mMaterial->alphablend);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
 | 
						|
{
 | 
						|
	MT_assert(GLEW_ARB_shader_objects && mShader);
 | 
						|
 | 
						|
	int i;
 | 
						|
	if ( !enable || !mShader->Ok() ) {
 | 
						|
		// frame cleanup.
 | 
						|
		if (mShader == mLastShader) {
 | 
						|
			mShader->SetProg(false);
 | 
						|
			mLastShader = NULL;
 | 
						|
		}
 | 
						|
 | 
						|
		ras->SetAlphaBlend(TF_SOLID);
 | 
						|
		BL_Texture::DisableAllTextures();
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	BL_Texture::DisableAllTextures();
 | 
						|
	mShader->SetProg(true);
 | 
						|
	mLastShader = mShader;
 | 
						|
	
 | 
						|
	BL_Texture::ActivateFirst();
 | 
						|
 | 
						|
	mShader->ApplyShader();
 | 
						|
 | 
						|
	// for each enabled unit
 | 
						|
	for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
		if (!mTextures[i].Ok()) continue;
 | 
						|
		mTextures[i].ActivateTexture();
 | 
						|
		mTextures[0].SetMapping(mMaterial->mapping[i].mapping);
 | 
						|
	}
 | 
						|
 | 
						|
	if (!mUserDefBlend) {
 | 
						|
		ras->SetAlphaBlend(mMaterial->alphablend);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		ras->SetAlphaBlend(TF_SOLID);
 | 
						|
		ras->SetAlphaBlend(-1); // indicates custom mode
 | 
						|
 | 
						|
		// tested to be valid enums
 | 
						|
		glEnable(GL_BLEND);
 | 
						|
		glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras)
 | 
						|
{
 | 
						|
	if ( !enable || !mBlenderShader->Ok() ) {
 | 
						|
		ras->SetAlphaBlend(TF_SOLID);
 | 
						|
 | 
						|
		// frame cleanup.
 | 
						|
		if (mLastBlenderShader) {
 | 
						|
			mLastBlenderShader->SetProg(false);
 | 
						|
			mLastBlenderShader= NULL;
 | 
						|
		}
 | 
						|
		else
 | 
						|
			BL_Texture::DisableAllTextures();
 | 
						|
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	if (!mBlenderShader->Equals(mLastBlenderShader)) {
 | 
						|
		ras->SetAlphaBlend(mMaterial->alphablend);
 | 
						|
 | 
						|
		if (mLastBlenderShader)
 | 
						|
			mLastBlenderShader->SetProg(false);
 | 
						|
		else
 | 
						|
			BL_Texture::DisableAllTextures();
 | 
						|
 | 
						|
		mBlenderShader->SetProg(true, ras->GetTime(), ras);
 | 
						|
		mLastBlenderShader= mBlenderShader;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
 | 
						|
{
 | 
						|
	BL_Texture::DisableAllTextures();
 | 
						|
 | 
						|
	if ( !enable ) {
 | 
						|
		ras->SetAlphaBlend(TF_SOLID);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	BL_Texture::ActivateFirst();
 | 
						|
 | 
						|
	if ( mMaterial->IdMode == DEFAULT_BLENDER ) {
 | 
						|
		ras->SetAlphaBlend(mMaterial->alphablend);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	if ( mMaterial->IdMode == TEXFACE ) {
 | 
						|
		// no material connected to the object
 | 
						|
		if ( mTextures[0].Ok() ) {
 | 
						|
			mTextures[0].ActivateTexture();
 | 
						|
			mTextures[0].setTexEnv(0, true);
 | 
						|
			mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
 | 
						|
			ras->SetAlphaBlend(mMaterial->alphablend);
 | 
						|
		}
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	int mode = 0,i=0;
 | 
						|
	for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
		if ( !mTextures[i].Ok() ) continue;
 | 
						|
 | 
						|
		mTextures[i].ActivateTexture();
 | 
						|
		mTextures[i].setTexEnv(mMaterial);
 | 
						|
		mode = mMaterial->mapping[i].mapping;
 | 
						|
 | 
						|
		if (mode &USEOBJ)
 | 
						|
			setObjectMatrixData(i, ras);
 | 
						|
		else
 | 
						|
			mTextures[i].SetMapping(mode);
 | 
						|
		
 | 
						|
		if (!(mode &USEOBJ))
 | 
						|
			setTexMatrixData( i );
 | 
						|
	}
 | 
						|
 | 
						|
	if (!mUserDefBlend) {
 | 
						|
		ras->SetAlphaBlend(mMaterial->alphablend);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		ras->SetAlphaBlend(TF_SOLID);
 | 
						|
		ras->SetAlphaBlend(-1); // indicates custom mode
 | 
						|
 | 
						|
		glEnable(GL_BLEND);
 | 
						|
		glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KX_BlenderMaterial::ActivatShaders(
 | 
						|
	RAS_IRasterizer* rasty, 
 | 
						|
	TCachingInfo& cachingInfo)const
 | 
						|
{
 | 
						|
	KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 | 
						|
 | 
						|
	// reset... 
 | 
						|
	if (tmp->mMaterial->IsShared()) 
 | 
						|
		cachingInfo =0;
 | 
						|
 | 
						|
	if (mLastBlenderShader) {
 | 
						|
		mLastBlenderShader->SetProg(false);
 | 
						|
		mLastBlenderShader= NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (GetCachingInfo() != cachingInfo) {
 | 
						|
 | 
						|
		if (!cachingInfo)
 | 
						|
			tmp->setShaderData(false, rasty);
 | 
						|
		
 | 
						|
		cachingInfo = GetCachingInfo();
 | 
						|
	
 | 
						|
		if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
 | 
						|
			tmp->setShaderData(true, rasty);
 | 
						|
		else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && mMaterial->alphablend != GEMAT_SOLID && !rasty->GetUsingOverrideShader())
 | 
						|
			tmp->setShaderData(true, rasty);
 | 
						|
		else
 | 
						|
			tmp->setShaderData(false, rasty);
 | 
						|
 | 
						|
		if (mMaterial->ras_mode &TWOSIDED)
 | 
						|
			rasty->SetCullFace(false);
 | 
						|
		else
 | 
						|
			rasty->SetCullFace(true);
 | 
						|
 | 
						|
		if ((mMaterial->ras_mode &WIRE) ||
 | 
						|
		    (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
 | 
						|
		{
 | 
						|
			if (mMaterial->ras_mode &WIRE) 
 | 
						|
				rasty->SetCullFace(false);
 | 
						|
			rasty->SetLines(true);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			rasty->SetLines(false);
 | 
						|
		ActivatGLMaterials(rasty);
 | 
						|
		ActivateTexGen(rasty);
 | 
						|
	}
 | 
						|
 | 
						|
	//ActivatGLMaterials(rasty);
 | 
						|
	//ActivateTexGen(rasty);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KX_BlenderMaterial::ActivateBlenderShaders(
 | 
						|
	RAS_IRasterizer* rasty, 
 | 
						|
	TCachingInfo& cachingInfo)const
 | 
						|
{
 | 
						|
	KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 | 
						|
 | 
						|
	if (mLastShader) {
 | 
						|
		mLastShader->SetProg(false);
 | 
						|
		mLastShader= NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (GetCachingInfo() != cachingInfo) {
 | 
						|
		if (!cachingInfo)
 | 
						|
			tmp->setBlenderShaderData(false, rasty);
 | 
						|
		
 | 
						|
		cachingInfo = GetCachingInfo();
 | 
						|
	
 | 
						|
		if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
 | 
						|
			tmp->setBlenderShaderData(true, rasty);
 | 
						|
		else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && mMaterial->alphablend != GEMAT_SOLID && !rasty->GetUsingOverrideShader())
 | 
						|
			tmp->setBlenderShaderData(true, rasty);
 | 
						|
		else
 | 
						|
			tmp->setBlenderShaderData(false, rasty);
 | 
						|
 | 
						|
		if (mMaterial->ras_mode &TWOSIDED)
 | 
						|
			rasty->SetCullFace(false);
 | 
						|
		else
 | 
						|
			rasty->SetCullFace(true);
 | 
						|
 | 
						|
		if ((mMaterial->ras_mode &WIRE) ||
 | 
						|
		    (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
 | 
						|
		{
 | 
						|
			if (mMaterial->ras_mode &WIRE) 
 | 
						|
				rasty->SetCullFace(false);
 | 
						|
			rasty->SetLines(true);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			rasty->SetLines(false);
 | 
						|
 | 
						|
		ActivatGLMaterials(rasty);
 | 
						|
		mBlenderShader->SetAttribs(rasty, mMaterial);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KX_BlenderMaterial::ActivateMat( 
 | 
						|
	RAS_IRasterizer* rasty,  
 | 
						|
	TCachingInfo& cachingInfo
 | 
						|
	)const
 | 
						|
{
 | 
						|
	KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
 | 
						|
 | 
						|
	if (mLastShader) {
 | 
						|
		mLastShader->SetProg(false);
 | 
						|
		mLastShader= NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (mLastBlenderShader) {
 | 
						|
		mLastBlenderShader->SetProg(false);
 | 
						|
		mLastBlenderShader= NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (GetCachingInfo() != cachingInfo) {
 | 
						|
		if (!cachingInfo) 
 | 
						|
			tmp->setTexData( false,rasty );
 | 
						|
		
 | 
						|
		cachingInfo = GetCachingInfo();
 | 
						|
 | 
						|
		if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
 | 
						|
			tmp->setTexData( true,rasty  );
 | 
						|
		else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && mMaterial->alphablend != GEMAT_SOLID && !rasty->GetUsingOverrideShader())
 | 
						|
			tmp->setTexData(true, rasty);
 | 
						|
		else
 | 
						|
			tmp->setTexData( false,rasty);
 | 
						|
 | 
						|
		if (mMaterial->ras_mode &TWOSIDED)
 | 
						|
			rasty->SetCullFace(false);
 | 
						|
		else
 | 
						|
			rasty->SetCullFace(true);
 | 
						|
 | 
						|
		if ((mMaterial->ras_mode &WIRE) ||
 | 
						|
		    (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME))
 | 
						|
		{
 | 
						|
			if (mMaterial->ras_mode &WIRE) 
 | 
						|
				rasty->SetCullFace(false);
 | 
						|
			rasty->SetLines(true);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			rasty->SetLines(false);
 | 
						|
		ActivatGLMaterials(rasty);
 | 
						|
		ActivateTexGen(rasty);
 | 
						|
	}
 | 
						|
 | 
						|
	//ActivatGLMaterials(rasty);
 | 
						|
	//ActivateTexGen(rasty);
 | 
						|
}
 | 
						|
 | 
						|
bool 
 | 
						|
KX_BlenderMaterial::Activate( 
 | 
						|
	RAS_IRasterizer* rasty,  
 | 
						|
	TCachingInfo& cachingInfo
 | 
						|
	)const
 | 
						|
{
 | 
						|
	if (GLEW_ARB_shader_objects && (mShader && mShader->Ok())) {
 | 
						|
		if ((mPass++) < mShader->getNumPass() ) {
 | 
						|
			ActivatShaders(rasty, cachingInfo);
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			if (mShader == mLastShader) {
 | 
						|
				mShader->SetProg(false);
 | 
						|
				mLastShader = NULL;
 | 
						|
			}
 | 
						|
			mPass = 0;
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else if ( GLEW_ARB_shader_objects && (mBlenderShader && mBlenderShader->Ok() ) ) {
 | 
						|
		if (mPass++ == 0) {
 | 
						|
			ActivateBlenderShaders(rasty, cachingInfo);
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			mPass = 0;
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		if (mPass++ == 0) {
 | 
						|
			ActivateMat(rasty, cachingInfo);
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			mPass = 0;
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
 | 
						|
{
 | 
						|
	if (!RAS_IPolyMaterial::UsesLighting(rasty))
 | 
						|
		return false;
 | 
						|
 | 
						|
	if (mShader && mShader->Ok())
 | 
						|
		return true;
 | 
						|
	else if (mBlenderShader && mBlenderShader->Ok())
 | 
						|
		return false;
 | 
						|
	else
 | 
						|
		return true;
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty) const
 | 
						|
{
 | 
						|
	if (mShader && GLEW_ARB_shader_objects) {
 | 
						|
		mShader->Update(ms, rasty);
 | 
						|
	}
 | 
						|
	else if (mBlenderShader && GLEW_ARB_shader_objects) {
 | 
						|
		int alphablend;
 | 
						|
 | 
						|
		mBlenderShader->Update(ms, rasty);
 | 
						|
 | 
						|
		/* we do blend modes here, because they can change per object
 | 
						|
		 * with the same material due to obcolor/obalpha */
 | 
						|
		alphablend = mBlenderShader->GetAlphaBlend();
 | 
						|
		if (ELEM(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID)
 | 
						|
			alphablend = mMaterial->alphablend;
 | 
						|
 | 
						|
		rasty->SetAlphaBlend(alphablend);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
 | 
						|
{
 | 
						|
	if (mShader || !mBlenderShader) {
 | 
						|
		rasty->SetSpecularity(
 | 
						|
			mMaterial->speccolor[0]*mMaterial->spec_f,
 | 
						|
			mMaterial->speccolor[1]*mMaterial->spec_f,
 | 
						|
			mMaterial->speccolor[2]*mMaterial->spec_f,
 | 
						|
			mMaterial->spec_f
 | 
						|
		);
 | 
						|
 | 
						|
		rasty->SetShinyness( mMaterial->hard );
 | 
						|
 | 
						|
		rasty->SetDiffuse(
 | 
						|
			mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, 
 | 
						|
			mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit,
 | 
						|
			mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit,
 | 
						|
			1.0f);
 | 
						|
 | 
						|
		rasty->SetEmissive(
 | 
						|
			mMaterial->matcolor[0]*mMaterial->emit,
 | 
						|
			mMaterial->matcolor[1]*mMaterial->emit,
 | 
						|
			mMaterial->matcolor[2]*mMaterial->emit,
 | 
						|
			1.0 );
 | 
						|
 | 
						|
		rasty->SetAmbient(mMaterial->amb);
 | 
						|
	}
 | 
						|
 | 
						|
	if (mMaterial->material)
 | 
						|
		rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
 | 
						|
{
 | 
						|
	if (ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED || 
 | 
						|
		(ras->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && mMaterial->alphablend != GEMAT_SOLID && !ras->GetUsingOverrideShader())) {
 | 
						|
		ras->SetAttribNum(0);
 | 
						|
		if (mShader && GLEW_ARB_shader_objects) {
 | 
						|
			if (mShader->GetAttribute() == BL_Shader::SHD_TANGENT) {
 | 
						|
				ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0);
 | 
						|
				ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1);
 | 
						|
				ras->SetAttribNum(2);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		ras->SetTexCoordNum(mMaterial->num_enabled);
 | 
						|
 | 
						|
		for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
 | 
						|
			int mode = mMaterial->mapping[i].mapping;
 | 
						|
 | 
						|
			if ( mode &(USEREFL|USEOBJ))
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
 | 
						|
			else if (mode &USEORCO)
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_ORCO, i);
 | 
						|
			else if (mode &USENORM)
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
 | 
						|
			else if (mode &USEUV)
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
 | 
						|
			else if (mode &USETANG)
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
 | 
						|
			else 
 | 
						|
				ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::setTexMatrixData(int i)
 | 
						|
{
 | 
						|
	glMatrixMode(GL_TEXTURE);
 | 
						|
	glLoadIdentity();
 | 
						|
 | 
						|
	if ( GLEW_ARB_texture_cube_map && 
 | 
						|
		mTextures[i].GetTextureType() == GL_TEXTURE_CUBE_MAP_ARB && 
 | 
						|
		mMaterial->mapping[i].mapping & USEREFL) {
 | 
						|
		glScalef( 
 | 
						|
			mMaterial->mapping[i].scale[0], 
 | 
						|
			-mMaterial->mapping[i].scale[1], 
 | 
						|
			-mMaterial->mapping[i].scale[2]
 | 
						|
		);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		glScalef( 
 | 
						|
			mMaterial->mapping[i].scale[0], 
 | 
						|
			mMaterial->mapping[i].scale[1], 
 | 
						|
			mMaterial->mapping[i].scale[2]
 | 
						|
		);
 | 
						|
	}
 | 
						|
	glTranslatef(
 | 
						|
		mMaterial->mapping[i].offsets[0],
 | 
						|
		mMaterial->mapping[i].offsets[1], 
 | 
						|
		mMaterial->mapping[i].offsets[2]
 | 
						|
	);
 | 
						|
 | 
						|
	glMatrixMode(GL_MODELVIEW);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void GetProjPlane(BL_Material *mat, int index,int num, float*param)
 | 
						|
{
 | 
						|
	param[0]=param[1]=param[2]=param[3]=0.f;
 | 
						|
	if ( mat->mapping[index].projplane[num] == PROJX )
 | 
						|
		param[0] = 1.f;
 | 
						|
	else if ( mat->mapping[index].projplane[num] == PROJY )
 | 
						|
		param[1] = 1.f;
 | 
						|
	else if ( mat->mapping[index].projplane[num] == PROJZ)
 | 
						|
		param[2] = 1.f;
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras)
 | 
						|
{
 | 
						|
	KX_GameObject *obj = 
 | 
						|
		(KX_GameObject*)
 | 
						|
		mScene->GetObjectList()->FindValue(mMaterial->mapping[i].objconame);
 | 
						|
 | 
						|
	if (!obj) return;
 | 
						|
 | 
						|
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
 | 
						|
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
 | 
						|
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
 | 
						|
 | 
						|
	GLenum plane = GL_EYE_PLANE;
 | 
						|
 | 
						|
	// figure plane gen
 | 
						|
	float proj[4] = {0.f,0.f,0.f,0.f};
 | 
						|
	GetProjPlane(mMaterial, i, 0, proj);
 | 
						|
	glTexGenfv(GL_S, plane, proj);
 | 
						|
	
 | 
						|
	GetProjPlane(mMaterial, i, 1, proj);
 | 
						|
	glTexGenfv(GL_T, plane, proj);
 | 
						|
 | 
						|
	GetProjPlane(mMaterial, i, 2, proj);
 | 
						|
	glTexGenfv(GL_R, plane, proj);
 | 
						|
 | 
						|
	glEnable(GL_TEXTURE_GEN_S);
 | 
						|
	glEnable(GL_TEXTURE_GEN_T);
 | 
						|
	glEnable(GL_TEXTURE_GEN_R);
 | 
						|
 | 
						|
	const MT_Matrix4x4& mvmat = ras->GetViewMatrix();
 | 
						|
 | 
						|
	glMatrixMode(GL_TEXTURE);
 | 
						|
	glLoadIdentity();
 | 
						|
	glScalef( 
 | 
						|
		mMaterial->mapping[i].scale[0], 
 | 
						|
		mMaterial->mapping[i].scale[1], 
 | 
						|
		mMaterial->mapping[i].scale[2]
 | 
						|
	);
 | 
						|
 | 
						|
	MT_Point3 pos = obj->NodeGetWorldPosition();
 | 
						|
	MT_Vector4 matmul = MT_Vector4(pos[0], pos[1], pos[2], 1.f);
 | 
						|
	MT_Vector4 t = mvmat*matmul;
 | 
						|
 | 
						|
	glTranslatef( (float)(-t[0]), (float)(-t[1]), (float)(-t[2]) );
 | 
						|
 | 
						|
	glMatrixMode(GL_MODELVIEW);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// ------------------------------------
 | 
						|
void KX_BlenderMaterial::UpdateIPO(
 | 
						|
	MT_Vector4 rgba,
 | 
						|
	MT_Vector3 specrgb,
 | 
						|
	MT_Scalar hard,
 | 
						|
	MT_Scalar spec,
 | 
						|
	MT_Scalar ref,
 | 
						|
	MT_Scalar emit,
 | 
						|
	MT_Scalar alpha
 | 
						|
	)
 | 
						|
{
 | 
						|
	// only works one deep now
 | 
						|
 | 
						|
	//	Multitexture				Input
 | 
						|
	mMaterial->speccolor[0]	= (float)(specrgb)[0];
 | 
						|
	mMaterial->speccolor[1]	= (float)(specrgb)[1];
 | 
						|
	mMaterial->speccolor[2]	= (float)(specrgb)[2];
 | 
						|
	mMaterial->matcolor[0]	= (float)(rgba[0]);
 | 
						|
	mMaterial->matcolor[1]	= (float)(rgba[1]);
 | 
						|
	mMaterial->matcolor[2]	= (float)(rgba[2]);
 | 
						|
	mMaterial->alpha			= (float)(rgba[3]);
 | 
						|
	mMaterial->hard			= (float)(hard);
 | 
						|
	mMaterial->emit			= (float)(emit);
 | 
						|
	mMaterial->spec_f			= (float)(spec);
 | 
						|
	mMaterial->ref			= (float)(ref);
 | 
						|
 | 
						|
	Material *ma = mMaterial->material;
 | 
						|
	if (ma) {
 | 
						|
		// GLSL				Input
 | 
						|
		ma->specr	= (float)(specrgb)[0];
 | 
						|
		ma->specg	= (float)(specrgb)[1];
 | 
						|
		ma->specb	= (float)(specrgb)[2];
 | 
						|
		ma->r		= (float)(rgba[0]);
 | 
						|
		ma->g		= (float)(rgba[1]);
 | 
						|
		ma->b		= (float)(rgba[2]);
 | 
						|
		ma->alpha	= (float)(rgba[3]);
 | 
						|
		ma->har		= (float)(hard);
 | 
						|
		ma->emit	= (float)(emit);
 | 
						|
		ma->spec	= (float)(spec);
 | 
						|
		ma->ref		= (float)(ref);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
 | 
						|
{
 | 
						|
	mScene= static_cast<KX_Scene *>(val);
 | 
						|
 | 
						|
	OnConstruction();
 | 
						|
}
 | 
						|
 | 
						|
void KX_BlenderMaterial::SetBlenderGLSLShader()
 | 
						|
{
 | 
						|
	if (!mBlenderShader)
 | 
						|
		mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer);
 | 
						|
 | 
						|
	if (!mBlenderShader->Ok()) {
 | 
						|
		delete mBlenderShader;
 | 
						|
		mBlenderShader = 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#ifdef WITH_PYTHON
 | 
						|
 | 
						|
PyMethodDef KX_BlenderMaterial::Methods[] = 
 | 
						|
{
 | 
						|
	KX_PYMETHODTABLE( KX_BlenderMaterial, getShader ),
 | 
						|
	KX_PYMETHODTABLE( KX_BlenderMaterial, getMaterialIndex ),
 | 
						|
	KX_PYMETHODTABLE( KX_BlenderMaterial, setBlending ),
 | 
						|
	{NULL,NULL} //Sentinel
 | 
						|
};
 | 
						|
 | 
						|
PyAttributeDef KX_BlenderMaterial::Attributes[] = {
 | 
						|
	KX_PYATTRIBUTE_RO_FUNCTION("shader", KX_BlenderMaterial, pyattr_get_shader),
 | 
						|
	KX_PYATTRIBUTE_RO_FUNCTION("material_index", KX_BlenderMaterial, pyattr_get_materialIndex),
 | 
						|
	KX_PYATTRIBUTE_RW_FUNCTION("blending", KX_BlenderMaterial, pyattr_get_blending, pyattr_set_blending),
 | 
						|
	{ NULL }	//Sentinel
 | 
						|
};
 | 
						|
 | 
						|
PyTypeObject KX_BlenderMaterial::Type = {
 | 
						|
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
						|
	"KX_BlenderMaterial",
 | 
						|
	sizeof(PyObjectPlus_Proxy),
 | 
						|
	0,
 | 
						|
	py_base_dealloc,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	py_base_repr,
 | 
						|
	0,0,0,0,0,0,0,0,0,
 | 
						|
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 | 
						|
	0,0,0,0,0,0,0,
 | 
						|
	Methods,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	&PyObjectPlus::Type,
 | 
						|
	0,0,0,0,0,0,
 | 
						|
	py_base_new
 | 
						|
};
 | 
						|
 | 
						|
PyObject *KX_BlenderMaterial::pyattr_get_shader(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 | 
						|
{
 | 
						|
	KX_BlenderMaterial* self = static_cast<KX_BlenderMaterial*>(self_v);
 | 
						|
	return self->PygetShader(NULL, NULL);
 | 
						|
}
 | 
						|
 | 
						|
PyObject *KX_BlenderMaterial::pyattr_get_materialIndex(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 | 
						|
{
 | 
						|
	KX_BlenderMaterial* self = static_cast<KX_BlenderMaterial*>(self_v);
 | 
						|
	return PyLong_FromLong(self->GetMaterialIndex());
 | 
						|
}
 | 
						|
 | 
						|
PyObject *KX_BlenderMaterial::pyattr_get_blending(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 | 
						|
{
 | 
						|
	KX_BlenderMaterial* self = static_cast<KX_BlenderMaterial*>(self_v);
 | 
						|
	unsigned int* bfunc = self->getBlendFunc();
 | 
						|
	return Py_BuildValue("(ll)", (long int)bfunc[0], (long int)bfunc[1]);
 | 
						|
}
 | 
						|
 | 
						|
int KX_BlenderMaterial::pyattr_set_blending(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 | 
						|
{
 | 
						|
	KX_BlenderMaterial* self = static_cast<KX_BlenderMaterial*>(self_v);
 | 
						|
	PyObject *obj = self->PysetBlending(value, NULL);
 | 
						|
	if (obj)
 | 
						|
	{
 | 
						|
		Py_DECREF(obj);
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	return -1;
 | 
						|
}
 | 
						|
 | 
						|
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
 | 
						|
{
 | 
						|
	if ( !GLEW_ARB_fragment_shader) {
 | 
						|
		if (!mModified)
 | 
						|
			spit("Fragment shaders not supported");
 | 
						|
	
 | 
						|
		mModified = true;
 | 
						|
		Py_RETURN_NONE;
 | 
						|
	}
 | 
						|
 | 
						|
	if ( !GLEW_ARB_vertex_shader) {
 | 
						|
		if (!mModified)
 | 
						|
			spit("Vertex shaders not supported");
 | 
						|
 | 
						|
		mModified = true;
 | 
						|
		Py_RETURN_NONE;
 | 
						|
	}
 | 
						|
 | 
						|
	if (!GLEW_ARB_shader_objects) {
 | 
						|
		if (!mModified)
 | 
						|
			spit("GLSL not supported");
 | 
						|
		mModified = true;
 | 
						|
		Py_RETURN_NONE;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		// returns Py_None on error
 | 
						|
		// the calling script will need to check
 | 
						|
 | 
						|
		if (!mShader && !mModified) {
 | 
						|
			mShader = new BL_Shader();
 | 
						|
			mModified = true;
 | 
						|
 | 
						|
			// Using a custom shader, make sure to initialize textures
 | 
						|
			InitTextures();
 | 
						|
		}
 | 
						|
 | 
						|
		if (mShader && !mShader->GetError()) {
 | 
						|
			m_flag &= ~RAS_BLENDERGLSL;
 | 
						|
			mMaterial->SetSharedMaterial(true);
 | 
						|
			mScene->GetBucketManager()->ReleaseDisplayLists(this);
 | 
						|
			return mShader->GetProxy();
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			// decref all references to the object
 | 
						|
			// then delete it!
 | 
						|
			// We will then go back to fixed functionality
 | 
						|
			// for this material
 | 
						|
			if (mShader) {
 | 
						|
				delete mShader; /* will handle python de-referencing */
 | 
						|
				mShader=0;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		Py_RETURN_NONE;
 | 
						|
	}
 | 
						|
	PyErr_SetString(PyExc_ValueError, "material.getShader(): KX_BlenderMaterial, GLSL Error");
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
 | 
						|
{
 | 
						|
	return PyLong_FromLong(GetMaterialIndex());
 | 
						|
}
 | 
						|
 | 
						|
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
 | 
						|
{
 | 
						|
	// TODO: enable python switching
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)")
 | 
						|
{
 | 
						|
	// TODO: enable python switching
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static const unsigned int GL_array[11] = {
 | 
						|
	GL_ZERO,
 | 
						|
	GL_ONE,
 | 
						|
	GL_SRC_COLOR,
 | 
						|
	GL_ONE_MINUS_SRC_COLOR,
 | 
						|
	GL_DST_COLOR,
 | 
						|
	GL_ONE_MINUS_DST_COLOR,
 | 
						|
	GL_SRC_ALPHA,
 | 
						|
	GL_ONE_MINUS_SRC_ALPHA,
 | 
						|
	GL_DST_ALPHA,
 | 
						|
	GL_ONE_MINUS_DST_ALPHA,
 | 
						|
	GL_SRC_ALPHA_SATURATE
 | 
						|
};
 | 
						|
 | 
						|
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( bge.logic.src, bge.logic.dest)")
 | 
						|
{
 | 
						|
	unsigned int b[2];
 | 
						|
	if (PyArg_ParseTuple(args, "ii:setBlending", &b[0], &b[1]))
 | 
						|
	{
 | 
						|
		bool value_found[2] = {false, false};
 | 
						|
		for (int i=0; i<11; i++)
 | 
						|
		{
 | 
						|
			if (b[0] == GL_array[i]) {
 | 
						|
				value_found[0] = true;
 | 
						|
				mBlendFunc[0] = b[0];
 | 
						|
			}
 | 
						|
			if (b[1] == GL_array[i]) {
 | 
						|
				value_found[1] = true;
 | 
						|
				mBlendFunc[1] = b[1];
 | 
						|
			}
 | 
						|
			if (value_found[0] && value_found[1]) break;
 | 
						|
		}
 | 
						|
		if (!value_found[0] || !value_found[1]) {
 | 
						|
			PyErr_SetString(PyExc_ValueError, "material.setBlending(int, int): KX_BlenderMaterial, invalid enum.");
 | 
						|
			return NULL;
 | 
						|
		}
 | 
						|
		mUserDefBlend = true;
 | 
						|
		Py_RETURN_NONE;
 | 
						|
	}
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
#endif // WITH_PYTHON
 |