Game Development Community

dev|Pro Game Development Curriculum

Shader deletion for TSE GFX

by Josh Moore · 08/17/2006 (12:18 pm) · 9 comments

This resource is now in TSE HEAD.


This enhancement adds the ability to destroy custom shaders to the GFX layer. I couldn't find any current method of deleting or reloading a GFXShader, so I tossed this stuff together. If you're wondering why this is usefull, don't bother reading any further.

gfxDevice.h

Locate:
virtual GFXShader * createShader( GFXShaderFeatureData &featureData, GFXVertexFlags vertFlags ) = 0;

Add:
//*****
	// Added - JM
	virtual void destroyShader(GFXShader* shader) {}
	//*****


gfxD3DDevice.h

Locate:
virtual GFXShader * createShader( GFXShaderFeatureData &featureData, GFXVertexFlags vertFlags );

Add:
//*****
	// Added - JM
	virtual void destroyShader(GFXShader* shader);
	//*****


gfxD3DDevice.cpp

Locate:
GFXShader * GFXD3DDevice::createShader(.......
........
........
}

Add:
//-----------------------------------------------------------------------------
//*****
// Added - JM
void GFXD3DDevice::destroyShader(GFXShader* shader)
{
	mShaderMgr.destroyShader(shader);
}
//*****


gfxShaderMgr.h

Locate:
virtual GFXShader * getShader( GFXShaderFeatureData &dat,
                                  GFXVertexFlags ) = 0;

Add:
//*****
	// Added - JM
	virtual void destroyShader(GFXShader* shader);
	//*****


gfxShaderMgr.cpp

Add to the end of file:
//----------------------------------------------------------------------------
// Destroy shader - JM
//----------------------------------------------------------------------------

void GFXShaderMgr::destroyShader(GFXShader* shader)
{
	if(!shader || mCustShaders.empty()) return;

	for(U32 i = 0; i < mCustShaders.size(); i++) {
		if(mCustShaders[ i ] == shader) {
			mCustShaders.erase(i);
			break;
		}
	}

	delete shader;
}




So what is the use for this functionality with the current state of TSE?
I wanted it for in-game shader (re)loading, which I'm also going to share:


shaderData.h

Locate:
bool initShader();

Add:
//*****
	// Added - JM
	bool reloadShader();
	void destroyShader();
	//*****


shaderData.cpp

Add this include:
#include "gfx/gfxShaderMgr.h"

Add all this to the end of the file:
//--------------------------------------------------------------------------
// Reload shader - JM
//--------------------------------------------------------------------------

bool ShaderData::reloadShader()
{
	if(!shader) return false;

	GFX->destroyShader(shader);
	shader = NULL;

	// get shader type from GFX layer
	switch(GFX->getAdapterType()) {
      case Direct3D9: {
			shader = GFX->createShader((char*)DXVertexShaderName, 
												(char*)DXPixelShaderName, 
												pixVersion);
			break;
		}
		default:
			return false;
	}

	return true;
}

//--------------------------------------------------------------------------
// Destroy shader - JM
//--------------------------------------------------------------------------

void ShaderData::destroyShader()
{
	if(!shader) return;

	GFX->destroyShader(shader);
	shader = NULL;

	return;
}

//*****
// Added - JM
ConsoleMethod(ShaderData, reload, bool, 2, 2, "Rebuilds both the vertex and pixel shaders.")
{
	return object->reloadShader();
}
//*****


Now you can compile a ShaderData object while in-game by simply typing MyShaderData.reload(); into the console.

#1
07/21/2006 (8:54 am)
nice josh.. thanx
#2
08/17/2006 (1:29 pm)
Very useful! Thanks
#3
08/18/2006 (1:48 pm)
Quote:If you're wondering why this is usefull, don't bother reading any further.
A true classic!
#4
08/19/2006 (11:41 am)
Will this let you hot swap materials?
#5
08/21/2006 (7:32 pm)
No, this has nothing todo with materials.
#6
08/23/2006 (4:15 pm)
Ok sorry. Just thought if you had a material being rendered with a shader and you changed the shader it would do something. I'll research it more sorry little rusty on TSE.
#7
08/24/2006 (11:09 pm)
Just to clarify, the first part of this resource simply adds the ability to delete GFXShaders to the GFX layer, while the second part allows for run-time shader reloading via script or C++.

So reloading a shader used by a CustomMaterial should work just fine.
#8
09/02/2006 (4:00 am)
Thanks Josh - damn useful
#9
09/12/2006 (12:29 am)
Excellent, thanks Josh. This will come in handy.

-Jase