Here's a patch that should take care of that. No one commit this to the community branch until its been tested thoroughly. You can also see some of the stuff for AlphaTest and Alpha to Coverage in there, ignore it (you'd also be in for a surprise if you did, should you scrutinize the if tests). It's untested and doesn't do anything unless you add the necessary code to the egRenderer.cpp in setMaterialRec.
It works using the XML syntax I described previously, instead of the full blown container <Context></Context>. It's only lightly tested, I haven't tried using multiple links or other odd combinations, such as linking to a link (EDIT: Just tested that). It does add the linked file as a resource, therefore it chokes and spits it at the log if it can't find the resource, of course it does not explicitly load the data.
Code:
<Context id="CONTEXTID" link="xxxxx.shader.xml" />
Code:
Index: egShader.cpp
===================================================================
--- egShader.cpp (revision 4)
+++ egShader.cpp (working copy)
@@ -149,7 +149,22 @@
_contexts.clear();
}
+ShaderContext *ShaderResource::getLink(const std::string &name)
+{
+ for(uint32 i = 0; i < _links.size(); ++i)
+ {
+ if(_links[i].contextName == name)
+ {
+ Resource *t = Modules::resMan().findResource(ResourceTypes::Shader, _links[i].shaderResName);
+ if(t)
+ {
+ return (((ShaderResource*)t)->findContext(_links[i].contextName));
+ }
+ }
+ }
+ return 0x0;
+}
bool ShaderResource::raiseError( const string &msg, int line )
{
@@ -232,44 +247,77 @@
{
if( node1.getAttribute( "id" ) == 0x0 ) return raiseError( "Missing Context attribute 'id'" );
- ShaderContext sc;
-
- sc.id = node1.getAttribute( "id" );
-
- // Config
- XMLNode node2 = node1.getChildNode( "RenderConfig" );
- if( !node2.isEmpty() )
+ if( _stricmp(node1.getAttribute( "link", "" ),"") == 0)
{
- if( _stricmp( node2.getAttribute( "writeDepth", "true" ), "false" ) == 0 ||
- _stricmp( node2.getAttribute( "writeDepth", "1" ), "0" ) == 0 )
- sc.writeDepth = false;
- else
- sc.writeDepth = true;
+ ShaderContext sc;
- if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "BLEND" ) == 0 )
- sc.blendMode = BlendModes::Blend;
- else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "ADD" ) == 0 )
- sc.blendMode = BlendModes::Add;
- else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "ADD_BLENDED" ) == 0 )
- sc.blendMode = BlendModes::AddBlended;
- else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "MULT" ) == 0 )
- sc.blendMode = BlendModes::Mult;
- else
- sc.blendMode = BlendModes::Replace;
- }
-
- // Code
- node2 = node1.getChildNode( "VertexShader" );
- if( node2.isEmpty() ) return raiseError( "Missing VertexShader node in Context '" + sc.id + "'" );
- if( !parseCode( node2, sc.vertShaderFracts ) ) return raiseError( "Error in VertexShader node of Context '" + sc.id + "'" );
+ sc.id = node1.getAttribute( "id" );
+
+ // Config
+ XMLNode node2 = node1.getChildNode( "RenderConfig" );
+ if( !node2.isEmpty() )
+ {
+ if( _stricmp( node2.getAttribute( "writeDepth", "true" ), "false" ) == 0 ||
+ _stricmp( node2.getAttribute( "writeDepth", "1" ), "0" ) == 0 )
+ sc.writeDepth = false;
+ else
+ sc.writeDepth = true;
- node2 = node1.getChildNode( "FragmentShader" );
- if( node2.isEmpty() ) return raiseError( "Missing VertexShader node in Context '" + sc.id + "'" );
- if( !parseCode( node2, sc.fragShaderFracts ) ) return raiseError( "Error in FragmentShader node of Context '" + sc.id + "'" );
+ if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "BLEND" ) == 0 )
+ sc.blendMode = BlendModes::Blend;
+ else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "ADD" ) == 0 )
+ sc.blendMode = BlendModes::Add;
+ else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "ADD_BLENDED" ) == 0 )
+ sc.blendMode = BlendModes::AddBlended;
+ else if( _stricmp( node2.getAttribute( "blendMode", "REPLACE" ), "MULT" ) == 0 )
+ sc.blendMode = BlendModes::Mult;
+ else
+ sc.blendMode = BlendModes::Replace;
- _contexts.push_back( sc );
+ //Alpha Depth Test
+ if( _stricmp( node2.getAttribute("alphaTest","false"),"true") == 0 ||
+ _stricmp( node2.getAttribute("alphaTest","0"),"1") == 0)
+ {
+ sc.testAlpha = false;
+ if( _stricmp( node2.getAttribute("alphaToCoverage","false"),"true") == 0 ||
+ _stricmp( node2.getAttribute("alphaToCoverage","0"),"1") == 0)
+ sc.alphaToCoverage = true;
+ else
+ sc.alphaToCoverage = false;
+ }
+ else
+ {
+ sc.testAlpha = true;
+ if( _stricmp( node2.getAttribute("alphaTestMode","greater"),"less") == 0)
+ sc.alphaTestDirection = false;
+ else sc.alphaTestDirection = true;
+ sc.alphaTestVal = (float)atof(node2.getAttribute("alphaTestValue","0"));
+ }
+ }
+
+ // Code
+ node2 = node1.getChildNode( "VertexShader" );
+ if( node2.isEmpty() ) return raiseError( "Missing VertexShader node in Context '" + sc.id + "'" );
+ if( !parseCode( node2, sc.vertShaderFracts ) ) return raiseError( "Error in VertexShader node of Context '" + sc.id + "'" );
+
+ node2 = node1.getChildNode( "FragmentShader" );
+ if( node2.isEmpty() ) return raiseError( "Missing VertexShader node in Context '" + sc.id + "'" );
+ if( !parseCode( node2, sc.fragShaderFracts ) ) return raiseError( "Error in FragmentShader node of Context '" + sc.id + "'" );
+
+ _contexts.push_back( sc );
+
+ node1 = rootNode.getChildNode( "Context", ++nodeItr1 );
+ }
+ else
+ {
+ ShaderLink t;
+ t.contextName = node1.getAttribute("id");
+ t.shaderResName = node1.getAttribute("link");
+ _links.push_back(t);
+ Modules::resMan().addResource(ResourceTypes::Shader,t.shaderResName,0,false);
+ node1 = rootNode.getChildNode("Context",++nodeItr1);
+ }
- node1 = rootNode.getChildNode( "Context", ++nodeItr1 );
}
compileShaders();
Index: egShader.h
===================================================================
--- egShader.h (revision 4)
+++ egShader.h (working copy)
@@ -60,7 +60,11 @@
typedef SmartResPtr< CodeResource > PCodeResource;
-
+struct ShaderLink
+{
+ string contextName;
+ string shaderResName;
+};
struct ShaderCodeFract
{
PCodeResource refCodeRes;
@@ -91,6 +95,12 @@
// RenderConfig
bool writeDepth;
+ bool testAlpha;
+ //true is > false is <
+ bool alphaTestDirection;
+ float alphaTestVal;
+ bool alphaToCoverage;
+
BlendModes::List blendMode;
// Engine uniform and attribute locations
@@ -130,6 +140,7 @@
static string _vertPreamble, _fragPreamble;
vector< ShaderContext > _contexts;
+ vector< ShaderLink > _links;
bool raiseError( const string &msg, int line = -1 );
bool parseCode( XMLNode &node, vector< ShaderCodeFract > &codeFracts );
@@ -150,12 +161,14 @@
bool load( const char *data, int size );
void compileShaders();
+ ShaderContext *getLink( const string &name );
ShaderContext *findContext( const string &name )
{
for( uint32 i = 0; i < _contexts.size(); ++i )
+ {
if( _contexts[i].id == name ) return &_contexts[i];
-
- return 0x0;
+ }
+ return getLink(name);
}
vector< ShaderContext > &getContexts() { return _contexts; }