Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

View file

@ -0,0 +1,448 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/bumpGLSL.h"
#include "shaderGen/shaderOp.h"
#include "gfx/gfxDevice.h"
#include "materials/matInstance.h"
#include "materials/processedMaterial.h"
#include "materials/materialFeatureTypes.h"
#include "shaderGen/shaderGenVars.h"
void BumpFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
const bool useTexAnim = fd.features[MFT_TexAnim];
// Output the texture coord.
getOutTexCoord( "texCoord",
"vec2",
true,
useTexAnim,
meta,
componentList );
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
addOutDetailTexCoord( componentList,
meta,
useTexAnim );
// Also output the worldToTanget transform which
// we use to create the world space normal.
getOutWorldToTangent( componentList, meta, fd );
}
void BumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// Get the texture coord.
Var *texCoord = getInTexCoord( "out_texCoord", "vec2", true, componentList );
// Sample the bumpmap.
Var *bumpMap = getNormalMapTex();
LangElement *texOp = NULL;
//Handle atlased textures
if(fd.features[MFT_NormalMapAtlas])
{
// This is a big block of code, so put a comment in the shader code
meta->addStatement( new GenOp( " // Atlased texture coordinate calculation (see BumpFeat*LSL for details)\r\n") );
Var *atlasedTex = new Var;
atlasedTex->setName("atlasedBumpCoord");
atlasedTex->setType("vec2");
LangElement *atDecl = new DecOp(atlasedTex);
// Parameters of the texture atlas
Var *atParams = new Var;
atParams->setType("vec4");
atParams->setName("bumpAtlasParams");
atParams->uniform = true;
atParams->constSortPos = cspPotentialPrimitive;
// Parameters of the texture (tile) this object is using in the atlas
Var *tileParams = new Var;
tileParams->setType("vec4");
tileParams->setName("bumpAtlasTileParams");
tileParams->uniform = true;
tileParams->constSortPos = cspPotentialPrimitive;
const bool is_sm3 = (GFX->getPixelShaderVersion() > 2.0f);
// getPixelShaderVersion() on Mac currently returns 2.0,
// or 3.0 if Advanced Lighting is enabled
if(is_sm3)
{
// Figure out the mip level
meta->addStatement(new GenOp(" vec2 _dx_bump = dFdx(@ * @.z);\r\n", texCoord, atParams));
meta->addStatement(new GenOp(" vec2 _dy_bump = dFdy(@ * @.z);\r\n", texCoord, atParams));
meta->addStatement(new GenOp(" float mipLod_bump = 0.5 * log2(max(dot(_dx_bump, _dx_bump), dot(_dy_bump, _dy_bump)));\r\n"));
meta->addStatement(new GenOp(" mipLod_bump = clamp(mipLod_bump, 0.0, @.w);\r\n", atParams));
// And the size of the mip level
meta->addStatement(new GenOp(" float mipPixSz_bump = pow(2.0, @.w - mipLod_bump);\r\n", atParams));
meta->addStatement(new GenOp(" vec2 mipSz_bump = mipPixSz_bump / @.xy;\r\n", atParams));
}
else
{
meta->addStatement(new GenOp(" vec2 mipSz = float2(1.0, 1.0);\r\n"));
}
// Tiling mode
// TODO: Select wrap or clamp somehow
if( true ) // Wrap
meta->addStatement(new GenOp(" @ = fract(@);\r\n", atDecl, texCoord));
else // Clamp
meta->addStatement(new GenOp(" @ = saturate(@);\r\n", atDecl, texCoord));
// Finally scale/offset, and correct for filtering
meta->addStatement(new GenOp(" @ = @ * ((mipSz_bump * @.xy - 1.0) / mipSz_bump) + 0.5 / mipSz_bump + @.xy * @.xy;\r\n",
atlasedTex, atlasedTex, atParams, atParams, tileParams));
// Add a newline
meta->addStatement(new GenOp( "\r\n"));
if(is_sm3)
{
texOp = new GenOp( "texture2DLod(@, vec4(@, 0.0, mipLod_bump)", bumpMap, texCoord );
}
else
{
texOp = new GenOp( "texture2D(@, @)", bumpMap, texCoord );
}
}
else
{
texOp = new GenOp( "texture2D(@, @)", bumpMap, texCoord );
}
Var *bumpNorm = new Var( "bumpNormal", "vec4" );
meta->addStatement( expandNormalMap( texOp, new DecOp( bumpNorm ), bumpNorm, fd ) );
// If we have a detail normal map we add the xy coords of
// it to the base normal map. This gives us the effect we
// want with few instructions and minial artifacts.
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
{
bumpMap = new Var;
bumpMap->setType( "sampler2D" );
bumpMap->setName( "detailBumpMap" );
bumpMap->uniform = true;
bumpMap->sampler = true;
bumpMap->constNum = Var::getTexUnitNum();
texCoord = getInTexCoord( "detCoord", "vec2", true, componentList );
texOp = new GenOp( "texture2D(@, @)", bumpMap, texCoord );
Var *detailBump = new Var;
detailBump->setName( "detailBump" );
detailBump->setType( "vec4" );
meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
Var *detailBumpScale = new Var;
detailBumpScale->setType( "float" );
detailBumpScale->setName( "detailBumpStrength" );
detailBumpScale->uniform = true;
detailBumpScale->constSortPos = cspPass;
meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpNorm, detailBump, detailBumpScale ) );
}
// We transform it into world space by reversing the
// multiplication by the worldToTanget transform.
Var *wsNormal = new Var( "wsNormal", "vec3" );
Var *worldToTanget = getInWorldToTangent( componentList );
meta->addStatement( new GenOp( " @ = normalize( vec3( @.xyz * @ ) );\r\n", new DecOp( wsNormal ), bumpNorm, worldToTanget ) );
}
ShaderFeature::Resources BumpFeatGLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
// If we have no parallax then we bring on the normal tex.
if ( !fd.features[MFT_Parallax] )
res.numTex = 1;
// Only the parallax or diffuse map will add texture
// coords other than us.
if ( !fd.features[MFT_Parallax] &&
!fd.features[MFT_DiffuseMap] &&
!fd.features[MFT_OverlayMap] &&
!fd.features[MFT_DetailMap] )
res.numTexReg++;
// We pass the world to tanget space transform.
res.numTexReg += 3;
// Do we have detail normal mapping?
if ( fd.features[MFT_DetailNormalMap] )
{
res.numTex++;
if ( !fd.features[MFT_DetailMap] )
res.numTexReg++;
}
return res;
}
void BumpFeatGLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
// If we had a parallax feature then it takes
// care of hooking up the normal map texture.
if ( fd.features[MFT_Parallax] )
return;
if ( fd.features[MFT_NormalMap] )
{
passData.mTexType[ texIndex ] = Material::Bump;
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
}
if ( fd.features[ MFT_DetailNormalMap ] )
{
passData.mTexType[ texIndex ] = Material::DetailBump;
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
}
}
//
Var* ParallaxFeatGLSL::_getUniformVar( const char *name, const char *type )
{
Var *theVar = (Var*)LangElement::find( name );
if ( !theVar )
{
theVar = new Var;
theVar->setType( type );
theVar->setName( name );
theVar->uniform = true;
theVar->constSortPos = cspPass;
}
return theVar;
}
void ParallaxFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatGLSL::processVert - We don't support SM 1.x!" );
MultiLine *meta = new MultiLine;
// Add the texture coords.
getOutTexCoord( "texCoord",
"vec2",
true,
fd.features[MFT_TexAnim],
meta,
componentList );
// Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
// Get the object space eye position and the world
// to tangent transform.
Var *eyePos = _getUniformVar( "eyePos", "vec3" );
Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
// send transform to pixel shader
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outViewTS = connectComp->getElement( RT_TEXCOORD, 1 );
outViewTS->setName( "outViewTS" );
outViewTS->setType( "vec3" );
meta->addStatement( new GenOp( " @ = ( @ - @.xyz ) * transpose( @ );\r\n",
outViewTS, inPos, eyePos, objToTangentSpace ) );
output = meta;
}
void ParallaxFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatGLSL::processPix - We don't support SM 1.x!" );
MultiLine *meta = new MultiLine;
// Order matters... get this first!
Var *texCoord = getInTexCoord( "texCoord", "vec2", true, componentList );
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS )
{
Var *inViewTS = (Var*)LangElement::find( "outViewTS" );
if ( !inViewTS )
{
inViewTS = connectComp->getElement( RT_TEXCOORD, 1 );
inViewTS->setName( "outViewTS" );
inViewTS->setType( "vec3" );
}
negViewTS = new Var( "negViewTS", "vec3" );
meta->addStatement( new GenOp( " @ = -normalize( @ );\r\n", new DecOp( negViewTS ), inViewTS ) );
}
// Get the rest of our inputs.
Var *parallaxInfo = _getUniformVar( "parallaxInfo", "float" );
Var *normalMap = getNormalMapTex();
// Do 3 parallax samples to get acceptable
// quality without too much overhead.
Var *pdepth = findOrCreateLocal( "pdepth", "float", meta );
Var *poffset = findOrCreateLocal( "poffset", "vec2", meta );
meta->addStatement( new GenOp( " @ = texture2D( @, @.xy ).a;\r\n", pdepth, normalMap, texCoord ) );
meta->addStatement( new GenOp( " @ = @.xy * ( @ * @ );\r\n", poffset, negViewTS, pdepth, parallaxInfo ) );
meta->addStatement( new GenOp( " @ = ( @ + texture2D( @, @.xy + @ ).a ) * 0.5;\r\n", pdepth, pdepth, normalMap, texCoord, poffset ) );
meta->addStatement( new GenOp( " @ = @.xy * ( @ * @ );\r\n", poffset, negViewTS, pdepth, parallaxInfo ) );
meta->addStatement( new GenOp( " @ = ( @ + texture2D( @, @.xy + @ ).a ) * 0.5;\r\n", pdepth, pdepth, normalMap, texCoord, poffset ) );
meta->addStatement( new GenOp( " @ = @.xy * ( @ * @ );\r\n", poffset, negViewTS, pdepth, parallaxInfo ) );
meta->addStatement( new GenOp( " @.xy += @;\r\n", texCoord, poffset ) );
// TODO: Fix second UV.
output = meta;
}
ShaderFeature::Resources ParallaxFeatGLSL::getResources( const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatGLSL::getResources - We don't support SM 1.x!" );
Resources res;
// We add the outViewTS to the outputstructure.
res.numTexReg = 1;
// If this isn't a prepass then we will be
// creating the normal map here.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex = 1;
return res;
}
void ParallaxFeatGLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatGLSL::setTexData - We don't support SM 1.x!" );
GFXTextureObject *tex = stageDat.getTex( MFT_NormalMap );
if ( tex )
{
passData.mTexType[ texIndex ] = Material::Bump;
passData.mTexSlot[ texIndex++ ].texObject = tex;
}
}
//
void NormalsOutFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
// If we have normal maps then we can count
// on it to generate the world space normal.
if ( fd.features[MFT_NormalMap] )
return;
MultiLine *meta = new MultiLine;
output = meta;
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outNormal = connectComp->getElement( RT_TEXCOORD );
outNormal->setName( "wsNormal" );
outNormal->setType( "vec3" );
outNormal->mapsToSampler = false;
// Find the incoming vertex normal.
Var *inNormal = (Var*)LangElement::find( "normal" );
if ( inNormal )
{
// Transform the normal to world space.
Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
meta->addStatement( new GenOp( " @ = @ * normalize( @ );\r\n", outNormal, objTrans, inNormal ) );
}
else
{
// If we don't have a vertex normal... just pass the
// camera facing normal to the pixel shader.
meta->addStatement( new GenOp( " @ = vec3( 0.0, 0.0, 1.0 );\r\n", outNormal ) );
}
}
void NormalsOutFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
Var *wsNormal = (Var*)LangElement::find( "wsNormal" );
if ( !wsNormal )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
wsNormal = connectComp->getElement( RT_TEXCOORD );
wsNormal->setName( "wsNormal" );
wsNormal->setType( "vec3" );
// If we loaded the normal its our resposibility
// to normalize it... the interpolators won't.
//
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", wsNormal, wsNormal ) );
}
LangElement *normalOut;
Var *outColor = (Var*)LangElement::find( "col" );
if ( outColor )
normalOut = new GenOp( "vec4( ( -@ + 1 ) * 0.5, @.a )", wsNormal, outColor );
else
normalOut = new GenOp( "vec4( ( -@ + 1 ) * 0.5, 1 )", wsNormal );
meta->addStatement( new GenOp( " @;\r\n",
assignColor( normalOut, Material::None ) ) );
}

View file

@ -0,0 +1,99 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _BUMP_GLSL_H_
#define _BUMP_GLSL_H_
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#endif
struct RenderPassData;
class MultiLine;
/// The Bumpmap feature will read the normal map and
/// transform it by the inverse of the worldToTanget
/// matrix. This normal is then used by subsequent
/// shader features.
class BumpFeatGLSL : public ShaderFeatureGLSL
{
public:
// ShaderFeatureGLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName() { return "Bumpmap"; }
};
/// This feature either generates the cheap yet effective offset
/// mapping style parallax or the much more expensive occlusion
/// mapping technique based on the enabled feature flags.
class ParallaxFeatGLSL : public ShaderFeatureGLSL
{
protected:
static Var* _getUniformVar( const char *name, const char *type );
public:
// ShaderFeatureGLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName() { return "Parallax"; }
};
/// This feature is used to render normals to the
/// diffuse target for imposter rendering.
class NormalsOutFeatGLSL : public ShaderFeatureGLSL
{
public:
// ShaderFeatureGLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual String getName() { return "NormalsOut"; }
};
#endif // _BUMP_GLSL_H_

View file

@ -0,0 +1,155 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/depthGLSL.h"
#include "materials/materialFeatureTypes.h"
void EyeSpaceDepthOutGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// grab output
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outWSEyeVec = connectComp->getElement( RT_TEXCOORD );
outWSEyeVec->setName( "outWSEyeVec" );
// grab incoming vert position
Var *wsPosition = new Var( "depthPos", "vec3" );
getWsPosition( componentList, fd.features[MFT_UseInstancing], meta, new DecOp( wsPosition ) );
Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
if( !eyePos )
{
eyePos = new Var;
eyePos->setType("vec3");
eyePos->setName("eyePosWorld");
eyePos->uniform = true;
eyePos->constSortPos = cspPass;
}
meta->addStatement( new GenOp( " @ = vec4( @.xyz - @, 1 );\r\n", outWSEyeVec, wsPosition, eyePos ) );
}
void EyeSpaceDepthOutGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
// grab connector position
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *wsEyeVec = connectComp->getElement( RT_TEXCOORD );
wsEyeVec->setName( "outWSEyeVec" );
wsEyeVec->setType( "vec4" );
wsEyeVec->mapsToSampler = false;
wsEyeVec->uniform = false;
// get shader constants
Var *vEye = new Var;
vEye->setType("vec3");
vEye->setName("vEye");
vEye->uniform = true;
vEye->constSortPos = cspPass;
// Expose the depth to the depth format feature
Var *depthOut = new Var;
depthOut->setType("float");
depthOut->setName(getOutputVarName());
LangElement *depthOutDecl = new DecOp( depthOut );
meta->addStatement( new GenOp( " @ = dot(@, (@.xyz / @.w));\r\n", depthOutDecl, vEye, wsEyeVec, wsEyeVec ) );
// If there isn't an output conditioner for the pre-pass, than just write
// out the depth to rgba and return.
if( !fd.features[MFT_PrePassConditioner] )
meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "vec4(@)", depthOut ), Material::None ) ) );
output = meta;
}
ShaderFeature::Resources EyeSpaceDepthOutGLSL::getResources( const MaterialFeatureData &fd )
{
Resources temp;
// Passing from VS->PS:
// - world space position (wsPos)
temp.numTexReg = 1;
return temp;
}
void DepthOutGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// Grab the output vert.
Var *outPosition = (Var*)LangElement::find( "gl_Position" );
// Grab our output depth.
Var *outDepth = connectComp->getElement( RT_TEXCOORD );
outDepth->setName( "outDepth" );
outDepth->setType( "float" );
output = new GenOp( " @ = @.z / @.w;\r\n", outDepth, outPosition, outPosition );
}
void DepthOutGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// grab connector position
Var *depthVar = connectComp->getElement( RT_TEXCOORD );
depthVar->setName( "outDepth" );
depthVar->setType( "float" );
depthVar->mapsToSampler = false;
depthVar->uniform = false;
/*
// Expose the depth to the depth format feature
Var *depthOut = new Var;
depthOut->setType("float");
depthOut->setName(getOutputVarName());
*/
LangElement *depthOut = new GenOp( "vec4( @, @ * @, 0, 1 )", depthVar, depthVar, depthVar );
output = new GenOp( " @;\r\n", assignColor( depthOut, Material::None ) );
}
ShaderFeature::Resources DepthOutGLSL::getResources( const MaterialFeatureData &fd )
{
// We pass the depth to the pixel shader.
Resources temp;
temp.numTexReg = 1;
return temp;
}

View file

@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _DEPTH_GLSL_H_
#define _DEPTH_GLSL_H_
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#endif
#ifndef _SHADEROP_H_
#include "shaderGen/shaderOp.h"
#endif
class EyeSpaceDepthOutGLSL : public ShaderFeatureGLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Eye Space Depth (Out)"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual const char* getOutputVarName() const { return "eyeSpaceDepth"; }
};
class DepthOutGLSL : public ShaderFeatureGLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Depth (Out)"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual const char* getOutputVarName() const { return "outDepth"; }
};
#endif // _DEPTH_GLSL_H_

View file

@ -0,0 +1,158 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/paraboloidGLSL.h"
#include "lighting/lightInfo.h"
#include "materials/sceneData.h"
#include "materials/materialFeatureTypes.h"
#include "materials/materialFeatureData.h"
#include "gfx/gfxShader.h"
void ParaboloidVertTransformGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
// First check for an input position from a previous feature
// then look for the default vertex position.
Var *inPosition = (Var*)LangElement::find( "inPosition" );
if ( !inPosition )
inPosition = (Var*)LangElement::find( "position" );
const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ];
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// Grab connector out position.
Var *outPosition = connectComp->getElement( RT_POSITION );
outPosition->setName( "gl_Position" );
// Get the atlas scale.
Var *atlasScale = new Var;
atlasScale->setType( "vec2" );
atlasScale->setName( "atlasScale" );
atlasScale->uniform = true;
atlasScale->constSortPos = cspPass;
// Transform into camera space
Var *worldViewOnly = getWorldView( componentList, fd.features[MFT_UseInstancing], meta );
// So what we're doing here is transforming into camera space, and
// then directly manipulate into shadowmap space.
//
// http://www.gamedev.net/reference/articles/article2308.asp
// Swizzle z and y post-transform
meta->addStatement( new GenOp( " @ = vec4(@ * vec4(@.xyz,1)).xzyw;\r\n", outPosition, worldViewOnly, inPosition ) );
meta->addStatement( new GenOp( " float L = length(@.xyz);\r\n", outPosition ) );
if ( isSinglePass )
{
// Flip the z in the back case
Var *outIsBack = connectComp->getElement( RT_TEXCOORD );
outIsBack->setType( "float" );
outIsBack->setName( "outIsBack" );
meta->addStatement( new GenOp( " bool isBack = @.z < 0.0;\r\n", outPosition ) );
meta->addStatement( new GenOp( " @ = isBack ? -1.0 : 1.0;\r\n", outIsBack ) );
meta->addStatement( new GenOp( " if ( isBack ) @.z = -@.z;\r\n", outPosition, outPosition ) );
}
meta->addStatement( new GenOp( " @ /= L;\r\n", outPosition ) );
meta->addStatement( new GenOp( " @.z = @.z + 1.0;\r\n", outPosition, outPosition ) );
meta->addStatement( new GenOp( " @.xy /= @.z;\r\n", outPosition, outPosition ) );
// Get the light parameters.
Var *lightParams = new Var;
lightParams->setType( "vec4" );
lightParams->setName( "lightParams" );
lightParams->uniform = true;
lightParams->constSortPos = cspPass;
// TODO: If we change other shadow shaders to write out
// linear depth, than fix this as well!
//
// (L - 1.0)/(lightParams.x - 1.0);
//
meta->addStatement( new GenOp( " @.z = L / @.x;\r\n", outPosition, lightParams ) );
meta->addStatement( new GenOp( " @.w = 1.0;\r\n", outPosition ) );
// Pass unmodified to pixel shader to allow it to clip properly.
Var *outPosXY = connectComp->getElement( RT_TEXCOORD );
outPosXY->setType( "vec2" );
outPosXY->setName( "outPosXY" );
meta->addStatement( new GenOp( " @ = @.xy;\r\n", outPosXY, outPosition ) );
// Scale and offset so it shows up in the atlas properly.
meta->addStatement( new GenOp( " @.xy *= @.xy;\r\n", outPosition, atlasScale ) );
if ( isSinglePass )
meta->addStatement( new GenOp( " @.x += isBack ? 0.5 : -0.5;\r\n", outPosition ) );
else
{
Var *atlasOffset = new Var;
atlasOffset->setType( "vec2" );
atlasOffset->setName( "atlasXOffset" );
atlasOffset->uniform = true;
atlasOffset->constSortPos = cspPass;
meta->addStatement( new GenOp( " @.xy += @;\r\n", outPosition, atlasOffset ) );
}
output = meta;
}
void ParaboloidVertTransformGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
MultiLine *meta = new MultiLine;
const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ];
if ( isSinglePass )
{
// Cull things on the back side of the map.
Var *isBack = connectComp->getElement( RT_TEXCOORD );
isBack->setName( "outIsBack" );
isBack->setType( "float" );
meta->addStatement( new GenOp( " if ( ( abs( @ ) - 0.999 ) < 0 ) discard;\r\n", isBack ) );
}
// Cull pixels outside of the valid paraboloid.
Var *posXY = connectComp->getElement( RT_TEXCOORD );
posXY->setName( "outPosXY" );
posXY->setType( "vec2" );
meta->addStatement( new GenOp( " if ( ( 1.0 - length( @ ) ) < 0 ) discard;\r\n", posXY ) );
output = meta;
}
ShaderFeature::Resources ParaboloidVertTransformGLSL::getResources( const MaterialFeatureData &fd )
{
Resources temp;
temp.numTexReg = 2;
return temp;
}

View file

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _PARABOLOID_GLSL_H_
#define _PARABOLOID_GLSL_H_
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#endif
#ifndef _SHADEROP_H_
#include "shaderGen/shaderOp.h"
#endif
class GFXShaderConstHandle;
class ParaboloidVertTransformGLSL : public ShaderFeatureGLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Paraboloid Vert Transform"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
};
#endif // _PARABOLOID_GLSL_H_

View file

@ -0,0 +1,208 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/pixSpecularGLSL.h"
#include "materials/processedMaterial.h"
#include "materials/materialFeatureTypes.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/shaderGenVars.h"
#include "gfx/gfxStructs.h"
PixelSpecularGLSL::PixelSpecularGLSL()
: mDep( "shaders/common/gl/lighting.glsl" )
{
addDependency( &mDep );
}
void PixelSpecularGLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
/*
AssertFatal( fd.features[MFT_RTLighting],
"PixelSpecularHLSL requires RTLighting to be enabled!" );
MultiLine *meta = new MultiLine;
// Get the eye world position.
Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
if( !eyePos )
{
eyePos = new Var;
eyePos->setType( "float3" );
eyePos->setName( "eyePosWorld" );
eyePos->uniform = true;
eyePos->constSortPos = cspPass;
}
// Grab a register for passing the
// world space view vector.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *wsView = connectComp->getElement( RT_TEXCOORD );
wsView->setName( "wsView" );
wsView->setStructName( "OUT" );
wsView->setType( "float3" );
// Get the input position.
Var *position = (Var*)LangElement::find( "inPosition" );
if ( !position )
position = (Var*)LangElement::find( "position" );
// Get the object to world transform.
Var *objTrans = (Var*) LangElement::find( "objTrans" );
if ( !objTrans )
{
objTrans = new Var;
objTrans->setType( "float4x4" );
objTrans->setName( "objTrans" );
objTrans->uniform = true;
objTrans->constSortPos = cspPrimitive;
}
meta->addStatement( new GenOp( " @ = @ - mul( @, float4( @.xyz,1 ) ).xyz;\r\n",
wsView, eyePos, objTrans, position ) );
output = meta;
*/
}
void PixelSpecularGLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
/*
AssertFatal( fd.features[MFT_RTLighting],
"PixelSpecularHLSL requires RTLighting to be enabled!" );
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
MultiLine *meta = new MultiLine;
// Get the normal and light vectors from which the
// RTLighting feature should have already setup.
Var *wsNormal = (Var*)LangElement::find( "wsNormal" );
Var *inLightVec = (Var*)LangElement::find( "inLightVec" );
// Grab the world space position to eye vector.
Var *wsView = connectComp->getElement( RT_TEXCOORD );
wsView->setName( "wsView" );
wsView->setStructName( "IN" );
wsView->setType( "float3" );
// Get the specular power and color.
Var *specPow = new Var( "specularPower", "float" );
specPow->uniform = true;
specPow->constSortPos = cspPass;
Var *specCol = (Var*)LangElement::find("specularColor");
if(specCol == NULL)
{
specCol = new Var( "specularColor", "vec4" );
specCol->uniform = true;
specCol->constSortPos = cspPass;
}
// Calcuate the specular factor.
Var *specular = new Var( "specular", "float" );
meta->addStatement( new GenOp( " @ = calcSpecular( -@, normalize( @ ), normalize( @ ), @ );\r\n",
new DecOp( specular ), inLightVec, wsNormal, wsView, specPow ) );
LangElement *specMul = new GenOp( "float4(@.rgb,0) * @", specCol, specular );
LangElement *final = specMul;
// mask out with lightmap if present
if( fd.features[MFT_LightMap] )
{
LangElement *lmColor = NULL;
// find lightmap color
lmColor = LangElement::find( "lmColor" );
if ( !lmColor )
{
LangElement * lightMap = LangElement::find( "lightMap" );
LangElement * lmCoord = LangElement::find( "texCoord2" );
lmColor = new GenOp( "tex2D(@, @)", lightMap, lmCoord );
}
final = new GenOp( "@ * float4(@.rgb,0)", specMul, lmColor );
}
// We we have a normal map then mask the specular
if ( !fd.features[MFT_SpecularMap] && fd.features[MFT_NormalMap] )
{
Var *bumpColor = (Var*)LangElement::find( "bumpNormal" );
final = new GenOp( "@ * @.a", final, bumpColor );
}
// Add the specular to the final color.
meta->addStatement( new GenOp( " @;\r\n", assignColor( final, Material::Add ) ) );
output = meta;
*/
}
ShaderFeature::Resources PixelSpecularGLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
res.numTexReg = 1;
return res;
}
void SpecularMapGLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Get the texture coord.
Var *texCoord = getInTexCoord( "out_texCoord", "vec2", true, componentList );
// create texture var
Var *specularMap = new Var;
specularMap->setType( "sampler2D" );
specularMap->setName( "specularMap" );
specularMap->uniform = true;
specularMap->sampler = true;
specularMap->constNum = Var::getTexUnitNum();
LangElement *texOp = new GenOp( "texture2D(@, @)", specularMap, texCoord );
Var *specularColor = new Var( "specularColor", "vec4" );
output = new GenOp( " @ = @;\r\n", new DecOp( specularColor ), texOp );
}
ShaderFeature::Resources SpecularMapGLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
res.numTex = 1;
return res;
}
void SpecularMapGLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
GFXTextureObject *tex = stageDat.getTex( MFT_SpecularMap );
if ( tex )
{
passData.mTexType[ texIndex ] = Material::Standard;
passData.mTexSlot[ texIndex++ ].texObject = tex;
}
}

View file

@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _PIXSPECULAR_GLSL_H_
#define _PIXSPECULAR_GLSL_H_
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#endif
/// A per-pixel specular feature.
class PixelSpecularGLSL : public ShaderFeatureGLSL
{
protected:
ShaderIncludeDependency mDep;
public:
PixelSpecularGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName()
{
return "Pixel Specular";
}
};
/// A texture source for the PixSpecular feature
class SpecularMapGLSL : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Specular Map";
}
};
#endif // _PIXSPECULAR_GLSL_H_

View file

@ -0,0 +1,263 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/shaderCompGLSL.h"
#include "shaderGen/shaderComp.h"
#include "shaderGen/langElement.h"
#include "gfx/gfxDevice.h"
Var * AppVertConnectorGLSL::getElement( RegisterType type,
U32 numElements,
U32 numRegisters )
{
switch( type )
{
case RT_POSITION:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "gl_Vertex" );
return newVar;
}
case RT_NORMAL:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "gl_Normal" );
return newVar;
}
case RT_COLOR:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "gl_Color" );
return newVar;
}
case RT_TEXCOORD:
case RT_BINORMAL:
case RT_TANGENT:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
char out[32];
dSprintf( (char*)out, sizeof(out), "gl_MultiTexCoord%d", mCurTexElem );
newVar->setConnectName( out );
newVar->constNum = mCurTexElem;
newVar->arraySize = numElements;
if ( numRegisters != -1 )
mCurTexElem += numRegisters;
else
mCurTexElem += numElements;
return newVar;
}
default:
break;
}
return NULL;
}
void AppVertConnectorGLSL::sortVars()
{
// Not required in GLSL
}
void AppVertConnectorGLSL::setName( char *newName )
{
dStrcpy( (char*)mName, newName );
}
void AppVertConnectorGLSL::reset()
{
for( U32 i=0; i<mElementList.size(); i++ )
{
mElementList[i] = NULL;
}
mElementList.setSize( 0 );
mCurTexElem = 0;
}
void AppVertConnectorGLSL::print( Stream &stream )
{
// print out elements
for( U32 i=0; i<mElementList.size(); i++ )
{
Var *var = mElementList[i];
U8 output[256];
const char* swizzle;
if(!dStrcmp((const char*)var->type, "float"))
swizzle = "x";
else if(!dStrcmp((const char*)var->type, "vec2"))
swizzle = "xy";
else if(!dStrcmp((const char*)var->type, "vec3"))
swizzle = "xyz";
else
swizzle = "xyzw";
// This is ugly. We use #defines to match user defined names with
// built in vars. There is no cleaner way to do this.
dSprintf( (char*)output, sizeof(output), "#define %s %s.%s\r\n", var->name, var->connectName, swizzle );
stream.write( dStrlen((char*)output), output );
}
}
Var * VertPixelConnectorGLSL::getElement( RegisterType type,
U32 numElements,
U32 numRegisters )
{
switch( type )
{
case RT_POSITION:
case RT_NORMAL:
case RT_COLOR:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
return newVar;
}
case RT_TEXCOORD:
case RT_BINORMAL:
case RT_TANGENT:
{
Var *newVar = new Var;
newVar->arraySize = numElements;
if ( numRegisters != -1 )
mCurTexElem += numRegisters;
else
mCurTexElem += numElements;
mElementList.push_back( newVar );
return newVar;
}
default:
break;
}
return NULL;
}
void VertPixelConnectorGLSL::sortVars()
{
// Not needed in GLSL
}
void VertPixelConnectorGLSL::setName( char *newName )
{
dStrcpy( (char*)mName, newName );
}
void VertPixelConnectorGLSL::reset()
{
for( U32 i=0; i<mElementList.size(); i++ )
{
mElementList[i] = NULL;
}
mElementList.setSize( 0 );
mCurTexElem = 0;
}
void VertPixelConnectorGLSL::print( Stream &stream )
{
// print out elements
for( U32 i=0; i<mElementList.size(); i++ )
{
U8 output[256];
Var *var = mElementList[i];
if(!dStrcmp((const char*)var->name, "gl_Position"))
continue;
if(var->arraySize <= 1)
dSprintf((char*)output, sizeof(output), "varying %s %s;\r\n", var->type, var->name);
else
dSprintf((char*)output, sizeof(output), "varying %s %s[%d];\r\n", var->type, var->name, var->arraySize);
stream.write( dStrlen((char*)output), output );
}
}
void VertexParamsDefGLSL::print( Stream &stream )
{
// find all the uniform variables and print them out
for( U32 i=0; i<LangElement::elementList.size(); i++)
{
Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
if( var )
{
if( var->uniform )
{
U8 output[256];
if(var->arraySize <= 1)
dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s;\r\n", var->type, var->name);
else
dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s[%d];\r\n", var->type, var->name, var->arraySize);
stream.write( dStrlen((char*)output), output );
}
}
}
const char *closer = "\r\n\r\nvoid main()\r\n{\r\n";
stream.write( dStrlen(closer), closer );
}
void PixelParamsDefGLSL::print( Stream &stream )
{
// find all the uniform variables and print them out
for( U32 i=0; i<LangElement::elementList.size(); i++)
{
Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
if( var )
{
if( var->uniform )
{
U8 output[256];
if(var->arraySize <= 1)
dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s;\r\n", var->type, var->name);
else
dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s[%d];\r\n", var->type, var->name, var->arraySize);
stream.write( dStrlen((char*)output), output );
}
}
}
const char *closer = "\r\nvoid main()\r\n{\r\n";
stream.write( dStrlen(closer), closer );
}

View file

@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERCOMP_GLSL_H_
#define _SHADERCOMP_GLSL_H_
#ifndef _SHADERCOMP_H_
#include "shaderGen/shaderComp.h"
#endif
class VertPixelConnectorGLSL : public ShaderConnector
{
public:
// ShaderConnector
virtual Var* getElement( RegisterType type,
U32 numElements = 1,
U32 numRegisters = -1 );
virtual void setName( char *newName );
virtual void reset();
virtual void sortVars();
virtual void print( Stream &stream );
};
class AppVertConnectorGLSL : public ShaderConnector
{
public:
virtual Var* getElement( RegisterType type,
U32 numElements = 1,
U32 numRegisters = -1 );
virtual void setName( char *newName );
virtual void reset();
virtual void sortVars();
virtual void print( Stream &stream );
};
class VertexParamsDefGLSL : public ParamsDef
{
public:
virtual void print( Stream &stream );
};
class PixelParamsDefGLSL : public ParamsDef
{
public:
virtual void print( Stream &stream );
};
#endif // _SHADERCOMP_GLSL_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,643 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#define _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
#ifndef _SHADERFEATURE_H_
#include "shaderGen/shaderFeature.h"
#endif
#ifndef _MATERIALFEATUREDATA_H_
#include "materials/materialFeatureData.h"
#endif
struct LangElement;
struct MaterialFeatureData;
struct RenderPassData;
class ShaderFeatureGLSL : public ShaderFeature
{
public:
ShaderFeatureGLSL();
///
Var* getOutTexCoord( const char *name,
const char *type,
bool mapsToSampler,
bool useTexAnim,
MultiLine *meta,
Vector<ShaderComponent*> &componentList );
/// Returns an input texture coord by name adding it
/// to the input connector if it doesn't exist.
static Var* getInTexCoord( const char *name,
const char *type,
bool mapsToSampler,
Vector<ShaderComponent*> &componentList );
/// Returns the "objToTangentSpace" transform or creates one if this
/// is the first feature to need it.
Var* getOutObjToTangentSpace( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the existing output "worldToTangent" transform or
/// creates one if this is the first feature to need it.
Var* getOutWorldToTangent( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the input "worldToTanget" space transform
/// adding it to the input connector if it doesn't exist.
static Var* getInWorldToTangent( Vector<ShaderComponent*> &componentList );
/// Returns the existing output "viewToTangent" transform or
/// creates one if this is the first feature to need it.
Var* getOutViewToTangent( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the input "viewToTangent" space transform
/// adding it to the input connector if it doesn't exist.
static Var* getInViewToTangent( Vector<ShaderComponent*> &componentList );
/// Calculates the world space position in the vertex shader and
/// assigns it to the passed language element. It does not pass /// it across the connector to the pixel shader.
/// @see addOutWsPosition
void getWsPosition( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta,
LangElement *wsPosition );
/// Adds the "wsPosition" to the input connector if it doesn't exist.
Var* addOutWsPosition( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
/// Returns the input world space position from the connector.
static Var* getInWsPosition( Vector<ShaderComponent*> &componentList );
/// Returns the world space view vector from the wsPosition.
static Var* getWsView( Var *wsPosition, MultiLine *meta );
/// Returns the input normal map texture.
static Var* getNormalMapTex();
///
Var* addOutDetailTexCoord( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
bool useTexAnim );
///
Var* getObjTrans( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getModelView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getWorldView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getInvWorldView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
// ShaderFeature
Var* getVertTexCoord( const String &name );
LangElement* setupTexSpaceMat( Vector<ShaderComponent*> &componentList, Var **texSpaceMat );
LangElement* assignColor( LangElement *elem, Material::BlendOp blend, LangElement *lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget );
LangElement* expandNormalMap( LangElement *sampleNormalOp, LangElement *normalDecl, LangElement *normalVar, const MaterialFeatureData &fd );
};
class NamedFeatureGLSL : public ShaderFeatureGLSL
{
protected:
String mName;
public:
NamedFeatureGLSL( const String &name )
: mName( name )
{}
virtual String getName() { return mName; }
};
class RenderTargetZeroGLSL : public ShaderFeatureGLSL
{
protected: ShaderFeature::OutputTarget mOutputTargetMask;
String mFeatureName;
public:
RenderTargetZeroGLSL( const ShaderFeature::OutputTarget target )
: mOutputTargetMask( target )
{
char buffer[256]; dSprintf(buffer, sizeof(buffer), "Render Target Output = 0.0, output mask %04b", mOutputTargetMask);
mFeatureName = buffer; }
virtual String getName() { return mFeatureName; }
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return
mOutputTargetMask; }
};
/// Vertex position
class VertPositionGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Vert Position";
}
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData )
{
// This feature is always on!
outFeatureData->features.addFeature( type );
}
};
/// Vertex lighting based on the normal and the light
/// direction passed through the vertex color.
class RTLightingFeatGLSL : public ShaderFeatureGLSL
{
protected:
ShaderIncludeDependency mDep;
public:
RTLightingFeatGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName()
{
return "RT Lighting";
}
};
/// Base texture
class DiffuseMapFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Base Texture";
}
};
/// Overlay texture
class OverlayTexFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Overlay Texture";
}
};
/// Diffuse color
class DiffuseFeatureGLSL : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Diffuse Color";
}
};
/// Diffuse vertex color
class DiffuseVertColorFeatureGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector< ShaderComponent* >& componentList,
const MaterialFeatureData& fd );
virtual void processPix( Vector< ShaderComponent* >&componentList,
const MaterialFeatureData& fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Diffuse Vertex Color";
}
};
/// Lightmap
class LightmapFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Lightmap";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Tonemap
class TonemapFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Tonemap";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Baked lighting stored on the vertex color
class VertLitGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Vert Lit";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Detail map
class DetailFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::Mul; }
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Detail";
}
};
/// Reflect Cubemap
class ReflectCubeFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Reflect Cube";
}
};
/// Fog
class FogFeatGLSL : public ShaderFeatureGLSL
{
protected:
ShaderIncludeDependency mFogDep;
public:
FogFeatGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::LerpAlpha; }
virtual String getName()
{
return "Fog";
}
};
/// Tex Anim
class TexAnimGLSL : public ShaderFeatureGLSL
{
public:
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Texture Animation";
}
};
/// Visibility
class VisibilityFeatGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Visibility";
}
};
///
class AlphaTestGLSL : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Alpha Test";
}
};
/// Special feature used to mask out the RGB color for
/// non-glow passes of glow materials.
/// @see RenderGlowMgr
class GlowMaskGLSL : public ShaderFeatureGLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Glow Mask";
}
};
/// This should be the final feature on most pixel shaders which
/// encodes the color for the current HDR target format.
/// @see HDRPostFx/// @see LightManager
/// @see torque.glsl
class HDROutGLSL : public ShaderFeatureGLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
public:
HDROutGLSL();
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName() { return "HDR Output"; }
};
///
class FoliageFeatureGLSL : public ShaderFeatureGLSL{
protected:
ShaderIncludeDependency mDep;
public:
FoliageFeatureGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Foliage Feature";
}
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData );
virtual ShaderFeatureConstHandles* createConstHandles( GFXShader *shader, SimObject *userObject );
};
///
class ParticleNormalFeatureGLSL : public ShaderFeatureGLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Particle Normal Generation Feature";
}
};
class ImposterVertFeatureGLSL : public ShaderFeatureGLSL
{
protected:
ShaderIncludeDependency mDep;
public:
ImposterVertFeatureGLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName() { return "Imposter Vert"; }
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData );
};
#endif // _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_

View file

@ -0,0 +1,179 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/GLSL/shaderGenGLSL.h"
#include "shaderGen/GLSL/shaderCompGLSL.h"
void ShaderGenPrinterGLSL::printShaderHeader( Stream& stream )
{
const char *header1 = "//*****************************************************************************\r\n";
const char *header2 = "// Torque -- GLSL procedural shader\r\n";
stream.write( dStrlen(header1), header1 );
stream.write( dStrlen(header2), header2 );
stream.write( dStrlen(header1), header1 );
// Cheap HLSL compatibility.
const char* header3 = "#include \"shaders/common/gl/hlslCompat.glsl\"\r\n";
stream.write( dStrlen(header3), header3 );
const char* header4 = "\r\n";
stream.write( dStrlen(header4), header4 );
}
void ShaderGenPrinterGLSL::printMainComment( Stream& stream )
{
// Print out main function definition
const char * header5 = "// Main \r\n";
const char * line = "//-----------------------------------------------------------------------------\r\n";
stream.write( dStrlen(line), line );
stream.write( dStrlen(header5), header5 );
stream.write( dStrlen(line), line );
}
void ShaderGenPrinterGLSL::printVertexShaderCloser( Stream& stream )
{
const char *closer = "}\r\n";
stream.write( dStrlen(closer), closer );
}
void ShaderGenPrinterGLSL::printPixelShaderOutputStruct( Stream& stream, const MaterialFeatureData &featureData )
{
// Nothing here
}
void ShaderGenPrinterGLSL::printPixelShaderCloser( Stream& stream )
{
const char *closer = " gl_FragColor = col;\r\n}\r\n";
stream.write( dStrlen(closer), closer );
}
void ShaderGenPrinterGLSL::printLine(Stream& stream, const String& line)
{
stream.write(line.length(), line.c_str());
const char* end = "\r\n";
stream.write(dStrlen(end), end);
}
const char* ShaderGenComponentFactoryGLSL::typeToString( GFXDeclType type )
{
switch ( type )
{
default:
case GFXDeclType_Float:
return "float";
case GFXDeclType_Float2:
return "vec2";
case GFXDeclType_Float3:
return "vec3";
case GFXDeclType_Float4:
case GFXDeclType_Color:
return "vec4";
}
}
ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexInputConnector( const GFXVertexFormat &vertexFormat )
{
AppVertConnectorGLSL *vertComp = new AppVertConnectorGLSL;
// Loop thru the vertex format elements.
for ( U32 i=0; i < vertexFormat.getElementCount(); i++ )
{
const GFXVertexElement &element = vertexFormat.getElement( i );
Var *var = NULL;
if ( element.isSemantic( GFXSemantic::POSITION ) )
{
var = vertComp->getElement( RT_POSITION );
var->setName( "position" );
}
else if ( element.isSemantic( GFXSemantic::NORMAL ) )
{
var = vertComp->getElement( RT_NORMAL );
var->setName( "normal" );
}
else if ( element.isSemantic( GFXSemantic::TANGENT ) )
{
var = vertComp->getElement( RT_TANGENT );
var->setName( "T" );
}
else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
{
var = vertComp->getElement( RT_BINORMAL );
var->setName( "B" );
}
else if ( element.isSemantic( GFXSemantic::COLOR ) )
{
var = vertComp->getElement( RT_COLOR );
var->setName( "diffuse" );
}
else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
{
var = vertComp->getElement( RT_TEXCOORD );
if ( element.getSemanticIndex() == 0 )
var->setName( "texCoord" );
else
var->setName( String::ToString( "texCoord%d", element.getSemanticIndex() + 1 ) );
}
else
{
// Everything else is a texcoord!
var = vertComp->getElement( RT_TEXCOORD );
var->setName( "tc" + element.getSemantic() );
}
if ( !var )
continue;
var->setStructName( "" );
var->setType( typeToString( element.getType() ) );
}
return vertComp;
}
ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexPixelConnector()
{
VertPixelConnectorGLSL* comp = new VertPixelConnectorGLSL;
return comp;
}
ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexParamsDef()
{
VertexParamsDefGLSL* comp = new VertexParamsDefGLSL;
return comp;
}
ShaderComponent* ShaderGenComponentFactoryGLSL::createPixelParamsDef()
{
PixelParamsDefGLSL* comp = new PixelParamsDefGLSL;
return comp;
}

View file

@ -0,0 +1,59 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGEN_GLSL_H_
#define _SHADERGEN_GLSL_H_
#ifndef _SHADERGEN_H_
#include "shaderGen/shaderGen.h"
#endif
class ShaderGenPrinterGLSL : public ShaderGenPrinter
{
public:
// ShaderGenPrinter
virtual void printShaderHeader(Stream& stream);
virtual void printMainComment(Stream& stream);
virtual void printVertexShaderCloser(Stream& stream);
virtual void printPixelShaderOutputStruct(Stream& stream, const MaterialFeatureData &featureData);
virtual void printPixelShaderCloser(Stream& stream);
virtual void printLine(Stream& stream, const String& line);
};
class ShaderGenComponentFactoryGLSL : public ShaderGenComponentFactory
{
public:
/// Helper function for converting a vertex decl
/// type to an GLSL type string.
static const char* typeToString( GFXDeclType type );
// ShaderGenComponentFactory
virtual ShaderComponent* createVertexInputConnector( const GFXVertexFormat &vertexFormat );
virtual ShaderComponent* createVertexPixelConnector();
virtual ShaderComponent* createVertexParamsDef();
virtual ShaderComponent* createPixelParamsDef();
};
#endif

View file

@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderGen.h"
#include "shaderGen/GLSL/shaderGenGLSL.h"
#include "shaderGen/GLSL/shaderFeatureGLSL.h"
#include "shaderGen/featureMgr.h"
#include "shaderGen/GLSL/bumpGLSL.h"
#include "shaderGen/GLSL/pixSpecularGLSL.h"
#include "shaderGen/GLSL/depthGLSL.h"
#include "shaderGen/GLSL/paraboloidGLSL.h"
#include "materials/materialFeatureTypes.h"
#include "core/module.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate;
void _initShaderGenGLSL( ShaderGen *shaderGen )
{
shaderGen->setPrinter( new ShaderGenPrinterGLSL );
shaderGen->setComponentFactory( new ShaderGenComponentFactoryGLSL );
shaderGen->setFileEnding( "glsl" );
FEATUREMGR->registerFeature( MFT_VertTransform, new VertPositionGLSL );
FEATUREMGR->registerFeature( MFT_RTLighting, new RTLightingFeatGLSL );
FEATUREMGR->registerFeature( MFT_IsDXTnm, new NamedFeatureGLSL( "DXTnm" ) );
FEATUREMGR->registerFeature( MFT_TexAnim, new TexAnimGLSL );
FEATUREMGR->registerFeature( MFT_DiffuseMap, new DiffuseMapFeatGLSL );
FEATUREMGR->registerFeature( MFT_OverlayMap, new OverlayTexFeatGLSL );
FEATUREMGR->registerFeature( MFT_DiffuseColor, new DiffuseFeatureGLSL );
FEATUREMGR->registerFeature( MFT_DiffuseVertColor, new DiffuseVertColorFeatureGLSL );
FEATUREMGR->registerFeature( MFT_AlphaTest, new AlphaTestGLSL );
FEATUREMGR->registerFeature( MFT_GlowMask, new GlowMaskGLSL );
FEATUREMGR->registerFeature( MFT_LightMap, new LightmapFeatGLSL );
FEATUREMGR->registerFeature( MFT_ToneMap, new TonemapFeatGLSL );
FEATUREMGR->registerFeature( MFT_VertLit, new VertLitGLSL );
FEATUREMGR->registerFeature( MFT_Parallax, new ParallaxFeatGLSL );
FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatGLSL );
FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureGLSL( "Detail Normal Map" ) );
FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatGLSL );
FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL );
FEATUREMGR->registerFeature( MFT_Fog, new FogFeatGLSL );
FEATUREMGR->registerFeature( MFT_NormalsOut, new NormalsOutFeatGLSL );
FEATUREMGR->registerFeature( MFT_DepthOut, new DepthOutGLSL );
FEATUREMGR->registerFeature(MFT_EyeSpaceDepthOut, new EyeSpaceDepthOutGLSL());
FEATUREMGR->registerFeature( MFT_HDROut, new HDROutGLSL );
FEATUREMGR->registerFeature( MFT_ParaboloidVertTransform, new ParaboloidVertTransformGLSL );
FEATUREMGR->registerFeature( MFT_IsSinglePassParaboloid, new NamedFeatureGLSL( "Single Pass Paraboloid" ) );
FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroGLSL
( ShaderFeature::RenderTarget1 ) );
FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureGLSL( "Diffuse Map Atlas" ) );
FEATUREMGR->registerFeature( MFT_NormalMapAtlas, new NamedFeatureGLSL( "Normal Map Atlas" ) );
FEATUREMGR->registerFeature( MFT_Foliage, new FoliageFeatureGLSL );
FEATUREMGR->registerFeature( MFT_ParticleNormal, new ParticleNormalFeatureGLSL );
FEATUREMGR->registerFeature( MFT_ForwardShading, new NamedFeatureGLSL( "Forward Shaded Material" ) );
FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureGLSL );
}
MODULE_BEGIN( ShaderGenGLSL )
MODULE_INIT_AFTER( ShaderGen )
MODULE_INIT_AFTER( ShaderGenFeatureMgr )
MODULE_INIT
{
sInitDelegate.bind( &_initShaderGenGLSL );
SHADERGEN->registerInitDelegate(OpenGL, sInitDelegate);
}
MODULE_END;

View file

@ -0,0 +1,461 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/bumpHLSL.h"
#include "shaderGen/shaderOp.h"
#include "gfx/gfxDevice.h"
#include "materials/matInstance.h"
#include "materials/processedMaterial.h"
#include "materials/materialFeatureTypes.h"
#include "shaderGen/shaderGenVars.h"
void BumpFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
const bool useTexAnim = fd.features[MFT_TexAnim];
// Output the texture coord.
getOutTexCoord( "texCoord",
"float2",
true,
useTexAnim,
meta,
componentList );
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
addOutDetailTexCoord( componentList,
meta,
useTexAnim );
// Also output the worldToTanget transform which
// we use to create the world space normal.
getOutWorldToTangent( componentList, meta, fd );
}
void BumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// Get the texture coord.
Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
// Sample the bumpmap.
Var *bumpMap = getNormalMapTex();
LangElement *texOp = NULL;
// Handle atlased textures
// http://www.infinity-universe.com/Infinity/index.php?option=com_content&task=view&id=65&Itemid=47
if(fd.features[MFT_NormalMapAtlas])
{
// This is a big block of code, so put a comment in the shader code
meta->addStatement( new GenOp( " // Atlased texture coordinate calculation (see BumpFeat*LSL for details)\r\n") );
Var *atlasedTex = new Var;
atlasedTex->setName("atlasedBumpCoord");
atlasedTex->setType( "float2" );
LangElement *atDecl = new DecOp( atlasedTex );
// Parameters of the texture atlas
Var *atParams = new Var;
atParams->setType( "float4" );
atParams->setName("bumpAtlasParams");
atParams->uniform = true;
atParams->constSortPos = cspPotentialPrimitive;
// Parameters of the texture (tile) this object is using in the atlas
Var *tileParams = new Var;
tileParams->setType( "float4" );
tileParams->setName("bumpAtlasTileParams");
tileParams->uniform = true;
tileParams->constSortPos = cspPotentialPrimitive;
const bool is_sm3 = (GFX->getPixelShaderVersion() > 2.0f);
if(is_sm3)
{
// Figure out the mip level
meta->addStatement( new GenOp( " float2 _dx_bump = ddx(@ * @.z);\r\n", texCoord, atParams ) );
meta->addStatement( new GenOp( " float2 _dy_bump = ddy(@ * @.z);\r\n", texCoord, atParams ) );
meta->addStatement( new GenOp( " float mipLod_bump = 0.5 * log2(max(dot(_dx_bump, _dx_bump), dot(_dy_bump, _dy_bump)));\r\n" ) );
meta->addStatement( new GenOp( " mipLod_bump = clamp(mipLod_bump, 0.0, @.w);\r\n", atParams ) );
// And the size of the mip level
meta->addStatement( new GenOp( " float mipPixSz_bump = pow(2.0, @.w - mipLod_bump);\r\n", atParams ) );
meta->addStatement( new GenOp( " float2 mipSz_bump = mipPixSz_bump / @.xy;\r\n", atParams ) );
}
else
{
meta->addStatement(new GenOp(" float2 mipSz = float2(1.0, 1.0);\r\n"));
}
// Tiling mode
if( true ) // Wrap
meta->addStatement( new GenOp( " @ = frac(@);\r\n", atDecl, texCoord ) );
else // Clamp
meta->addStatement( new GenOp( " @ = saturate(@);\r\n", atDecl, texCoord ) );
// Finally scale/offset, and correct for filtering
meta->addStatement( new GenOp( " @ = @ * ((mipSz_bump * @.xy - 1.0) / mipSz_bump) + 0.5 / mipSz_bump + @.xy * @.xy;\r\n",
atlasedTex, atlasedTex, atParams, atParams, tileParams ) );
// Add a newline
meta->addStatement( new GenOp( "\r\n" ) );
if(is_sm3)
{
texOp = new GenOp( "tex2Dlod(@, float4(@, 0.0, mipLod_bump))", bumpMap, texCoord );
}
else
{
texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
}
}
else
{
texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
}
Var *bumpNorm = new Var( "bumpNormal", "float4" );
meta->addStatement( expandNormalMap( texOp, new DecOp( bumpNorm ), bumpNorm, fd ) );
// If we have a detail normal map we add the xy coords of
// it to the base normal map. This gives us the effect we
// want with few instructions and minial artifacts.
if ( fd.features.hasFeature( MFT_DetailNormalMap ) )
{
bumpMap = new Var;
bumpMap->setType( "sampler2D" );
bumpMap->setName( "detailBumpMap" );
bumpMap->uniform = true;
bumpMap->sampler = true;
bumpMap->constNum = Var::getTexUnitNum();
texCoord = getInTexCoord( "detCoord", "float2", true, componentList );
texOp = new GenOp( "tex2D(@, @)", bumpMap, texCoord );
Var *detailBump = new Var;
detailBump->setName( "detailBump" );
detailBump->setType( "float4" );
meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) );
Var *detailBumpScale = new Var;
detailBumpScale->setType( "float" );
detailBumpScale->setName( "detailBumpStrength" );
detailBumpScale->uniform = true;
detailBumpScale->constSortPos = cspPass;
meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpNorm, detailBump, detailBumpScale ) );
}
// We transform it into world space by reversing the
// multiplication by the worldToTanget transform.
Var *wsNormal = new Var( "wsNormal", "float3" );
Var *worldToTanget = getInWorldToTangent( componentList );
meta->addStatement( new GenOp( " @ = normalize( mul( @.xyz, @ ) );\r\n", new DecOp( wsNormal ), bumpNorm, worldToTanget ) );
}
ShaderFeature::Resources BumpFeatHLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
// If we have no parallax then we bring on the normal tex.
if ( !fd.features[MFT_Parallax] )
res.numTex = 1;
// Only the parallax or diffuse map will add texture
// coords other than us.
if ( !fd.features[MFT_Parallax] &&
!fd.features[MFT_DiffuseMap] &&
!fd.features[MFT_OverlayMap] &&
!fd.features[MFT_DetailMap] )
res.numTexReg++;
// We pass the world to tanget space transform.
res.numTexReg += 3;
// Do we have detail normal mapping?
if ( fd.features[MFT_DetailNormalMap] )
{
res.numTex++;
if ( !fd.features[MFT_DetailMap] )
res.numTexReg++;
}
return res;
}
void BumpFeatHLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
// If we had a parallax feature then it takes
// care of hooking up the normal map texture.
if ( fd.features[MFT_Parallax] )
return;
if ( fd.features[MFT_NormalMap] )
{
passData.mTexType[ texIndex ] = Material::Bump;
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
}
if ( fd.features[ MFT_DetailNormalMap ] )
{
passData.mTexType[ texIndex ] = Material::DetailBump;
passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
}
}
ParallaxFeatHLSL::ParallaxFeatHLSL()
: mIncludeDep( "shaders/common/torque.hlsl" )
{
addDependency( &mIncludeDep );
}
Var* ParallaxFeatHLSL::_getUniformVar( const char *name, const char *type, ConstantSortPosition csp )
{
Var *theVar = (Var*)LangElement::find( name );
if ( !theVar )
{
theVar = new Var;
theVar->setType( type );
theVar->setName( name );
theVar->uniform = true;
theVar->constSortPos = csp;
}
return theVar;
}
void ParallaxFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatHLSL::processVert - We don't support SM 1.x!" );
MultiLine *meta = new MultiLine;
// Add the texture coords.
getOutTexCoord( "texCoord",
"float2",
true,
fd.features[MFT_TexAnim],
meta,
componentList );
// Grab the input position.
Var *inPos = (Var*)LangElement::find( "inPosition" );
if ( !inPos )
inPos = (Var*)LangElement::find( "position" );
// Get the object space eye position and the
// object to tangent space transform.
Var *eyePos = _getUniformVar( "eyePos", "float3", cspPrimitive );
Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd );
// Now send the negative view vector in tangent space to the pixel shader.
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD );
outNegViewTS->setName( "outNegViewTS" );
outNegViewTS->setStructName( "OUT" );
outNegViewTS->setType( "float3" );
meta->addStatement( new GenOp( " @ = mul( @, float3( @.xyz - @ ) );\r\n",
outNegViewTS, objToTangentSpace, inPos, eyePos ) );
// TODO: I'm at a loss at why i need to flip the binormal/y coord
// to get a good view vector for parallax. Lighting works properly
// with the TS matrix as is... but parallax does not.
//
// Someone figure this out!
//
meta->addStatement( new GenOp( " @.y = -@.y;\r\n", outNegViewTS, outNegViewTS ) );
// If we have texture anim matrix the tangent
// space view vector may need to be rotated.
Var *texMat = (Var*)LangElement::find( "texMat" );
if ( texMat )
{
meta->addStatement( new GenOp( " @ = mul(@, float4(@,0)).xyz;\r\n",
outNegViewTS, texMat, outNegViewTS ) );
}
output = meta;
}
void ParallaxFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatHLSL::processPix - We don't support SM 1.x!" );
MultiLine *meta = new MultiLine;
// Order matters... get this first!
Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// We need the negative tangent space view vector
// as in parallax mapping we step towards the camera.
Var *negViewTS = (Var*)LangElement::find( "negViewTS" );
if ( !negViewTS )
{
Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" );
if ( !inNegViewTS )
{
inNegViewTS = connectComp->getElement( RT_TEXCOORD );
inNegViewTS->setName( "outNegViewTS" );
inNegViewTS->setStructName( "IN" );
inNegViewTS->setType( "float3" );
}
negViewTS = new Var( "negViewTS", "float3" );
meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) );
}
// Get the rest of our inputs.
Var *parallaxInfo = _getUniformVar( "parallaxInfo", "float", cspPotentialPrimitive );
Var *normalMap = getNormalMapTex();
// Call the library function to do the rest.
meta->addStatement( new GenOp( " @.xy += parallaxOffset( @, @.xy, @, @ );\r\n",
texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
// TODO: Fix second UV maybe?
output = meta;
}
ShaderFeature::Resources ParallaxFeatHLSL::getResources( const MaterialFeatureData &fd )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatHLSL::getResources - We don't support SM 1.x!" );
Resources res;
// We add the outViewTS to the outputstructure.
res.numTexReg = 1;
// If this isn't a prepass then we will be
// creating the normal map here.
if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
res.numTex = 1;
return res;
}
void ParallaxFeatHLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
AssertFatal( GFX->getPixelShaderVersion() >= 2.0,
"ParallaxFeatHLSL::setTexData - We don't support SM 1.x!" );
GFXTextureObject *tex = stageDat.getTex( MFT_NormalMap );
if ( tex )
{
passData.mTexType[ texIndex ] = Material::Bump;
passData.mTexSlot[ texIndex++ ].texObject = tex;
}
}
void NormalsOutFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
// If we have normal maps then we can count
// on it to generate the world space normal.
if ( fd.features[MFT_NormalMap] )
return;
MultiLine *meta = new MultiLine;
output = meta;
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outNormal = connectComp->getElement( RT_TEXCOORD );
outNormal->setName( "wsNormal" );
outNormal->setStructName( "OUT" );
outNormal->setType( "float3" );
outNormal->mapsToSampler = false;
// Find the incoming vertex normal.
Var *inNormal = (Var*)LangElement::find( "normal" );
if ( inNormal )
{
// Transform the normal to world space.
Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
meta->addStatement( new GenOp( " @ = mul( @, normalize( @ ) );\r\n", outNormal, objTrans, inNormal ) );
}
else
{
// If we don't have a vertex normal... just pass the
// camera facing normal to the pixel shader.
meta->addStatement( new GenOp( " @ = float3( 0.0, 0.0, 1.0 );\r\n", outNormal ) );
}
}
void NormalsOutFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
Var *wsNormal = (Var*)LangElement::find( "wsNormal" );
if ( !wsNormal )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
wsNormal = connectComp->getElement( RT_TEXCOORD );
wsNormal->setName( "wsNormal" );
wsNormal->setStructName( "IN" );
wsNormal->setType( "float3" );
// If we loaded the normal its our resposibility
// to normalize it... the interpolators won't.
//
// Note we cast to half here to get partial precision
// optimized code which is an acceptable loss of
// precision for normals and performs much better
// on older Geforce cards.
//
meta->addStatement( new GenOp( " @ = normalize( half3( @ ) );\r\n", wsNormal, wsNormal ) );
}
LangElement *normalOut;
Var *outColor = (Var*)LangElement::find( "col" );
if ( outColor && !fd.features[MFT_AlphaTest] )
normalOut = new GenOp( "float4( ( -@ + 1 ) * 0.5, @.a )", wsNormal, outColor );
else
normalOut = new GenOp( "float4( ( -@ + 1 ) * 0.5, 1 )", wsNormal );
meta->addStatement( new GenOp( " @;\r\n",
assignColor( normalOut, Material::None ) ) );
}

View file

@ -0,0 +1,106 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _BUMP_HLSL_H_
#define _BUMP_HLSL_H_
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#endif
#ifndef _LANG_ELEMENT_H_
#include "shaderGen/langElement.h"
#endif
struct RenderPassData;
class MultiLine;
/// The Bumpmap feature will read the normal map and
/// transform it by the inverse of the worldToTanget
/// matrix. This normal is then used by subsequent
/// shader features.
class BumpFeatHLSL : public ShaderFeatureHLSL
{
public:
// ShaderFeatureHLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName() { return "Bumpmap"; }
};
/// This feature either generates the cheap yet effective offset
/// mapping style parallax or the much more expensive occlusion
/// mapping technique based on the enabled feature flags.
class ParallaxFeatHLSL : public ShaderFeatureHLSL
{
protected:
static Var* _getUniformVar( const char *name,
const char *type,
ConstantSortPosition csp );
ShaderIncludeDependency mIncludeDep;
public:
ParallaxFeatHLSL();
// ShaderFeatureHLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName() { return "Parallax"; }
};
/// This feature is used to render normals to the
/// diffuse target for imposter rendering.
class NormalsOutFeatHLSL : public ShaderFeatureHLSL
{
public:
// ShaderFeatureHLSL
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual String getName() { return "NormalsOut"; }
};
#endif // _BUMP_HLSL_H_

View file

@ -0,0 +1,173 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/depthHLSL.h"
#include "materials/materialFeatureTypes.h"
#include "materials/materialFeatureData.h"
void EyeSpaceDepthOutHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
output = meta;
// grab output
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *outWSEyeVec = connectComp->getElement( RT_TEXCOORD );
outWSEyeVec->setName( "wsEyeVec" );
outWSEyeVec->setStructName( "OUT" );
// grab incoming vert position
Var *wsPosition = new Var( "depthPos", "float3" );
getWsPosition( componentList, fd.features[MFT_UseInstancing], meta, new DecOp( wsPosition ) );
Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
if( !eyePos )
{
eyePos = new Var;
eyePos->setType("float3");
eyePos->setName("eyePosWorld");
eyePos->uniform = true;
eyePos->constSortPos = cspPass;
}
meta->addStatement( new GenOp( " @ = float4( @.xyz - @, 1 );\r\n", outWSEyeVec, wsPosition, eyePos ) );
}
void EyeSpaceDepthOutHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
// grab connector position
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
Var *wsEyeVec = connectComp->getElement( RT_TEXCOORD );
wsEyeVec->setName( "wsEyeVec" );
wsEyeVec->setStructName( "IN" );
wsEyeVec->setType( "float4" );
wsEyeVec->mapsToSampler = false;
wsEyeVec->uniform = false;
// get shader constants
Var *vEye = new Var;
vEye->setType("float3");
vEye->setName("vEye");
vEye->uniform = true;
vEye->constSortPos = cspPass;
// Expose the depth to the depth format feature
Var *depthOut = new Var;
depthOut->setType("float");
depthOut->setName(getOutputVarName());
LangElement *depthOutDecl = new DecOp( depthOut );
meta->addStatement( new GenOp( "#ifndef CUBE_SHADOW_MAP\r\n" ) );
meta->addStatement( new GenOp( " @ = dot(@, (@.xyz / @.w));\r\n", depthOutDecl, vEye, wsEyeVec, wsEyeVec ) );
meta->addStatement( new GenOp( "#else\r\n" ) );
Var *farDist = (Var*)Var::find( "oneOverFarplane" );
if ( !farDist )
{
farDist = new Var;
farDist->setType("float4");
farDist->setName("oneOverFarplane");
farDist->uniform = true;
farDist->constSortPos = cspPass;
}
meta->addStatement( new GenOp( " @ = length( @.xyz / @.w ) * @.x;\r\n", depthOutDecl, wsEyeVec, wsEyeVec, farDist ) );
meta->addStatement( new GenOp( "#endif\r\n" ) );
// If there isn't an output conditioner for the pre-pass, than just write
// out the depth to rgba and return.
if( !fd.features[MFT_PrePassConditioner] )
meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "float4(@.rrr,1)", depthOut ), Material::None ) ) );
output = meta;
}
ShaderFeature::Resources EyeSpaceDepthOutHLSL::getResources( const MaterialFeatureData &fd )
{
Resources temp;
// Passing from VS->PS:
// - world space position (wsPos)
temp.numTexReg = 1;
return temp;
}
void DepthOutHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// Grab the output vert.
Var *outPosition = (Var*)LangElement::find( "hpos" );
// Grab our output depth.
Var *outDepth = connectComp->getElement( RT_TEXCOORD );
outDepth->setName( "depth" );
outDepth->setStructName( "OUT" );
outDepth->setType( "float" );
output = new GenOp( " @ = @.z / @.w;\r\n", outDepth, outPosition, outPosition );
}
void DepthOutHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// grab connector position
Var *depthVar = connectComp->getElement( RT_TEXCOORD );
depthVar->setName( "depth" );
depthVar->setStructName( "IN" );
depthVar->setType( "float" );
depthVar->mapsToSampler = false;
depthVar->uniform = false;
/*
// Expose the depth to the depth format feature
Var *depthOut = new Var;
depthOut->setType("float");
depthOut->setName(getOutputVarName());
*/
LangElement *depthOut = new GenOp( "float4( @, 0, 0, 1 )", depthVar );
output = new GenOp( " @;\r\n", assignColor( depthOut, Material::None ) );
}
ShaderFeature::Resources DepthOutHLSL::getResources( const MaterialFeatureData &fd )
{
// We pass the depth to the pixel shader.
Resources temp;
temp.numTexReg = 1;
return temp;
}

View file

@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _DEPTH_HLSL_H_
#define _DEPTH_HLSL_H_
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#endif
#ifndef _SHADEROP_H_
#include "shaderGen/shaderOp.h"
#endif
class EyeSpaceDepthOutHLSL : public ShaderFeatureHLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Eye Space Depth (Out)"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual const char* getOutputVarName() const { return "eyeSpaceDepth"; }
};
class DepthOutHLSL : public ShaderFeatureHLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Depth (Out)"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual const char* getOutputVarName() const { return "IN.depth"; }
};
#endif // _DEPTH_HLSL_H_

View file

@ -0,0 +1,163 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/paraboloidHLSL.h"
#include "lighting/lightInfo.h"
#include "materials/sceneData.h"
#include "materials/materialFeatureTypes.h"
#include "materials/materialFeatureData.h"
#include "gfx/gfxShader.h"
void ParaboloidVertTransformHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
MultiLine *meta = new MultiLine;
// First check for an input position from a previous feature
// then look for the default vertex position.
Var *inPosition = (Var*)LangElement::find( "inPosition" );
if ( !inPosition )
inPosition = (Var*)LangElement::find( "position" );
const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ];
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
// Grab connector out position.
Var *outPosition = connectComp->getElement( RT_POSITION );
outPosition->setName( "hpos" );
outPosition->setStructName( "OUT" );
// Get the atlas scale.
Var *atlasScale = new Var;
atlasScale->setType( "float2" );
atlasScale->setName( "atlasScale" );
atlasScale->uniform = true;
atlasScale->constSortPos = cspPass;
// Transform into camera space
Var *worldViewOnly = getWorldView( componentList, fd.features[MFT_UseInstancing], meta );
// So what we're doing here is transforming into camera space, and
// then directly manipulate into shadowmap space.
//
// http://www.gamedev.net/reference/articles/article2308.asp
// Swizzle z and y post-transform
meta->addStatement( new GenOp( " @ = mul(@, float4(@.xyz,1)).xzyw;\r\n", outPosition, worldViewOnly, inPosition ) );
meta->addStatement( new GenOp( " float L = length(@.xyz);\r\n", outPosition ) );
if ( isSinglePass )
{
// Flip the z in the back case
Var *outIsBack = connectComp->getElement( RT_TEXCOORD );
outIsBack->setType( "float" );
outIsBack->setName( "isBack" );
outIsBack->setStructName( "OUT" );
meta->addStatement( new GenOp( " bool isBack = @.z < 0.0;\r\n", outPosition ) );
meta->addStatement( new GenOp( " @ = isBack ? -1.0 : 1.0;\r\n", outIsBack ) );
meta->addStatement( new GenOp( " if ( isBack ) @.z = -@.z;\r\n", outPosition, outPosition ) );
}
meta->addStatement( new GenOp( " @ /= L;\r\n", outPosition ) );
meta->addStatement( new GenOp( " @.z = @.z + 1.0;\r\n", outPosition, outPosition ) );
meta->addStatement( new GenOp( " @.xy /= @.z;\r\n", outPosition, outPosition ) );
// Get the light parameters.
Var *lightParams = new Var;
lightParams->setType( "float4" );
lightParams->setName( "lightParams" );
lightParams->uniform = true;
lightParams->constSortPos = cspPass;
// TODO: If we change other shadow shaders to write out
// linear depth, than fix this as well!
//
// (L - zNear)/(lightParams.x - zNear);
//
meta->addStatement( new GenOp( " @.z = L / @.x;\r\n", outPosition, lightParams ) );
meta->addStatement( new GenOp( " @.w = 1.0;\r\n", outPosition ) );
// Pass unmodified to pixel shader to allow it to clip properly.
Var *outPosXY = connectComp->getElement( RT_TEXCOORD );
outPosXY->setType( "float2" );
outPosXY->setName( "posXY" );
outPosXY->setStructName( "OUT" );
meta->addStatement( new GenOp( " @ = @.xy;\r\n", outPosXY, outPosition ) );
// Scale and offset so it shows up in the atlas properly.
meta->addStatement( new GenOp( " @.xy *= @.xy;\r\n", outPosition, atlasScale ) );
if ( isSinglePass )
meta->addStatement( new GenOp( " @.x += isBack ? 0.5 : -0.5;\r\n", outPosition ) );
else
{
Var *atlasOffset = new Var;
atlasOffset->setType( "float2" );
atlasOffset->setName( "atlasXOffset" );
atlasOffset->uniform = true;
atlasOffset->constSortPos = cspPass;
meta->addStatement( new GenOp( " @.xy += @;\r\n", outPosition, atlasOffset ) );
}
output = meta;
}
void ParaboloidVertTransformHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
MultiLine *meta = new MultiLine;
const bool isSinglePass = fd.features[ MFT_IsSinglePassParaboloid ];
if ( isSinglePass )
{
// Cull things on the back side of the map.
Var *isBack = connectComp->getElement( RT_TEXCOORD );
isBack->setName( "isBack" );
isBack->setStructName( "IN" );
isBack->setType( "float" );
meta->addStatement( new GenOp( " clip( abs( @ ) - 0.999 );\r\n", isBack ) );
}
// Cull pixels outside of the valid paraboloid.
Var *posXY = connectComp->getElement( RT_TEXCOORD );
posXY->setName( "posXY" );
posXY->setStructName( "IN" );
posXY->setType( "float2" );
meta->addStatement( new GenOp( " clip( 1.0 - abs(@.x) );\r\n", posXY ) );
output = meta;
}
ShaderFeature::Resources ParaboloidVertTransformHLSL::getResources( const MaterialFeatureData &fd )
{
Resources temp;
temp.numTexReg = 2;
return temp;
}

View file

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _PARABOLOID_HLSL_H_
#define _PARABOLOID_HLSL_H_
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#endif
#ifndef _SHADEROP_H_
#include "shaderGen/shaderOp.h"
#endif
class GFXShaderConstHandle;
class ParaboloidVertTransformHLSL : public ShaderFeatureHLSL
{
public:
// ShaderFeature
virtual void processVert( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName() { return "Paraboloid Vert Transform"; }
virtual Material::BlendOp getBlendOp() { return Material::None; }
};
#endif // _PARABOLOID_HLSL_H_

View file

@ -0,0 +1,152 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/pixSpecularHLSL.h"
#include "materials/processedMaterial.h"
#include "materials/materialFeatureTypes.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/shaderGenVars.h"
#include "gfx/gfxStructs.h"
PixelSpecularHLSL::PixelSpecularHLSL()
: mDep( "shaders/common/lighting.hlsl" )
{
addDependency( &mDep );
}
void PixelSpecularHLSL::processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( fd.features[MFT_RTLighting],
"PixelSpecularHLSL requires RTLighting to be enabled!" );
// Nothing to do here... MFT_RTLighting should have
// taken care of passing everything to the pixel shader.
}
void PixelSpecularHLSL::processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{
AssertFatal( fd.features[MFT_RTLighting],
"PixelSpecularHLSL requires RTLighting to be enabled!" );
// RTLighting should have spit out the 4 specular
// powers for the 4 potential lights on this pass.
//
// This can sometimes be NULL if RTLighting skips out
// on us for lightmaps or missing normals.
Var *specular = (Var*)LangElement::find( "specular" );
if ( !specular )
return;
MultiLine *meta = new MultiLine;
LangElement *specMul = new GenOp( "@", specular );
LangElement *final = specMul;
// mask out with lightmap if present
if ( fd.features[MFT_LightMap] )
{
LangElement *lmColor = NULL;
// find lightmap color
lmColor = LangElement::find( "lmColor" );
if ( !lmColor )
{
LangElement * lightMap = LangElement::find( "lightMap" );
LangElement * lmCoord = LangElement::find( "texCoord2" );
lmColor = new GenOp( "tex2D(@, @)", lightMap, lmCoord );
}
final = new GenOp( "@ * float4(@.rgb,0)", specMul, lmColor );
}
// If we have a normal map then mask the specular
if ( fd.features[MFT_SpecularMap] )
{
Var *specularColor = (Var*)LangElement::find( "specularColor" );
if (specularColor)
final = new GenOp( "@ * @", final, specularColor );
}
else if ( fd.features[MFT_NormalMap] && !fd.features[MFT_IsDXTnm] )
{
Var *bumpColor = (Var*)LangElement::find( "bumpNormal" );
final = new GenOp( "@ * @.a", final, bumpColor );
}
// Add the specular to the final color.
// search for color var
Var *color = (Var*)LangElement::find( "col" );
meta->addStatement( new GenOp( " @.rgb += ( @ ).rgb;\r\n", color, final ) );
output = meta;
}
ShaderFeature::Resources PixelSpecularHLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
return res;
}
void SpecularMapHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
{
// Get the texture coord.
Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
// create texture var
Var *specularMap = new Var;
specularMap->setType( "sampler2D" );
specularMap->setName( "specularMap" );
specularMap->uniform = true;
specularMap->sampler = true;
specularMap->constNum = Var::getTexUnitNum();
LangElement *texOp = new GenOp( "tex2D(@, @)", specularMap, texCoord );
Var *specularColor = new Var( "specularColor", "float4" );
output = new GenOp( " @ = @;\r\n", new DecOp( specularColor ), texOp );
}
ShaderFeature::Resources SpecularMapHLSL::getResources( const MaterialFeatureData &fd )
{
Resources res;
res.numTex = 1;
return res;
}
void SpecularMapHLSL::setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex )
{
GFXTextureObject *tex = stageDat.getTex( MFT_SpecularMap );
if ( tex )
{
passData.mTexType[ texIndex ] = Material::Standard;
passData.mTexSlot[ texIndex++ ].texObject = tex;
}
}

View file

@ -0,0 +1,77 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _PIXSPECULAR_HLSL_H_
#define _PIXSPECULAR_HLSL_H_
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#endif
/// A per-pixel specular feature.
class PixelSpecularHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mDep;
public:
PixelSpecularHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName()
{
return "Pixel Specular";
}
};
/// A texture source for the PixSpecular feature
class SpecularMapHLSL : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Specular Map";
}
};
#endif // _PIXSPECULAR_HLSL_H_

View file

@ -0,0 +1,349 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/shaderCompHLSL.h"
#include "shaderGen/shaderComp.h"
#include "shaderGen/langElement.h"
#include "gfx/gfxDevice.h"
Var * ShaderConnectorHLSL::getElement( RegisterType type,
U32 numElements,
U32 numRegisters )
{
Var *ret = getIndexedElement( mCurTexElem, type, numElements, numRegisters );
// Adjust texture offset if this is a texcoord type
if( type == RT_TEXCOORD )
{
if ( numRegisters != -1 )
mCurTexElem += numRegisters;
else
mCurTexElem += numElements;
}
return ret;
}
Var * ShaderConnectorHLSL::getIndexedElement( U32 index, RegisterType type, U32 numElements /*= 1*/, U32 numRegisters /*= -1 */ )
{
switch( type )
{
case RT_POSITION:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "POSITION" );
return newVar;
}
case RT_NORMAL:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "NORMAL" );
return newVar;
}
case RT_BINORMAL:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "BINORMAL" );
return newVar;
}
case RT_TANGENT:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "TANGENT" );
return newVar;
}
case RT_COLOR:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "COLOR" );
return newVar;
}
case RT_VPOS:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
newVar->setConnectName( "VPOS" );
return newVar;
}
case RT_TEXCOORD:
{
Var *newVar = new Var;
mElementList.push_back( newVar );
// This was needed for hardware instancing, but
// i don't really remember why right now.
if ( index > mCurTexElem )
mCurTexElem = index + 1;
char out[32];
dSprintf( (char*)out, sizeof(out), "TEXCOORD%d", index );
newVar->setConnectName( out );
newVar->constNum = index;
newVar->arraySize = numElements;
return newVar;
}
default:
break;
}
return NULL;
}
void ShaderConnectorHLSL::sortVars()
{
if ( GFX->getPixelShaderVersion() >= 2.0 )
return;
// Sort connector variables - They must be sorted on hardware that is running
// ps 1.4 and below. The reason is that texture coordinate registers MUST
// map exactly to their respective texture stage. Ie. if you have fog
// coordinates being passed into a pixel shader in texture coordinate register
// number 4, the fog texture MUST reside in texture stage 4 for it to work.
// The problem is solved by pushing non-texture coordinate data to the end
// of the structure so that the texture coodinates are all at the "top" of the
// structure in the order that the features are processed.
// create list of just the texCoords, sorting by 'mapsToSampler'
Vector< Var * > texCoordList;
// - first pass is just coords mapped to a sampler
for( U32 i=0; i<mElementList.size(); i++ )
{
Var *var = mElementList[i];
if( var->mapsToSampler )
{
texCoordList.push_back( var );
}
}
// - next pass is for the others
for( U32 i=0; i<mElementList.size(); i++ )
{
Var *var = mElementList[i];
if( dStrstr( (const char *)var->connectName, "TEX" ) &&
!var->mapsToSampler )
{
texCoordList.push_back( var );
}
}
// rename the connectNames
for( U32 i=0; i<texCoordList.size(); i++ )
{
char out[32];
dSprintf( (char*)out, sizeof(out), "TEXCOORD%d", i );
texCoordList[i]->setConnectName( out );
}
// write new, sorted list over old one
if( texCoordList.size() )
{
U32 index = 0;
for( U32 i=0; i<mElementList.size(); i++ )
{
Var *var = mElementList[i];
if( dStrstr( (const char *)var->connectName, "TEX" ) )
{
mElementList[i] = texCoordList[index];
index++;
}
}
}
}
void ShaderConnectorHLSL::setName( char *newName )
{
dStrcpy( (char*)mName, newName );
}
void ShaderConnectorHLSL::reset()
{
for( U32 i=0; i<mElementList.size(); i++ )
{
mElementList[i] = NULL;
}
mElementList.setSize( 0 );
mCurTexElem = 0;
}
void ShaderConnectorHLSL::print( Stream &stream )
{
const char * header = "struct ";
const char * header2 = "\r\n{\r\n";
const char * footer = "};\r\n\r\n\r\n";
stream.write( dStrlen(header), header );
stream.write( dStrlen((char*)mName), mName );
stream.write( dStrlen(header2), header2 );
// print out elements
for( U32 i=0; i<mElementList.size(); i++ )
{
U8 output[256];
Var *var = mElementList[i];
if (var->arraySize <= 1)
dSprintf( (char*)output, sizeof(output), " %s %-15s : %s;\r\n", var->type, var->name, var->connectName );
else
dSprintf( (char*)output, sizeof(output), " %s %s[%d] : %s;\r\n", var->type, var->name, var->arraySize, var->connectName );
stream.write( dStrlen((char*)output), output );
}
stream.write( dStrlen(footer), footer );
}
void ParamsDefHLSL::assignConstantNumbers()
{
// Here we assign constant number to uniform vars, sorted
// by their update frequency.
U32 mCurrConst = 0;
for (U32 bin = cspUninit+1; bin < csp_Count; bin++)
{
// Find all the uniform variables that are part of this group and assign constant numbers
for( U32 i=0; i<LangElement::elementList.size(); i++)
{
Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
if( var )
{
bool shaderConst = var->uniform && !var->sampler;
AssertFatal((!shaderConst) || var->constSortPos != cspUninit, "Const sort position has not been set, variable will not receive a constant number!!");
if( shaderConst && var->constSortPos == bin)
{
var->constNum = mCurrConst;
// Increment our constant number based on the variable type
if (dStrcmp((const char*)var->type, "float4x4") == 0)
{
mCurrConst += (4 * var->arraySize);
} else {
if (dStrcmp((const char*)var->type, "float3x3") == 0)
{
mCurrConst += (3 * var->arraySize);
} else {
mCurrConst += var->arraySize;
}
}
}
}
}
}
}
void VertexParamsDefHLSL::print( Stream &stream )
{
assignConstantNumbers();
const char *opener = "ConnectData main( VertData IN";
stream.write( dStrlen(opener), opener );
// find all the uniform variables and print them out
for( U32 i=0; i<LangElement::elementList.size(); i++)
{
Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
if( var )
{
if( var->uniform )
{
const char* nextVar = ",\r\n ";
stream.write( dStrlen(nextVar), nextVar );
U8 varNum[64];
dSprintf( (char*)varNum, sizeof(varNum), "register(C%d)", var->constNum );
U8 output[256];
if (var->arraySize <= 1)
dSprintf( (char*)output, sizeof(output), "uniform %-8s %-15s : %s", var->type, var->name, varNum );
else
dSprintf( (char*)output, sizeof(output), "uniform %-8s %s[%d] : %s", var->type, var->name, var->arraySize, varNum );
stream.write( dStrlen((char*)output), output );
}
}
}
const char *closer = "\r\n)\r\n{\r\n ConnectData OUT;\r\n\r\n";
stream.write( dStrlen(closer), closer );
}
void PixelParamsDefHLSL::print( Stream &stream )
{
assignConstantNumbers();
const char * opener = "Fragout main( ConnectData IN";
stream.write( dStrlen(opener), opener );
// find all the sampler & uniform variables and print them out
for( U32 i=0; i<LangElement::elementList.size(); i++)
{
Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
if( var )
{
if( var->uniform )
{
WRITESTR( ",\r\n " );
U8 varNum[32];
if( var->sampler )
{
dSprintf( (char*)varNum, sizeof(varNum), "register(S%d)", var->constNum );
}
else
{
dSprintf( (char*)varNum, sizeof(varNum), "register(C%d)", var->constNum );
}
U8 output[256];
if (var->arraySize <= 1)
dSprintf( (char*)output, sizeof(output), "uniform %-9s %-15s : %s", var->type, var->name, varNum );
else
dSprintf( (char*)output, sizeof(output), "uniform %-9s %s[%d] : %s", var->type, var->name, var->arraySize, varNum );
WRITESTR( (char*) output );
}
}
}
const char *closer = "\r\n)\r\n{\r\n Fragout OUT;\r\n\r\n";
stream.write( dStrlen(closer), closer );
}

View file

@ -0,0 +1,72 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERCOMP_HLSL_H_
#define _SHADERCOMP_HLSL_H_
#ifndef _SHADERCOMP_H_
#include "shaderGen/shaderComp.h"
#endif
class ShaderConnectorHLSL : public ShaderConnector
{
public:
// ShaderConnector
virtual Var* getElement( RegisterType type,
U32 numElements = 1,
U32 numRegisters = -1 );
virtual Var* getIndexedElement( U32 index,
RegisterType type,
U32 numElements = 1,
U32 numRegisters = -1 );
virtual void setName( char *newName );
virtual void reset();
virtual void sortVars();
virtual void print( Stream &stream );
};
class ParamsDefHLSL : public ParamsDef
{
protected:
virtual void assignConstantNumbers();
};
class VertexParamsDefHLSL : public ParamsDefHLSL
{
public:
virtual void print( Stream &stream );
};
class PixelParamsDefHLSL : public ParamsDefHLSL
{
public:
virtual void print( Stream &stream );
};
#endif // _SHADERCOMP_HLSL_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,654 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#define _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
#ifndef _SHADERFEATURE_H_
#include "shaderGen/shaderFeature.h"
#endif
struct LangElement;
struct MaterialFeatureData;
struct RenderPassData;
class ShaderFeatureHLSL : public ShaderFeature
{
public:
ShaderFeatureHLSL();
///
Var* getOutTexCoord( const char *name,
const char *type,
bool mapsToSampler,
bool useTexAnim,
MultiLine *meta,
Vector<ShaderComponent*> &componentList );
/// Returns an input texture coord by name adding it
/// to the input connector if it doesn't exist.
static Var* getInTexCoord( const char *name,
const char *type,
bool mapsToSampler,
Vector<ShaderComponent*> &componentList );
static Var* getInColor( const char *name,
const char *type,
Vector<ShaderComponent*> &componentList );
///
static Var* addOutVpos( MultiLine *meta,
Vector<ShaderComponent*> &componentList );
/// Returns the VPOS input register for the pixel shader.
static Var* getInVpos( MultiLine *meta,
Vector<ShaderComponent*> &componentList );
/// Returns the "objToTangentSpace" transform or creates one if this
/// is the first feature to need it.
Var* getOutObjToTangentSpace( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the existing output "outWorldToTangent" transform or
/// creates one if this is the first feature to need it.
Var* getOutWorldToTangent( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the input "worldToTanget" space transform
/// adding it to the input connector if it doesn't exist.
static Var* getInWorldToTangent( Vector<ShaderComponent*> &componentList );
/// Returns the existing output "outViewToTangent" transform or
/// creates one if this is the first feature to need it.
Var* getOutViewToTangent( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
const MaterialFeatureData &fd );
/// Returns the input "viewToTangent" space transform
/// adding it to the input connector if it doesn't exist.
static Var* getInViewToTangent( Vector<ShaderComponent*> &componentList );
/// Calculates the world space position in the vertex shader and
/// assigns it to the passed language element. It does not pass
/// it across the connector to the pixel shader.
/// @see addOutWsPosition
void getWsPosition( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta,
LangElement *wsPosition );
/// Adds the "wsPosition" to the input connector if it doesn't exist.
Var* addOutWsPosition( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
/// Returns the input world space position from the connector.
static Var* getInWsPosition( Vector<ShaderComponent*> &componentList );
/// Returns the world space view vector from the wsPosition.
static Var* getWsView( Var *wsPosition, MultiLine *meta );
/// Returns the input normal map texture.
static Var* getNormalMapTex();
///
Var* addOutDetailTexCoord( Vector<ShaderComponent*> &componentList,
MultiLine *meta,
bool useTexAnim );
///
Var* getObjTrans( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getModelView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getWorldView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
///
Var* getInvWorldView( Vector<ShaderComponent*> &componentList,
bool useInstancing,
MultiLine *meta );
// ShaderFeature
Var* getVertTexCoord( const String &name );
LangElement* setupTexSpaceMat( Vector<ShaderComponent*> &componentList, Var **texSpaceMat );
LangElement* assignColor( LangElement *elem, Material::BlendOp blend, LangElement *lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget );
LangElement* expandNormalMap( LangElement *sampleNormalOp, LangElement *normalDecl, LangElement *normalVar, const MaterialFeatureData &fd );
};
class NamedFeatureHLSL : public ShaderFeatureHLSL
{
protected:
String mName;
public:
NamedFeatureHLSL( const String &name )
: mName( name )
{}
virtual String getName() { return mName; }
};
class RenderTargetZeroHLSL : public ShaderFeatureHLSL
{
protected:
ShaderFeature::OutputTarget mOutputTargetMask;
String mFeatureName;
public:
RenderTargetZeroHLSL( const ShaderFeature::OutputTarget target )
: mOutputTargetMask( target )
{
char buffer[256];
dSprintf(buffer, sizeof(buffer), "Render Target Output = 0.0, output mask %04b", mOutputTargetMask);
mFeatureName = buffer;
}
virtual String getName() { return mFeatureName; }
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return mOutputTargetMask; }
};
/// Vertex position
class VertPositionHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Vert Position";
}
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData );
};
/// Vertex lighting based on the normal and the light
/// direction passed through the vertex color.
class RTLightingFeatHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mDep;
public:
RTLightingFeatHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual Resources getResources( const MaterialFeatureData &fd );
virtual String getName()
{
return "RT Lighting";
}
};
/// Base texture
class DiffuseMapFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Base Texture";
}
};
/// Overlay texture
class OverlayTexFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Overlay Texture";
}
};
/// Diffuse color
class DiffuseFeatureHLSL : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Diffuse Color";
}
};
/// Diffuse vertex color
class DiffuseVertColorFeatureHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector< ShaderComponent* >& componentList,
const MaterialFeatureData& fd );
virtual void processPix( Vector< ShaderComponent* >&componentList,
const MaterialFeatureData& fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Diffuse Vertex Color";
}
};
/// Lightmap
class LightmapFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Lightmap";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Tonemap
class TonemapFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Tonemap";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Baked lighting stored on the vertex color
class VertLitHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::None; }
virtual String getName()
{
return "Vert Lit";
}
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
};
/// Detail map
class DetailFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp(){ return Material::Mul; }
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Detail";
}
};
/// Reflect Cubemap
class ReflectCubeFeatHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
// Sets textures and texture flags for current pass
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex );
virtual String getName()
{
return "Reflect Cube";
}
};
/// Fog
class FogFeatHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mFogDep;
public:
FogFeatHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::LerpAlpha; }
virtual String getName()
{
return "Fog";
}
};
/// Tex Anim
class TexAnimHLSL : public ShaderFeatureHLSL
{
public:
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Texture Animation";
}
};
/// Visibility
class VisibilityFeatHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
public:
VisibilityFeatHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Resources getResources( const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Visibility";
}
};
///
class AlphaTestHLSL : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Alpha Test";
}
};
/// Special feature used to mask out the RGB color for
/// non-glow passes of glow materials.
/// @see RenderGlowMgr
class GlowMaskHLSL : public ShaderFeatureHLSL
{
public:
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName()
{
return "Glow Mask";
}
};
/// This should be the final feature on most pixel shaders which
/// encodes the color for the current HDR target format.
/// @see HDRPostFx
/// @see LightManager
/// @see torque.hlsl
class HDROutHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mTorqueDep;
public:
HDROutHLSL();
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual Material::BlendOp getBlendOp() { return Material::None; }
virtual String getName() { return "HDR Output"; }
};
///
class FoliageFeatureHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mDep;
public:
FoliageFeatureHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Foliage Feature";
}
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData );
virtual ShaderFeatureConstHandles* createConstHandles( GFXShader *shader, SimObject *userObject );
};
class ParticleNormalFeatureHLSL : public ShaderFeatureHLSL
{
public:
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName()
{
return "Particle Normal Generation Feature";
}
};
/// Special feature for unpacking imposter verts.
/// @see RenderImposterMgr
class ImposterVertFeatureHLSL : public ShaderFeatureHLSL
{
protected:
ShaderIncludeDependency mDep;
public:
ImposterVertFeatureHLSL();
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd );
virtual String getName() { return "Imposter Vert"; }
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData );
};
#endif // _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_

View file

@ -0,0 +1,199 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/HLSL/shaderGenHLSL.h"
#include "shaderGen/HLSL/shaderCompHLSL.h"
#include "shaderGen/featureMgr.h"
void ShaderGenPrinterHLSL::printShaderHeader(Stream& stream)
{
const char *header1 = "//*****************************************************************************\r\n";
const char *header2 = "// Torque -- HLSL procedural shader\r\n";
stream.write( dStrlen(header1), header1 );
stream.write( dStrlen(header2), header2 );
stream.write( dStrlen(header1), header1 );
const char* header3 = "\r\n";
stream.write( dStrlen(header3), header3 );
}
void ShaderGenPrinterHLSL::printMainComment(Stream& stream)
{
const char * header5 = "// Main\r\n";
const char * line = "//-----------------------------------------------------------------------------\r\n";
stream.write( dStrlen(line), line );
stream.write( dStrlen(header5), header5 );
stream.write( dStrlen(line), line );
}
void ShaderGenPrinterHLSL::printVertexShaderCloser(Stream& stream)
{
const char *closer = " return OUT;\r\n}\r\n";
stream.write( dStrlen(closer), closer );
}
void ShaderGenPrinterHLSL::printPixelShaderOutputStruct(Stream& stream, const MaterialFeatureData &featureData)
{
// Determine the number of output targets we need
U32 numMRTs = 0;
for( U32 i = 0; i < FEATUREMGR->getFeatureCount(); i++ )
{
const FeatureInfo &info = FEATUREMGR->getAt( i );
if( featureData.features.hasFeature( *info.type ) )
numMRTs |= info.feature->getOutputTargets( featureData );
}
WRITESTR( "struct Fragout\r\n" );
WRITESTR( "{\r\n" );
WRITESTR( " float4 col : COLOR0;\r\n" );
for( U32 i = 1; i < 4; i++ )
{
if( numMRTs & 1 << i )
WRITESTR( avar( " float4 col%d : COLOR%d;\r\n", i, i ) );
}
WRITESTR( "};\r\n" );
WRITESTR( "\r\n" );
WRITESTR( "\r\n" );
}
void ShaderGenPrinterHLSL::printPixelShaderCloser(Stream& stream)
{
WRITESTR( "\r\n return OUT;\r\n}\r\n" );
}
void ShaderGenPrinterHLSL::printLine(Stream& stream, const String& line)
{
stream.write(line.length(), line.c_str());
const char* end = "\r\n";
stream.write(dStrlen(end), end);
}
const char* ShaderGenComponentFactoryHLSL::typeToString( GFXDeclType type )
{
switch ( type )
{
default:
case GFXDeclType_Float:
return "float";
case GFXDeclType_Float2:
return "float2";
case GFXDeclType_Float3:
return "float3";
case GFXDeclType_Float4:
case GFXDeclType_Color:
return "float4";
}
}
ShaderComponent* ShaderGenComponentFactoryHLSL::createVertexInputConnector( const GFXVertexFormat &vertexFormat )
{
ShaderConnectorHLSL *vertComp = new ShaderConnectorHLSL;
vertComp->setName( "VertData" );
// Loop thru the vertex format elements.
for ( U32 i=0; i < vertexFormat.getElementCount(); i++ )
{
const GFXVertexElement &element = vertexFormat.getElement( i );
Var *var = NULL;
if ( element.isSemantic( GFXSemantic::POSITION ) )
{
var = vertComp->getElement( RT_POSITION );
var->setName( "position" );
}
else if ( element.isSemantic( GFXSemantic::NORMAL ) )
{
var = vertComp->getElement( RT_NORMAL );
var->setName( "normal" );
}
else if ( element.isSemantic( GFXSemantic::TANGENT ) )
{
var = vertComp->getElement( RT_TANGENT );
var->setName( "T" );
}
else if ( element.isSemantic( GFXSemantic::TANGENTW ) )
{
var = vertComp->getIndexedElement( element.getSemanticIndex(), RT_TEXCOORD );
var->setName( "tangentW" );
}
else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
{
var = vertComp->getElement( RT_BINORMAL );
var->setName( "B" );
}
else if ( element.isSemantic( GFXSemantic::COLOR ) )
{
var = vertComp->getElement( RT_COLOR );
var->setName( "diffuse" );
}
else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
{
var = vertComp->getIndexedElement( element.getSemanticIndex(), RT_TEXCOORD );
if ( element.getSemanticIndex() == 0 )
var->setName( "texCoord" );
else
var->setName( String::ToString( "texCoord%d", element.getSemanticIndex() + 1 ) );
}
else
{
// Everything else is a texcoord!
var = vertComp->getIndexedElement( element.getSemanticIndex(), RT_TEXCOORD );
var->setName( "tc" + element.getSemantic() );
}
if ( !var )
continue;
var->setStructName( "IN" );
var->setType( typeToString( element.getType() ) );
}
return vertComp;
}
ShaderComponent* ShaderGenComponentFactoryHLSL::createVertexPixelConnector()
{
ShaderComponent* comp = new ShaderConnectorHLSL;
((ShaderConnector*)comp)->setName("ConnectData");
return comp;
}
ShaderComponent* ShaderGenComponentFactoryHLSL::createVertexParamsDef()
{
ShaderComponent* comp = new VertexParamsDefHLSL;
return comp;
}
ShaderComponent* ShaderGenComponentFactoryHLSL::createPixelParamsDef()
{
ShaderComponent* comp = new PixelParamsDefHLSL;
return comp;
}

View file

@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGEN_HLSL_H_
#define _SHADERGEN_HLSL_H_
#ifndef _SHADERGEN_H_
#include "shaderGen/shaderGen.h"
#endif
class ShaderGenPrinterHLSL : public ShaderGenPrinter
{
public:
// ShaderGenPrinter
virtual void printShaderHeader(Stream& stream);
virtual void printMainComment(Stream& stream);
virtual void printVertexShaderCloser(Stream& stream);
virtual void printPixelShaderOutputStruct(Stream& stream, const MaterialFeatureData &featureData);
virtual void printPixelShaderCloser(Stream& stream);
virtual void printLine(Stream& stream, const String& line);
};
class ShaderGenComponentFactoryHLSL : public ShaderGenComponentFactory
{
public:
/// Helper function for converting a vertex decl
/// type to an HLSL type string.
static const char* typeToString( GFXDeclType type );
// ShaderGenComponentFactory
virtual ShaderComponent* createVertexInputConnector( const GFXVertexFormat &vertexFormat );
virtual ShaderComponent* createVertexPixelConnector();
virtual ShaderComponent* createVertexParamsDef();
virtual ShaderComponent* createPixelParamsDef();
};
#endif // _SHADERGEN_HLSL_H_

View file

@ -0,0 +1,110 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderGen.h"
#include "shaderGen/HLSL/shaderGenHLSL.h"
#include "shaderGen/HLSL/shaderFeatureHLSL.h"
#include "shaderGen/featureMgr.h"
#include "shaderGen/HLSL/bumpHLSL.h"
#include "shaderGen/HLSL/pixSpecularHLSL.h"
#include "shaderGen/HLSL/depthHLSL.h"
#include "shaderGen/HLSL/paraboloidHLSL.h"
#include "materials/materialFeatureTypes.h"
#include "core/module.h"
static ShaderGen::ShaderGenInitDelegate sInitDelegate;
void _initShaderGenHLSL( ShaderGen *shaderGen )
{
shaderGen->setPrinter( new ShaderGenPrinterHLSL );
shaderGen->setComponentFactory( new ShaderGenComponentFactoryHLSL );
shaderGen->setFileEnding( "hlsl" );
FEATUREMGR->registerFeature( MFT_VertTransform, new VertPositionHLSL );
FEATUREMGR->registerFeature( MFT_RTLighting, new RTLightingFeatHLSL );
FEATUREMGR->registerFeature( MFT_IsDXTnm, new NamedFeatureHLSL( "DXTnm" ) );
FEATUREMGR->registerFeature( MFT_TexAnim, new TexAnimHLSL );
FEATUREMGR->registerFeature( MFT_DiffuseMap, new DiffuseMapFeatHLSL );
FEATUREMGR->registerFeature( MFT_OverlayMap, new OverlayTexFeatHLSL );
FEATUREMGR->registerFeature( MFT_DiffuseColor, new DiffuseFeatureHLSL );
FEATUREMGR->registerFeature( MFT_DiffuseVertColor, new DiffuseVertColorFeatureHLSL );
FEATUREMGR->registerFeature( MFT_AlphaTest, new AlphaTestHLSL );
FEATUREMGR->registerFeature( MFT_GlowMask, new GlowMaskHLSL );
FEATUREMGR->registerFeature( MFT_LightMap, new LightmapFeatHLSL );
FEATUREMGR->registerFeature( MFT_ToneMap, new TonemapFeatHLSL );
FEATUREMGR->registerFeature( MFT_VertLit, new VertLitHLSL );
FEATUREMGR->registerFeature( MFT_Parallax, new ParallaxFeatHLSL );
FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatHLSL );
FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureHLSL( "Detail Normal Map" ) );
FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatHLSL );
FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatHLSL );
FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularHLSL );
FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureHLSL( "Translucent" ) );
FEATUREMGR->registerFeature( MFT_IsTranslucentZWrite, new NamedFeatureHLSL( "Translucent ZWrite" ) );
FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
FEATUREMGR->registerFeature( MFT_Fog, new FogFeatHLSL );
FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapHLSL );
FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) );
FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureHLSL( "Diffuse Map Atlas" ) );
FEATUREMGR->registerFeature( MFT_NormalMapAtlas, new NamedFeatureHLSL( "Normal Map Atlas" ) );
FEATUREMGR->registerFeature( MFT_NormalsOut, new NormalsOutFeatHLSL );
FEATUREMGR->registerFeature( MFT_DepthOut, new DepthOutHLSL );
FEATUREMGR->registerFeature( MFT_EyeSpaceDepthOut, new EyeSpaceDepthOutHLSL() );
FEATUREMGR->registerFeature( MFT_HDROut, new HDROutHLSL );
FEATUREMGR->registerFeature( MFT_ParaboloidVertTransform, new ParaboloidVertTransformHLSL );
FEATUREMGR->registerFeature( MFT_IsSinglePassParaboloid, new NamedFeatureHLSL( "Single Pass Paraboloid" ) );
FEATUREMGR->registerFeature( MFT_UseInstancing, new NamedFeatureHLSL( "Hardware Instancing" ) );
FEATUREMGR->registerFeature( MFT_Foliage, new FoliageFeatureHLSL );
FEATUREMGR->registerFeature( MFT_ParticleNormal, new ParticleNormalFeatureHLSL );
FEATUREMGR->registerFeature( MFT_InterlacedPrePass, new NamedFeatureHLSL( "Interlaced Pre Pass" ) );
FEATUREMGR->registerFeature( MFT_ForwardShading, new NamedFeatureHLSL( "Forward Shaded Material" ) );
FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureHLSL );
}
MODULE_BEGIN( ShaderGenHLSL )
MODULE_INIT_AFTER( ShaderGen )
MODULE_INIT_AFTER( ShaderGenFeatureMgr )
MODULE_INIT
{
sInitDelegate.bind(_initShaderGenHLSL);
SHADERGEN->registerInitDelegate(Direct3D9, sInitDelegate);
SHADERGEN->registerInitDelegate(Direct3D9_360, sInitDelegate);
}
MODULE_END;

View file

@ -0,0 +1,241 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/conditionerFeature.h"
#include "shaderGen/shaderOp.h"
#include "shaderGen/featureMgr.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "core/stream/fileStream.h"
#include "materials/shaderData.h"
#include "core/util/safeDelete.h"
const String ConditionerFeature::ConditionerIncludeFileName = "autogenConditioners.h";
bool ConditionerFeature::smDirtyConditioners = true;
Vector<ConditionerFeature*> ConditionerFeature::smConditioners;
ConditionerFeature::ConditionerFeature( const GFXFormat bufferFormat )
: mBufferFormat(bufferFormat)
{
dMemset( mMethodDependency, 0, sizeof( mMethodDependency ) );
smConditioners.push_back( this );
smDirtyConditioners = true;
}
ConditionerFeature::~ConditionerFeature()
{
for( U32 i = 0; i < NumMethodTypes; i++ )
SAFE_DELETE( mMethodDependency[i] );
smConditioners.remove( this );
smDirtyConditioners = true;
}
LangElement *ConditionerFeature::assignOutput( Var *unconditionedOutput, ShaderFeature::OutputTarget outputTarget /* = ShaderFeature::DefaultTarget*/ )
{
LangElement *assign;
MultiLine *meta = new MultiLine;
meta->addStatement( new GenOp( avar( "\r\n\r\n // output buffer format: %s\r\n", GFXStringTextureFormat[getBufferFormat()] ) ) );
// condition the output
Var *conditionedOutput = _conditionOutput( unconditionedOutput, meta );
// search for color var
Var *color = (Var*) LangElement::find( getOutputTargetVarName(outputTarget) );
if ( !color )
{
// create color var
color = new Var;
if(GFX->getAdapterType() == OpenGL)
{
color->setName( getOutputTargetVarName(outputTarget) );
color->setType( "vec4" );
DecOp* colDecl = new DecOp(color);
assign = new GenOp( "@ = vec4(@)", colDecl, conditionedOutput );
}
else
{
color->setType( "fragout" );
color->setName( getOutputTargetVarName(outputTarget) );
color->setStructName( "OUT" );
assign = new GenOp( "@ = @", color, conditionedOutput );
}
}
else
{
if (GFX->getAdapterType() == OpenGL)
assign = new GenOp( "@ = vec4(@)", color, conditionedOutput);
else
assign = new GenOp( "@ = @", color, conditionedOutput );
}
meta->addStatement( new GenOp( " @;\r\n", assign ) );
return meta;
}
Var *ConditionerFeature::_conditionOutput( Var *unconditionedOutput, MultiLine *meta )
{
meta->addStatement( new GenOp( " // generic conditioner: no conditioning performed\r\n" ) );
return unconditionedOutput;
}
Var *ConditionerFeature::_unconditionInput( Var *conditionedInput, MultiLine *meta )
{
meta->addStatement( new GenOp( " // generic conditioner: no conditioning performed\r\n" ) );
return conditionedInput;
}
const String &ConditionerFeature::getShaderMethodName( MethodType methodType )
{
if ( mConditionMethodName.isEmpty() )
{
const U32 hash = getName().getHashCaseInsensitive();
mUnconditionMethodName = avar("autogen%s_%08x", "Uncondition", hash );
mConditionMethodName = avar("autogen%s_%08x", "Condition", hash );
}
return methodType == UnconditionMethod ? mUnconditionMethodName : mConditionMethodName;
}
ConditionerMethodDependency* ConditionerFeature::getConditionerMethodDependency( MethodType methodType )
{
if ( mMethodDependency[methodType] == NULL )
mMethodDependency[methodType] = new ConditionerMethodDependency( this, methodType );
return mMethodDependency[methodType];
}
void ConditionerFeature::_print( Stream *stream )
{
_printMethod( ConditionMethod, getShaderMethodName( ConditionMethod ), *stream );
LangElement::deleteElements();
_printMethod( UnconditionMethod, getShaderMethodName( UnconditionMethod ), *stream );
LangElement::deleteElements();
}
void ConditionerFeature::_updateConditioners()
{
smDirtyConditioners = false;
String includePath = "shadergen:/" + ConditionerIncludeFileName;
FileStream stream;
if ( !stream.open( includePath, Torque::FS::File::Write ) )
return;
for ( U32 i=0; i < smConditioners.size(); i++ )
smConditioners[i]->_print( &stream );
}
Var *ConditionerFeature::printMethodHeader( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta )
{
Var *methodVar = new Var;
methodVar->setName(methodName);
DecOp *methodDecl = new DecOp(methodVar);
const bool isCondition = (methodType == ConditionerFeature::ConditionMethod);
Var *paramVar = new Var;
paramVar->setName(avar("%sconditioned%sput", isCondition ? "un" : "", isCondition ? "Out" : "In"));
DecOp *paramDecl = new DecOp(paramVar);
if(GFX->getAdapterType() == OpenGL)
{
methodVar->setType("vec4");
paramVar->setType("vec4");
}
else
{
methodVar->setType("inline float4");
paramVar->setType("in float4");
}
// Method header and opening bracket
meta->addStatement( new GenOp( "@(@)\r\n", methodDecl, paramDecl ) );
meta->addStatement( new GenOp( "{\r\n" ) );
return paramVar;
}
void ConditionerFeature::printMethodFooter( MethodType methodType, Var *retVar, Stream &stream, MultiLine *meta )
{
// Return and closing bracket
meta->addStatement( new GenOp( "\r\n return @;\r\n", retVar ) );
meta->addStatement( new GenOp( "}\r\n" ) );
}
void ConditionerFeature::_printMethod( MethodType methodType, const String &methodName, Stream &stream )
{
MultiLine *meta = new MultiLine;
printHeaderComment( methodType, methodName, stream, meta );
Var *paramVar = printMethodHeader( methodType, methodName, stream, meta );
Var *unconditionedInput = NULL;
if( methodType == UnconditionMethod )
unconditionedInput = _unconditionInput( paramVar, meta );
else
unconditionedInput = _conditionOutput( paramVar, meta );
printMethodFooter( methodType, unconditionedInput, stream, meta );
printFooterComment( methodType, methodName, stream, meta );
meta->print(stream);
}
void ConditionerFeature::printHeaderComment( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta )
{
meta->addStatement( new GenOp( "//------------------------------------------------------------------------------\r\n" ) );
meta->addStatement( new GenOp( avar( "// Autogenerated '%s' %s Method\r\n", getName().c_str(),
methodType == ConditionMethod ? "Condition" : "Uncondition" ) ) );
meta->addStatement( new GenOp( "//------------------------------------------------------------------------------\r\n" ) );
}
void ConditionerFeature::printFooterComment( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta )
{
meta->addStatement( new GenOp( "\r\n\r\n" ) );
}
void ConditionerMethodDependency::print( Stream &s ) const
{
mConditioner->_printMethod(mMethodType, mConditioner->getShaderMethodName(mMethodType), s);
}
void ConditionerMethodDependency::createMethodMacro( const String &methodName, Vector<GFXShaderMacro> &macros )
{
GFXShaderMacro conditionerMethodMacro;
conditionerMethodMacro.name = methodName;
conditionerMethodMacro.value = mConditioner->getShaderMethodName(mMethodType);
macros.push_back(conditionerMethodMacro);
}

View file

@ -0,0 +1,137 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _CONDITIONER_BASE_H_
#define _CONDITIONER_BASE_H_
#ifndef _SHADERFEATURE_H_
#include "shaderGen/shaderFeature.h"
#endif
#ifndef _SHADER_DEPENDENCY_H_
#include "shaderGen/shaderDependency.h"
#endif
class MultiLine;
class ConditionerMethodDependency;
class ConditionerFeature : public ShaderFeature
{
friend class ConditionerMethodDependency;
typedef ShaderFeature Parent;
public:
enum MethodType
{
ConditionMethod = 0, ///< Method used to take unconditioned data, and turn it into a format that can be written to the conditioned buffer
UnconditionMethod, ///< Method used to take conditioned data from a buffer, and extract what is stored
NumMethodTypes,
};
ConditionerFeature( const GFXFormat bufferFormat );
virtual ~ConditionerFeature();
virtual Material::BlendOp getBlendOp()
{
return Material::None;
}
virtual GFXFormat getBufferFormat() const { return mBufferFormat; }
virtual bool setBufferFormat(const GFXFormat bufferFormat) { bool ret = mBufferFormat == bufferFormat; mBufferFormat = bufferFormat; return ret; }
// zero-out these methods
virtual Var* getVertTexCoord( const String &name ) { AssertFatal( false, "don't use this." ); return NULL; }
virtual LangElement *setupTexSpaceMat( Vector<ShaderComponent*> &componentList, Var **texSpaceMat ) { AssertFatal( false, "don't use this." ); return NULL; }
virtual LangElement *expandNormalMap( LangElement *sampleNormalOp, LangElement *normalDecl, LangElement *normalVar, const MaterialFeatureData &fd ) { AssertFatal( false, "don't use this." ); return NULL; }
virtual LangElement *assignColor( LangElement *elem, Material::BlendOp blend, LangElement *lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget ) { AssertFatal( false, "don't use this." ); return NULL; }
// conditioned output
virtual LangElement *assignOutput( Var *unconditionedOutput, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget );
// Get an HLSL/GLSL method name that will be available for the
// shader to read or write data to a conditioned buffer.
virtual const String &getShaderMethodName( MethodType methodType );
// Get the Method Dependency for ShaderGen, for this conditioner
virtual ConditionerMethodDependency *getConditionerMethodDependency( MethodType methodType );
static const String ConditionerIncludeFileName;
static void updateConditioners() { if ( smDirtyConditioners ) _updateConditioners(); }
protected:
static void _updateConditioners();
static bool smDirtyConditioners;
ConditionerMethodDependency *mMethodDependency[NumMethodTypes];
static Vector<ConditionerFeature*> smConditioners;
GFXFormat mBufferFormat;
String mUnconditionMethodName;
String mConditionMethodName;
String mShaderIncludePath;
void _print( Stream *stream );
virtual Var *_conditionOutput( Var *unconditionedOutput, MultiLine *meta );
virtual Var *_unconditionInput( Var *conditionedInput, MultiLine *meta );
// Print method header, return primary parameter
virtual Var *printMethodHeader( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta );
virtual void printMethodFooter( MethodType methodType, Var *retVar, Stream &stream, MultiLine *meta );
// Print comments
virtual void printHeaderComment( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta );
virtual void printFooterComment( MethodType methodType, const String &methodName, Stream &stream, MultiLine *meta );
// print a HLSL/GLSL method to a stream, which can be used by a custom shader
// to read conditioned data
virtual void _printMethod( MethodType methodType, const String &methodName, Stream &stream );
};
//------------------------------------------------------------------------------
// ShaderDependancy that allows shadergen features to add a dependency on a conditioner method
class ConditionerMethodDependency : public ShaderDependency
{
protected:
ConditionerFeature *mConditioner;
ConditionerFeature::MethodType mMethodType;
public:
ConditionerMethodDependency( ConditionerFeature *conditioner, const ConditionerFeature::MethodType methodType ) :
mConditioner(conditioner), mMethodType(methodType) {}
virtual void print( Stream &s ) const;
// Auto insert information into a macro
virtual void createMethodMacro( const String &methodName, Vector<GFXShaderMacro> &macros );
};
#endif // _CONDITIONER_BASE_H_

View file

@ -0,0 +1,143 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/featureMgr.h"
#include "shaderGen/featureType.h"
#include "shaderGen/shaderFeature.h"
#include "core/util/safeDelete.h"
#include "core/module.h"
MODULE_BEGIN( ShaderGenFeatureMgr )
MODULE_INIT_BEFORE( ShaderGen )
MODULE_SHUTDOWN_AFTER( Sim ) // allow registered features to be removed before destroying singleton
MODULE_INIT
{
ManagedSingleton< FeatureMgr >::createSingleton();
}
MODULE_SHUTDOWN
{
ManagedSingleton< FeatureMgr >::deleteSingleton();
}
MODULE_END;
FeatureMgr::FeatureMgr()
: mNeedsSort( false )
{
VECTOR_SET_ASSOCIATION( mFeatures );
}
FeatureMgr::~FeatureMgr()
{
unregisterAll();
}
void FeatureMgr::unregisterAll()
{
FeatureInfoVector::iterator iter = mFeatures.begin();
for ( ; iter != mFeatures.end(); iter++ )
{
if ( iter->feature )
delete iter->feature;
}
mFeatures.clear();
mNeedsSort = false;
}
const FeatureInfo& FeatureMgr::getAt( U32 index )
{
if ( mNeedsSort )
{
mFeatures.sort( _featureInfoCompare );
mNeedsSort = false;
}
AssertFatal( index < mFeatures.size(), "FeatureMgr::getAt() - Index out of range!" );
return mFeatures[index];
}
ShaderFeature* FeatureMgr::getByType( const FeatureType &type )
{
FeatureInfoVector::iterator iter = mFeatures.begin();
for ( ; iter != mFeatures.end(); iter++ )
{
if ( *iter->type == type )
return iter->feature;
}
return NULL;
}
void FeatureMgr::registerFeature( const FeatureType &type,
ShaderFeature *feature )
{
// Remove any existing feature first.
unregisterFeature( type );
// Now add the new feature.
mFeatures.increment();
mFeatures.last().type = &type;
mFeatures.last().feature = feature;
// Make sure we resort the features.
mNeedsSort = true;
}
S32 QSORT_CALLBACK FeatureMgr::_featureInfoCompare( const FeatureInfo* a, const FeatureInfo* b )
{
const FeatureType *typeA = a->type;
const FeatureType *typeB = b->type;
if ( typeA->getGroup() < typeB->getGroup() )
return -1;
else if ( typeA->getGroup() > typeB->getGroup() )
return 1;
else if ( typeA->getOrder() < typeB->getOrder() )
return -1;
else if ( typeA->getOrder() > typeB->getOrder() )
return 1;
else
return 0;
}
void FeatureMgr::unregisterFeature( const FeatureType &type )
{
FeatureInfoVector::iterator iter = mFeatures.begin();
for ( ; iter != mFeatures.end(); iter++ )
{
if ( *iter->type != type )
continue;
delete iter->feature;
mFeatures.erase( iter );
return;
}
}

View file

@ -0,0 +1,89 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _FEATUREMGR_H_
#define _FEATUREMGR_H_
#ifndef _TSINGLETON_H_
#include "core/util/tSingleton.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
class FeatureType;
class ShaderFeature;
/// Used by the feature manager.
struct FeatureInfo
{
const FeatureType *type;
ShaderFeature *feature;
};
///
class FeatureMgr
{
protected:
bool mNeedsSort;
typedef Vector<FeatureInfo> FeatureInfoVector;
FeatureInfoVector mFeatures;
static S32 QSORT_CALLBACK _featureInfoCompare( const FeatureInfo *a, const FeatureInfo *b );
public:
FeatureMgr();
~FeatureMgr();
/// Returns the count of registered features.
U32 getFeatureCount() const { return mFeatures.size(); }
/// Returns the feature info at the index.
const FeatureInfo& getAt( U32 index );
///
ShaderFeature* getByType( const FeatureType &type );
// Allows other systems to add features. index is
// the enum in GFXMaterialFeatureData.
void registerFeature( const FeatureType &type,
ShaderFeature *feature );
// Unregister a feature.
void unregisterFeature( const FeatureType &type );
/// Removes all features.
void unregisterAll();
// For ManagedSingleton.
static const char* getSingletonName() { return "FeatureMgr"; }
};
// Helper for accessing the feature manager singleton.
#define FEATUREMGR ManagedSingleton<FeatureMgr>::instance()
#endif // FEATUREMGR

View file

@ -0,0 +1,225 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/featureSet.h"
#include "shaderGen/featureType.h"
#include "platform/profiler.h"
#include "core/util/hashFunction.h"
const FeatureSet FeatureSet::EmptySet;
S32 QSORT_CALLBACK FeatureSet::_typeCmp( const FeatureInfo* a, const FeatureInfo* b )
{
if ( a->type->getGroup() < b->type->getGroup() )
return -1;
else if ( a->type->getGroup() > b->type->getGroup() )
return 1;
else if ( a->index < b->index )
return -1;
else if ( a->index > b->index )
return 1;
else if ( a->type->getOrder() < b->type->getOrder() )
return -1;
else if ( a->type->getOrder() > b->type->getOrder() )
return 1;
else
return 0;
}
void FeatureSet::_rebuildDesc()
{
PROFILE_SCOPE( FeatureSet_RebuildDesc );
// First get the features in the proper order.
mFeatures.sort( _typeCmp );
String desc;
for ( U32 i=0; i < mFeatures.size(); i++ )
desc += String::ToString( "%s,%d\n",
mFeatures[i].type->getName().c_str(),
mFeatures[i].index );
// By interning the description we have only
// one instance in the system and we get fast
// pointer compares for equality.
mDescription = desc.intern();
}
const FeatureType& FeatureSet::getAt( U32 index, S32 *outIndex ) const
{
// We want to make sure we access the features in the
// correct order. By asking for the description we ensure
// the feature set is properly sorted.
getDescription();
if ( outIndex )
*outIndex = mFeatures[index].index;
return *mFeatures[index].type;
}
void FeatureSet::clear()
{
mDescription.clear();
mFeatures.clear();
}
FeatureSet& FeatureSet::operator =( const FeatureSet &h )
{
clear();
merge( h );
return *this;
}
bool FeatureSet::hasFeature( const FeatureType &type, S32 index ) const
{
PROFILE_SCOPE(FeatureSet_hasFeature);
for ( U32 i = 0; i < mFeatures.size(); i++)
{
if ( mFeatures[i].type == &type &&
( index < 0 || mFeatures[i].index == index ) )
return true;
}
return false;
}
void FeatureSet::setFeature( const FeatureType &type, bool set, S32 index )
{
for ( U32 i=0; i < mFeatures.size(); i++ )
{
const FeatureInfo &info = mFeatures[i];
if ( info.type == &type && info.index == index )
{
if ( set )
return;
else
{
mFeatures.erase_fast( i );
mDescription.clear();
return;
}
}
}
if ( !set )
return;
FeatureInfo info;
info.type = &type;
info.index = index;
mFeatures.push_back( info );
mDescription.clear();
}
void FeatureSet::addFeature( const FeatureType &type, S32 index )
{
for ( U32 i=0; i < mFeatures.size(); i++ )
{
const FeatureInfo &info = mFeatures[i];
if ( info.type == &type &&
info.index == index )
return;
}
FeatureInfo info;
info.type = &type;
info.index = index;
mFeatures.push_back( info );
mDescription.clear();
}
void FeatureSet::removeFeature( const FeatureType &type )
{
for ( U32 i=0; i < mFeatures.size(); i++ )
{
const FeatureInfo &info = mFeatures[i];
if ( info.type == &type )
{
mFeatures.erase_fast( i );
mDescription.clear();
return;
}
}
}
U32 FeatureSet::getNextFeatureIndex( const FeatureType &type, S32 index ) const
{
for ( U32 i=0; i < mFeatures.size(); i++ )
{
const FeatureInfo &info = mFeatures[i];
if ( info.type == &type && info.index > index )
return i;
}
return -1;
}
void FeatureSet::filter( const FeatureSet &features )
{
PROFILE_SCOPE( FeatureSet_Filter );
for ( U32 i=0; i < mFeatures.size(); )
{
if ( !features.hasFeature( *mFeatures[i].type ) )
mFeatures.erase_fast( i );
else
i++;
}
mDescription.clear();
}
void FeatureSet::exclude( const FeatureSet &features )
{
PROFILE_SCOPE( FeatureSet_Exclude );
for ( U32 i=0; i < features.mFeatures.size(); i++ )
removeFeature( *features.mFeatures[i].type );
mDescription.clear();
}
void FeatureSet::merge( const FeatureSet &features )
{
PROFILE_SCOPE( FeatureSet_Merge );
if ( mFeatures.empty() )
{
mFeatures.merge( features.mFeatures );
mDescription = features.mDescription;
return;
}
for ( U32 i=0; i < features.mFeatures.size(); i++ )
addFeature( *features.mFeatures[i].type,
features.mFeatures[i].index );
}

View file

@ -0,0 +1,138 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _FEATURESET_H_
#define _FEATURESET_H_
#ifndef _TORQUE_STRING_H_
#include "core/util/str.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
class FeatureType;
//
class FeatureSet
{
protected:
struct FeatureInfo
{
const FeatureType* type;
S32 index;
};
/// The list of featurs.
Vector<FeatureInfo> mFeatures;
/// A string representation of all the
/// features used for comparisons.
String mDescription;
///
static S32 _typeCmp( const FeatureInfo* a, const FeatureInfo *b );
///
void _rebuildDesc();
public:
FeatureSet()
{
}
FeatureSet( const FeatureSet &h )
: mFeatures( h.mFeatures ),
mDescription( h.mDescription )
{
}
FeatureSet& operator =( const FeatureSet &h );
/// Equality operators.
inline bool operator != ( const FeatureSet &h ) const { return h.getDescription() != getDescription(); }
inline bool operator == ( const FeatureSet &h ) const { return h.getDescription() == getDescription(); }
bool operator []( const FeatureType &type ) const { return hasFeature( type ); }
/// Returns true if the feature set is empty.
bool isEmpty() const { return mFeatures.empty(); }
/// Returns true if the feature set is not empty.
bool isNotEmpty() const { return !mFeatures.empty(); }
/// Return the description string which uniquely identifies this feature set.
const String& getDescription() const;
/// Returns the feature count.
U32 getCount() const { return mFeatures.size(); }
/// Returns the feature at the index and optionally
/// the feature index when it was added.
const FeatureType& getAt( U32 index, S32 *outIndex = NULL ) const;
/// Returns true if this handle has this feature.
bool hasFeature( const FeatureType &type, S32 index = -1 ) const;
///
void setFeature( const FeatureType &type, bool set, S32 index = -1 );
///
void addFeature( const FeatureType &type, S32 index = -1 );
///
void removeFeature( const FeatureType &type );
///
U32 getNextFeatureIndex( const FeatureType &type, S32 index ) const;
/// Removes features that are not in the input set.
void filter( const FeatureSet &features );
/// Removes features that are in the input set.
void exclude( const FeatureSet &features );
///
void merge( const FeatureSet &features );
/// Clears all features.
void clear();
/// Default empty feature set.
static const FeatureSet EmptySet;
};
inline const String& FeatureSet::getDescription() const
{
// Update the description if its empty and we have features.
if ( mDescription.isEmpty() && !mFeatures.empty() )
const_cast<FeatureSet*>(this)->_rebuildDesc();
return mDescription;
}
#endif // _FEATURESET_H_

View file

@ -0,0 +1,62 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/featureType.h"
#include "shaderGen/featureSet.h"
FeatureTypeVector& FeatureType::_getTypes()
{
// We create it as a method static so that
// its available to other statics regardless
// of initialization order.
static FeatureTypeVector theTypes;
return theTypes;
}
void FeatureType::addDefaultTypes( FeatureSet *outFeatures )
{
const FeatureTypeVector &types = _getTypes();
for ( U32 i=0; i < types.size(); i++ )
{
if ( types[i]->isDefault() )
outFeatures->addFeature( *types[i] );
}
}
FeatureType::FeatureType( const char *name, U32 group, F32 order, bool isDefault )
: mName( name ),
mGroup( group ),
mOrder( order ),
mIsDefault( isDefault )
{
FeatureTypeVector &types = _getTypes();
#ifdef TORQUE_DEBUG
for ( U32 i=0; i < types.size(); i++ )
AssertFatal( !mName.equal( types[i]->getName() ), "FeatureType - This feature already exists!" );
#endif
mId = types.size();
types.push_back( this );
}

View file

@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _FEATURETYPE_H_
#define _FEATURETYPE_H_
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _TORQUE_STRING_H_
#include "core/util/str.h"
#endif
class FeatureType;
class FeatureSet;
/// A vector of feature types.
typedef Vector<const FeatureType*> FeatureTypeVector;
///
class FeatureType
{
protected:
/// Returns the map of all the types.
static FeatureTypeVector& _getTypes();
/// The feature type name.
String mName;
/// A unique feature id value.
U32 mId;
/// The group is used to orginize the types.
U32 mGroup;
/// The sort order of this feature type
/// within its group.
F32 mOrder;
///
bool mIsDefault;
///
FeatureType( const FeatureType &type );
public:
/// Adds all the default features types to the set.
static void addDefaultTypes( FeatureSet *outFeatures );
/// You should not use this constructor directly.
/// @see DeclareFeatureType
/// @see ImplementFeatureType
FeatureType( const char *type,
U32 group = -1,
F32 order = -1.0f,
bool isDefault = true );
bool operator !=( const FeatureType &type ) const { return this != &type; }
bool operator ==( const FeatureType &type ) const { return this == &type; }
const String& getName() const { return mName; }
U32 getId() const { return mId; }
U32 getGroup() const { return mGroup; }
F32 getOrder() const { return mOrder; }
bool isDefault() const { return mIsDefault; }
};
///
#define DeclareFeatureType( name ) \
extern const FeatureType name
///
#define ImplementFeatureType( name, group, order, isDefault ) \
const FeatureType name( #name, group, order, isDefault )
/*
#define ImplementFeatureType( name, group, order ) \
const FeatureType name( #name, group, order );
#define ImplementFeatureType( name, group ) \
const FeatureType name( #name, group );
#define ImplementFeatureType( name ) \
const FeatureType name( #name );
*/
#endif // _FEATURETYPE_H_

View file

@ -0,0 +1,204 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "core/strings/stringFunctions.h"
#include "core/util/str.h"
#include "langElement.h"
//**************************************************************************
// Language element
//**************************************************************************
Vector<LangElement*> LangElement::elementList( __FILE__, __LINE__ );
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
LangElement::LangElement()
{
elementList.push_back( this );
static U32 tempNum = 0;
dSprintf( (char*)name, sizeof(name), "tempName%d", tempNum++ );
}
//--------------------------------------------------------------------------
// Find element of specified name
//--------------------------------------------------------------------------
LangElement * LangElement::find( const char *name )
{
for( U32 i=0; i<elementList.size(); i++ )
{
if( !dStrcmp( (char*)elementList[i]->name, name ) )
{
return elementList[i];
}
}
return NULL;
}
//--------------------------------------------------------------------------
// Delete existing elements
//--------------------------------------------------------------------------
void LangElement::deleteElements()
{
for( U32 i=0; i<elementList.size(); i++ )
{
delete elementList[i];
}
elementList.setSize( 0 );
}
//--------------------------------------------------------------------------
// Set name
//--------------------------------------------------------------------------
void LangElement::setName(const char* newName )
{
dStrncpy( ( char* ) name, newName, sizeof( name ) );
name[ sizeof( name ) - 1 ] = '\0';
}
//**************************************************************************
// Variable
//**************************************************************************
U32 Var::texUnitCount = 0;
Var::Var()
{
dStrcpy( (char*)type, "float4" );
structName[0] = '\0';
uniform = false;
vertData = false;
connector = false;
sampler = false;
mapsToSampler = false;
texCoordNum = 0;
constSortPos = cspUninit;
arraySize = 1;
}
Var::Var( const char *inName, const char *inType )
{
structName[0] = '\0';
uniform = false;
vertData = false;
connector = false;
sampler = false;
mapsToSampler = false;
texCoordNum = 0;
constSortPos = cspUninit;
arraySize = 1;
setName( inName );
setType( inType );
}
void Var::setUniform(const String& constType, const String& constName, ConstantSortPosition sortPos)
{
uniform = true;
setType(constType.c_str());
setName(constName.c_str());
constSortPos = cspPass;
}
//--------------------------------------------------------------------------
// Set struct name
//--------------------------------------------------------------------------
void Var::setStructName(const char* newName )
{
dStrncpy( ( char* ) structName, newName, sizeof( structName ) );
structName[ sizeof( structName ) - 1 ] = '\0';
}
//--------------------------------------------------------------------------
// Set connect name
//--------------------------------------------------------------------------
void Var::setConnectName(const char* newName )
{
dStrncpy( ( char* ) connectName, newName, sizeof( connectName ) );
connectName[ sizeof( connectName ) - 1 ] = '\0';
}
//--------------------------------------------------------------------------
// Set type
//--------------------------------------------------------------------------
void Var::setType(const char *newType )
{
dStrncpy( ( char* ) type, newType, sizeof( type ) );
type[ sizeof( type ) - 1 ] = '\0';
}
//--------------------------------------------------------------------------
// print
//--------------------------------------------------------------------------
void Var::print( Stream &stream )
{
if( structName[0] != '\0' )
{
stream.write( dStrlen((char*)structName), structName );
stream.write( 1, "." );
}
stream.write( dStrlen((char*)name), name );
}
//--------------------------------------------------------------------------
// Get next available texture unit number
//--------------------------------------------------------------------------
U32 Var::getTexUnitNum(U32 numElements)
{
U32 ret = texUnitCount;
texUnitCount += numElements;
return ret;
}
//--------------------------------------------------------------------------
// Reset
//--------------------------------------------------------------------------
void Var::reset()
{
texUnitCount = 0;
}
//**************************************************************************
// Multi line statement
//**************************************************************************
void MultiLine::addStatement( LangElement *elem )
{
AssertFatal( elem, "Attempting to add empty statement" );
mStatementList.push_back( elem );
}
//--------------------------------------------------------------------------
// Print
//--------------------------------------------------------------------------
void MultiLine::print( Stream &stream )
{
for( U32 i=0; i<mStatementList.size(); i++ )
{
mStatementList[i]->print( stream );
}
}

View file

@ -0,0 +1,183 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _LANG_ELEMENT_H_
#define _LANG_ELEMENT_H_
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _STREAM_H_
#include "core/stream/stream.h"
#endif
#define WRITESTR( a ){ stream.write( dStrlen(a), a ); }
//**************************************************************************
/*!
The LangElement class is the base building block for procedurally
generated shader code. LangElement and its subclasses are strung
together using the static Vector 'elementList'.
When a shader needs to be written to disk, the elementList is
traversed and print() is called on each LangElement and the shader
is output. elementList is cleared after each shader is printed out.
*/
//**************************************************************************
//**************************************************************************
// Language element
//**************************************************************************
struct LangElement
{
static Vector<LangElement*> elementList;
static LangElement * find( const char *name );
static void deleteElements();
U8 name[32];
LangElement();
virtual ~LangElement() {};
virtual void print( Stream &stream ){};
void setName(const char *newName );
};
enum ConstantSortPosition
{
/// Default / unset
cspUninit = 0,
/// Updated before every draw primitive call.
cspPrimitive,
/// Potentially updated every draw primitive call, but not necessarily (lights for example)
cspPotentialPrimitive,
/// Updated one per pass
cspPass,
/// Count var, do not use
csp_Count
};
//----------------------------------------------------------------------------
/*!
Var - Variable - used to specify a variable to be used in a shader.
Var stores information such that when it is printed out, its context
can be identified and the proper information will automatically be printed.
For instance, if a variable is created with 'uniform' set to true, when the
shader function definition is printed, it will automatically add that
variable to the incoming parameters of the shader. There are several
similar cases such as when a new variable is declared within a shader.
example:
@code
Var *modelview = new Var;
modelview->setType( "float4x4" );
modelview->setName( "modelview" );
modelview->uniform = true;
modelview->constSortPos = cspPass;
@endcode
it prints out in the shader declaration as:
@code
ConnectData main( VertData IN,
uniform float4x4 modelview : register(C0) )
@endcode
*/
//----------------------------------------------------------------------------
struct Var : public LangElement
{
U8 type[32];
U8 structName[32];
char connectName[32];
ConstantSortPosition constSortPos; // used to calculate constant number
U32 constNum;
U32 texCoordNum;
bool uniform; // argument passed in through constant registers
bool vertData; // argument coming from vertex data
bool connector; // variable that will be passed to pixel shader
bool sampler; // texture
bool mapsToSampler; // for ps 1.x shaders - texcoords must be mapped to same sampler stage
U32 arraySize; // 1 = no array, > 1 array of "type"
static U32 texUnitCount;
static U32 getTexUnitNum(U32 numElements = 1);
static void reset();
// Default
Var();
Var( const char *name, const char *type );
void setStructName(const char *newName );
void setConnectName(const char *newName );
void setType(const char *newType );
virtual void print( Stream &stream );
// Construct a uniform / shader const var
void setUniform(const String& constType, const String& constName, ConstantSortPosition sortPos);
};
//----------------------------------------------------------------------------
/*!
MultiLine - Multi Line Statement - This class simply ties multiple
example:
@code
MultiLine *meta = new MultiLine;
meta->addStatement( new GenOp( "foo = true;\r\n" ) );
meta->addStatement( new GenOp( "bar = false;\r\n ) );
@endcode
it prints out in the shader declaration as:
@code
foo = true;
bar = false;
@endcode
*/
//----------------------------------------------------------------------------
class MultiLine : public LangElement
{
Vector <LangElement*> mStatementList;
public:
MultiLine()
{
VECTOR_SET_ASSOCIATION( mStatementList );
}
void addStatement( LangElement *elem );
virtual void print( Stream &stream );
};
#endif // _LANG_ELEMENT_H_

View file

@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "shaderComp.h"
//**************************************************************************
// Connector Struct Component
//**************************************************************************
//----------------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------------
ShaderConnector::ShaderConnector()
{
mCurTexElem = 0;
}
//----------------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------------
ShaderConnector::~ShaderConnector()
{
// Elements freed by LangElement::freeElements()
}

View file

@ -0,0 +1,99 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERCOMP_H_
#define _SHADERCOMP_H_
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _MISCSHDRDAT_H_
#include "materials/miscShdrDat.h"
#endif
class Stream;
struct Var;
//**************************************************************************
// Shader Component - these objects are the main logical breakdown of a
// high level shader. They represent the various data structures
// and the main() procedure necessary to create a shader.
//**************************************************************************
class ShaderComponent
{
public:
virtual ~ShaderComponent() {}
virtual void print( Stream &stream ){};
};
//**************************************************************************
// Connector Struct Component - used for incoming Vertex struct and also the
// "connection" struct shared by the vertex and pixel shader
//**************************************************************************
class ShaderConnector : public ShaderComponent
{
protected:
enum Consts
{
NUM_TEX_REGS = 8,
};
enum Elements
{
POSITION = 0,
NORMAL,
COLOR,
NUM_BASIC_ELEMS
};
Vector <Var*> mElementList;
U32 mCurTexElem;
U8 mName[32];
public:
ShaderConnector();
virtual ~ShaderConnector();
///
virtual Var* getElement( RegisterType type,
U32 numElements = 1,
U32 numRegisters = -1 ) = 0;
virtual void setName( char *newName ) = 0;
virtual void reset() = 0;
virtual void sortVars() = 0;
virtual void print( Stream &stream ) = 0;
};
/// This is to provide common functionalty needed by vertex and pixel main defs
class ParamsDef : public ShaderComponent
{
protected:
virtual void assignConstantNumbers() {}
};
#endif // _SHADERCOMP_H_

View file

@ -0,0 +1,47 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderDependency.h"
#include "core/stream/fileStream.h"
#include "core/frameAllocator.h"
ShaderIncludeDependency::ShaderIncludeDependency( const Torque::Path &pathToInclude )
: mIncludePath( pathToInclude )
{
}
bool ShaderIncludeDependency::operator==( const ShaderDependency &cmpTo ) const
{
return this == &cmpTo ||
( dynamic_cast<const ShaderIncludeDependency*>( &cmpTo ) &&
static_cast<const ShaderIncludeDependency*>( &cmpTo )->mIncludePath == mIncludePath );
}
void ShaderIncludeDependency::print( Stream &s ) const
{
// Print the include... all shaders support #includes.
String include = String::ToString( "#include \"%s\"\r\n", mIncludePath.getFullPath().c_str() );
s.write( include.length(), include.c_str() );
}

View file

@ -0,0 +1,66 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADER_DEPENDENCY_H_
#define _SHADER_DEPENDENCY_H_
#ifndef _PATH_H_
#include "core/util/path.h"
#endif
class Stream;
/// The base class for shader dependencies
class ShaderDependency
{
public:
virtual ~ShaderDependency() {}
/// Compare this dependency to another one.
virtual bool operator==( const ShaderDependency &cmpTo ) const
{
return this == &cmpTo;
}
/// Print the dependency into the header of a shader.
virtual void print( Stream &s ) const = 0;
};
/// A shader dependency for adding #include's into shadergen shaders.
class ShaderIncludeDependency : public ShaderDependency
{
protected:
Torque::Path mIncludePath;
public:
ShaderIncludeDependency( const Torque::Path &pathToInclude );
virtual bool operator==( const ShaderDependency &cmpTo ) const;
virtual void print( Stream &s ) const;
};
#endif // _SHADER_DEPENDENCY_H_

View file

@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderFeature.h"
#include "shaderGen/langElement.h"
#include "shaderGen/shaderOp.h"
void ShaderFeature::addDependency( const ShaderDependency *dependsOn )
{
for ( U32 i = 0; i < mDependencies.size(); i++ )
{
if ( *mDependencies[i] == *dependsOn )
return;
}
mDependencies.push_back( dependsOn );
}
ShaderFeature::Resources ShaderFeature::getResources( const MaterialFeatureData &fd )
{
Resources temp;
return temp;
}
const char* ShaderFeature::getOutputTargetVarName( OutputTarget target ) const
{
const char* targName = "col";
if ( target != DefaultTarget )
{
targName = "col1";
AssertFatal(target == RenderTarget1, "yeah Pat is lame and didn't want to do bit math stuff, TODO");
}
return targName;
}
Var* ShaderFeature::findOrCreateLocal( const char *name,
const char *type,
MultiLine *multi )
{
Var *outVar = (Var*)LangElement::find( name );
if ( !outVar )
{
outVar = new Var;
outVar->setType( type );
outVar->setName( name );
multi->addStatement( new GenOp( " @;\r\n", new DecOp( outVar ) ) );
}
return outVar;
}

View file

@ -0,0 +1,296 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERFEATURE_H_
#define _SHADERFEATURE_H_
#ifndef _MATERIALDEFINITION_H_
#include "materials/materialDefinition.h"
#endif
#ifndef _SHADERCOMP_H_
#include "shaderGen/shaderComp.h"
#endif
#ifndef _SHADER_DEPENDENCY_H_
#include "shaderGen/shaderDependency.h"
#endif
class MultiLine;
struct LangElement;
struct MaterialFeatureData;
class GFXShaderConstBuffer;
struct RenderPassData;
struct SceneData;
class SceneRenderState;
class GFXShader;
class GFXVertexFormat;
///
class ShaderFeatureConstHandles
{
public:
virtual void init( GFXShader *shader ) = 0;
virtual void setConsts( SceneRenderState *state,
const SceneData &sgData,
GFXShaderConstBuffer *buffer ) = 0;
};
//**************************************************************************
/*!
The ShaderFeature class is the base class for every procedurally generated
feature. Each feature the engine recognizes is part of the MaterialFeatureType
enum. That structure is used to indicate which features are present in a shader
to be generated. This is useful as many ShaderFeatures will output different
code depending on what other features are going to be in the shader.
Shaders are generated using the ShaderFeature interface, so all of the
descendants interact pretty much the same way.
*/
//**************************************************************************
//**************************************************************************
// Shader Feature
//**************************************************************************
class ShaderFeature
{
public:
// Bitfield which allows a shader feature to say which render targets it outputs
// data to (could be more than one).
enum OutputTarget
{
DefaultTarget = 1 << 0,
RenderTarget1 = 1 << 1,
RenderTarget2 = 1 << 2,
RenderTarget3 = 1 << 3,
};
protected:
LangElement *output;
/// The list of unique shader dependencies.
Vector<const ShaderDependency *> mDependencies;
///
S32 mProcessIndex;
public:
// TODO: Make this protected and give it a proper API.
GFXVertexFormat *mInstancingFormat;
//**************************************************************************
/*!
The Resources structure is used by ShaderFeature to indicate how many
hardware "resources" it needs. Resources are things such as how
many textures it uses and how many texture registers it needs to pass
information from the vertex to the pixel shader.
The Resources data can change depending what hardware is available. For
instance, pixel 1.x level hardware may need more texture registers than
pixel 2.0+ hardware because each texture register can only be used with
its respective texture sampler.
The data in Resources is used to determine how many features can be
squeezed into a singe shader. If a feature requires too many resources
to fit into the current shader, it will be put into another pass.
*/
//**************************************************************************
struct Resources
{
U32 numTex;
U32 numTexReg;
Resources()
{
dMemset( this, 0, sizeof( Resources ) );
}
};
//-----------------------------------------------------------------------
// Base functions
//-----------------------------------------------------------------------
ShaderFeature()
: output( NULL ),
mProcessIndex( 0 ),
mInstancingFormat( NULL )
{
}
virtual ~ShaderFeature() {}
/// returns output from a processed vertex or pixel shader
LangElement* getOutput() const { return output; }
///
void setProcessIndex( S32 index ) { mProcessIndex = index; }
///
U32 getProcessIndex() const { return mProcessIndex; }
//-----------------------------------------------------------------------
// Virtual Functions
//-----------------------------------------------------------------------
/// Get the incoming base texture coords - useful for bumpmap and detail maps
virtual Var* getVertTexCoord( const String &name ) = 0;
/// Set up a texture space matrix - to pass into pixel shader
virtual LangElement * setupTexSpaceMat( Vector<ShaderComponent*> &componentList,
Var **texSpaceMat ) = 0;
/// Expand and assign a normal map. This takes care of compressed normal maps as well.
virtual LangElement * expandNormalMap( LangElement *sampleNormalOp,
LangElement *normalDecl, LangElement *normalVar, const MaterialFeatureData &fd ) = 0;
/// Helper function for applying the color to shader output.
///
/// @param elem The rbg or rgba color to assign.
///
/// @param blend The type of blending to perform.
///
/// @param lerpElem The optional lerp parameter when doing a LerpAlpha blend,
/// if not set then the elem is used.
///
virtual LangElement* assignColor( LangElement *elem,
Material::BlendOp blend,
LangElement *lerpElem = NULL,
ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget ) = 0;
//-----------------------------------------------------------------------
/*!
Process vertex shader - This function is used by each feature to
generate a list of LangElements that can be traversed and "printed"
to generate the actual shader code. The 'output' member is the head
of that list.
The componentList is used mostly for access to the "Connector"
structure which is used to pass data from the vertex to the pixel
shader.
The MaterialFeatureData parameter is used to determine what other
features are present for the shader being generated.
*/
//-----------------------------------------------------------------------
virtual void processVert( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{ output = NULL; }
//-----------------------------------------------------------------------
/*!
Process pixel shader - This function is used by each feature to
generate a list of LangElements that can be traversed and "printed"
to generate the actual shader code. The 'output' member is the head
of that list.
The componentList is used mostly for access to the "Connector"
structure which is used to pass data from the vertex to the pixel
shader.
The MaterialFeatureData parameter is used to determine what other
features are present for the shader being generated.
*/
//-----------------------------------------------------------------------
virtual void processPix( Vector<ShaderComponent*> &componentList,
const MaterialFeatureData &fd )
{ output = NULL; }
/// Allows the feature to add macros to pixel shader compiles.
virtual void processPixMacros( Vector<GFXShaderMacro> &macros, const MaterialFeatureData &fd ) {};
/// Allows the feature to add macros to vertex shader compiles.
virtual void processVertMacros( Vector<GFXShaderMacro> &macros, const MaterialFeatureData &fd ) {};
/// Identifies what type of blending a feature uses. This is used to
/// group features with the same blend operation together in a multipass
/// situation.
virtual Material::BlendOp getBlendOp() { return Material::Add; }
/// Returns the resource requirements of this feature based on what
/// other features are present. The "resources" are things such as
/// texture units, and texture registers of which there can be
/// very limited numbers. The resources can vary depending on hardware
/// and what other features are present.
virtual Resources getResources( const MaterialFeatureData &fd );
/// Fills texture related info in RenderPassData for this feature. It
/// takes into account the current pass (passData) as well as what other
/// data is available to the material stage (stageDat).
///
/// For instance, ReflectCubeFeatHLSL would like to modulate its output
/// by the alpha channel of another texture. If the current pass does
/// not contain a diffuse or bump texture, but the Material does, then
/// this function allows it to use one of those textures in the current
/// pass.
virtual void setTexData( Material::StageData &stageDat,
const MaterialFeatureData &fd,
RenderPassData &passData,
U32 &texIndex ){};
/// Returns the name of this feature.
virtual String getName() = 0;
/// Adds a dependency to this shader feature.
virtual void addDependency( const ShaderDependency *depends );
/// Gets the dependency list for this shader feature.
virtual const Vector<const ShaderDependency *> &getDependencies() const { return mDependencies; }
/// Returns the output variable name for this feature if it applies.
virtual const char* getOutputVarName() const { return NULL; }
/// Gets the render target this shader feature is assigning data to.
virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return DefaultTarget; }
/// Returns the name of output targer var.
const char* getOutputTargetVarName( OutputTarget target = DefaultTarget ) const;
// Called from ProcessedShaderMaterial::determineFeatures to enable/disable features.
virtual void determineFeature( Material *material,
const GFXVertexFormat *vertexFormat,
U32 stageNum,
const FeatureType &type,
const FeatureSet &features,
MaterialFeatureData *outFeatureData ) { }
//
virtual ShaderFeatureConstHandles* createConstHandles( GFXShader *shader, SimObject *userObject ) { return NULL; }
/// Called after processing the vertex and processing the pixel
/// to cleanup any temporary structures stored in the feature.
virtual void reset() { output = NULL; mProcessIndex = 0; mInstancingFormat = NULL; }
/// A simpler helper function which either finds
/// the existing local var or creates one.
static Var* findOrCreateLocal( const char *name,
const char *type,
MultiLine *multi );
};
#endif // _SHADERFEATURE_H_

View file

@ -0,0 +1,507 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderGen.h"
#include "shaderGen/conditionerFeature.h"
#include "core/stream/fileStream.h"
#include "shaderGen/featureMgr.h"
#include "shaderGen/shaderOp.h"
#include "gfx/gfxDevice.h"
#include "core/memVolume.h"
#include "core/module.h"
MODULE_BEGIN( ShaderGen )
MODULE_INIT_BEFORE( GFX )
MODULE_SHUTDOWN_AFTER( GFX )
MODULE_INIT
{
ManagedSingleton< ShaderGen >::createSingleton();
}
MODULE_SHUTDOWN
{
ManagedSingleton< ShaderGen >::deleteSingleton();
}
MODULE_END;
ShaderGen::ShaderGen()
{
mInit = false;
GFXDevice::getDeviceEventSignal().notify(this, &ShaderGen::_handleGFXEvent);
mOutput = NULL;
}
ShaderGen::~ShaderGen()
{
GFXDevice::getDeviceEventSignal().remove(this, &ShaderGen::_handleGFXEvent);
_uninit();
}
void ShaderGen::registerInitDelegate(GFXAdapterType adapterType, ShaderGenInitDelegate& initDelegate)
{
mInitDelegates[(U32)adapterType] = initDelegate;
}
bool ShaderGen::_handleGFXEvent(GFXDevice::GFXDeviceEventType event)
{
switch (event)
{
case GFXDevice::deInit :
initShaderGen();
break;
case GFXDevice::deDestroy :
{
flushProceduralShaders();
}
break;
default :
break;
}
return true;
}
void ShaderGen::initShaderGen()
{
if (mInit)
return;
const GFXAdapterType adapterType = GFX->getAdapterType();
if (!mInitDelegates[adapterType])
return;
mInitDelegates[adapterType](this);
mFeatureInitSignal.trigger( adapterType );
mInit = true;
String shaderPath = Con::getVariable( "$shaderGen::cachePath");
#if defined(TORQUE_SHADERGEN) && ( defined(TORQUE_OS_XENON) || defined(TORQUE_OS_PS3) )
// If this is a console build, and TORQUE_SHADERGEN is defined
// (signifying that new shaders should be generated) then clear the shader
// path so that the MemFileSystem is used instead.
shaderPath.clear();
#endif
if (!shaderPath.equal( "shadergen:" ) && !shaderPath.isEmpty() )
{
// this is necessary, especially under Windows with UAC enabled
if (!Torque::FS::VerifyWriteAccess(shaderPath))
{
// we don't have write access so enable the virtualized memory store
Con::warnf("ShaderGen: Write permission unavailable, switching to virtualized memory storage");
shaderPath.clear();
}
}
if ( shaderPath.equal( "shadergen:" ) || shaderPath.isEmpty() )
{
// If we didn't get a path then we're gonna cache the shaders to
// a virtualized memory file system.
mMemFS = new Torque::Mem::MemFileSystem( "shadergen:/" );
Torque::FS::Mount( "shadergen", mMemFS );
}
else
Torque::FS::Mount( "shadergen", shaderPath + "/" );
// Delete the auto-generated conditioner include file.
Torque::FS::Remove( "shadergen:/" + ConditionerFeature::ConditionerIncludeFileName );
}
void ShaderGen::generateShader( const MaterialFeatureData &featureData,
char *vertFile,
char *pixFile,
F32 *pixVersion,
const GFXVertexFormat *vertexFormat,
const char* cacheName,
Vector<GFXShaderMacro> &macros )
{
PROFILE_SCOPE( ShaderGen_GenerateShader );
mFeatureData = featureData;
mVertexFormat = vertexFormat;
_uninit();
_init();
char vertShaderName[256];
char pixShaderName[256];
// Note: We use a postfix of _V/_P here so that it sorts the matching
// vert and pixel shaders together when listed alphabetically.
dSprintf( vertShaderName, sizeof(vertShaderName), "shadergen:/%s_V.%s", cacheName, mFileEnding.c_str() );
dSprintf( pixShaderName, sizeof(pixShaderName), "shadergen:/%s_P.%s", cacheName, mFileEnding.c_str() );
dStrcpy( vertFile, vertShaderName );
dStrcpy( pixFile, pixShaderName );
// this needs to change - need to optimize down to ps v.1.1
*pixVersion = GFX->getPixelShaderVersion();
if ( !Con::getBoolVariable( "ShaderGen::GenNewShaders", true ) )
{
// If we are not regenerating the shader we will return here.
// But we must fill in the shader macros first!
_processVertFeatures( macros, true );
_processPixFeatures( macros, true );
return;
}
// create vertex shader
//------------------------
FileStream* s = new FileStream();
if(!s->open(vertShaderName, Torque::FS::File::Write ))
{
AssertFatal(false, "Failed to open Shader Stream" );
return;
}
mOutput = new MultiLine;
mInstancingFormat.clear();
_processVertFeatures(macros);
_printVertShader( *s );
delete s;
((ShaderConnector*)mComponents[C_CONNECTOR])->reset();
LangElement::deleteElements();
// create pixel shader
//------------------------
s = new FileStream();
if(!s->open(pixShaderName, Torque::FS::File::Write ))
{
AssertFatal(false, "Failed to open Shader Stream" );
return;
}
mOutput = new MultiLine;
_processPixFeatures(macros);
_printPixShader( *s );
delete s;
LangElement::deleteElements();
}
void ShaderGen::_init()
{
_createComponents();
}
void ShaderGen::_uninit()
{
for( U32 i=0; i<mComponents.size(); i++ )
{
delete mComponents[i];
mComponents[i] = NULL;
}
mComponents.setSize(0);
LangElement::deleteElements();
Var::reset();
}
void ShaderGen::_createComponents()
{
ShaderComponent* vertComp = mComponentFactory->createVertexInputConnector( *mVertexFormat );
mComponents.push_back(vertComp);
ShaderComponent* vertPixelCon = mComponentFactory->createVertexPixelConnector();
mComponents.push_back(vertPixelCon);
ShaderComponent* vertParamDef = mComponentFactory->createVertexParamsDef();
mComponents.push_back(vertParamDef);
ShaderComponent* pixParamDef = mComponentFactory->createPixelParamsDef();
mComponents.push_back(pixParamDef);
}
//----------------------------------------------------------------------------
// Process features
//----------------------------------------------------------------------------
void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> &macros, bool macrosOnly )
{
const FeatureSet &features = mFeatureData.features;
for( U32 i=0; i < features.getCount(); i++ )
{
S32 index;
const FeatureType &type = features.getAt( i, &index );
ShaderFeature* feature = FEATUREMGR->getByType( type );
if ( feature )
{
feature->setProcessIndex( index );
feature->processVertMacros( macros, mFeatureData );
if ( macrosOnly )
continue;
feature->mInstancingFormat = &mInstancingFormat;
feature->processVert( mComponents, mFeatureData );
String line;
if ( index > -1 )
line = String::ToString( " // %s %d\r\n", feature->getName().c_str(), index );
else
line = String::ToString( " // %s\r\n", feature->getName().c_str() );
mOutput->addStatement( new GenOp( line ) );
if ( feature->getOutput() )
mOutput->addStatement( feature->getOutput() );
feature->reset();
mOutput->addStatement( new GenOp( " \r\n" ) );
}
}
ShaderConnector *connect = dynamic_cast<ShaderConnector *>( mComponents[C_CONNECTOR] );
connect->sortVars();
}
void ShaderGen::_processPixFeatures( Vector<GFXShaderMacro> &macros, bool macrosOnly )
{
const FeatureSet &features = mFeatureData.features;
for( U32 i=0; i < features.getCount(); i++ )
{
S32 index;
const FeatureType &type = features.getAt( i, &index );
ShaderFeature* feature = FEATUREMGR->getByType( type );
if ( feature )
{
feature->setProcessIndex( index );
feature->processPixMacros( macros, mFeatureData );
if ( macrosOnly )
continue;
feature->mInstancingFormat = &mInstancingFormat;
feature->processPix( mComponents, mFeatureData );
String line;
if ( index > -1 )
line = String::ToString( " // %s %d\r\n", feature->getName().c_str(), index );
else
line = String::ToString( " // %s\r\n", feature->getName().c_str() );
mOutput->addStatement( new GenOp( line ) );
if ( feature->getOutput() )
mOutput->addStatement( feature->getOutput() );
feature->reset();
mOutput->addStatement( new GenOp( " \r\n" ) );
}
}
ShaderConnector *connect = dynamic_cast<ShaderConnector *>( mComponents[C_CONNECTOR] );
connect->sortVars();
}
void ShaderGen::_printFeatureList(Stream &stream)
{
mPrinter->printLine(stream, "// Features:");
const FeatureSet &features = mFeatureData.features;
for( U32 i=0; i < features.getCount(); i++ )
{
S32 index;
const FeatureType &type = features.getAt( i, &index );
ShaderFeature* feature = FEATUREMGR->getByType( type );
if ( feature )
{
String line;
if ( index > -1 )
line = String::ToString( "// %s %d", feature->getName().c_str(), index );
else
line = String::ToString( "// %s", feature->getName().c_str() );
mPrinter->printLine( stream, line );
}
}
mPrinter->printLine(stream, "");
}
void ShaderGen::_printDependencies(Stream &stream)
{
Vector<const ShaderDependency *> dependencies;
for( U32 i=0; i < FEATUREMGR->getFeatureCount(); i++ )
{
const FeatureInfo &info = FEATUREMGR->getAt( i );
if ( mFeatureData.features.hasFeature( *info.type ) )
dependencies.merge( info.feature->getDependencies() );
}
// Do a quick loop removing any duplicate dependancies.
for( U32 i=0; i < dependencies.size(); )
{
bool dup = false;
for( U32 j=0; j < dependencies.size(); j++ )
{
if ( j != i &&
*dependencies[i] == *dependencies[j] )
{
dup = true;
break;
}
}
if ( dup )
dependencies.erase( i );
else
i++;
}
// Print dependencies
if( dependencies.size() > 0 )
{
mPrinter->printLine(stream, "// Dependencies:");
for( int i = 0; i < dependencies.size(); i++ )
dependencies[i]->print( stream );
mPrinter->printLine(stream, "");
}
}
void ShaderGen::_printFeatures( Stream &stream )
{
mOutput->print( stream );
}
void ShaderGen::_printVertShader( Stream &stream )
{
mPrinter->printShaderHeader(stream);
_printDependencies(stream); // TODO: Split into vert and pix dependencies?
_printFeatureList(stream);
// print out structures
mComponents[C_VERT_STRUCT]->print( stream );
mComponents[C_CONNECTOR]->print( stream );
mPrinter->printMainComment(stream);
mComponents[C_VERT_MAIN]->print( stream );
// print out the function
_printFeatures( stream );
mPrinter->printVertexShaderCloser(stream);
}
void ShaderGen::_printPixShader( Stream &stream )
{
mPrinter->printShaderHeader(stream);
_printDependencies(stream); // TODO: Split into vert and pix dependencies?
_printFeatureList(stream);
mComponents[C_CONNECTOR]->print( stream );
mPrinter->printPixelShaderOutputStruct(stream, mFeatureData);
mPrinter->printMainComment(stream);
mComponents[C_PIX_MAIN]->print( stream );
// print out the function
_printFeatures( stream );
mPrinter->printPixelShaderCloser(stream);
}
GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros )
{
PROFILE_SCOPE( ShaderGen_GetShader );
const FeatureSet &features = featureData.codify();
// Build a description string from the features
// and vertex format combination ( and macros ).
String shaderDescription = vertexFormat->getDescription() + features.getDescription();
if ( macros && !macros->empty() )
{
String macroStr;
GFXShaderMacro::stringize( *macros, &macroStr );
shaderDescription += macroStr;
}
// Generate a single 64bit hash from the description string.
//
// Don't get paranoid! This has 1 in 18446744073709551616
// chance for collision... it won't happen in this lifetime.
//
U64 hash = Torque::hash64( (const U8*)shaderDescription.c_str(), shaderDescription.length(), 0 );
hash = convertHostToLEndian(hash);
U32 high = (U32)( hash >> 32 );
U32 low = (U32)( hash & 0x00000000FFFFFFFF );
String cacheKey = String::ToString( "%x%x", high, low );
// return shader if exists
GFXShader *match = mProcShaders[cacheKey];
if ( match )
return match;
// if not, then create it
char vertFile[256];
char pixFile[256];
F32 pixVersion;
Vector<GFXShaderMacro> shaderMacros;
shaderMacros.push_back( GFXShaderMacro( "TORQUE_SHADERGEN" ) );
if ( macros )
shaderMacros.merge( *macros );
generateShader( featureData, vertFile, pixFile, &pixVersion, vertexFormat, cacheKey, shaderMacros );
GFXShader *shader = GFX->createShader();
shader->mInstancingFormat.copy( mInstancingFormat ); // TODO: Move to init() below!
if ( !shader->init( vertFile, pixFile, pixVersion, shaderMacros ) )
{
delete shader;
return NULL;
}
mProcShaders[cacheKey] = shader;
return shader;
}
void ShaderGen::flushProceduralShaders()
{
// The shaders are reference counted, so we
// just need to clear the map.
mProcShaders.clear();
}

View file

@ -0,0 +1,233 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGEN_H_
#define _SHADERGEN_H_
#ifndef _LANG_ELEMENT_H_
#include "shaderGen/langElement.h"
#endif
#ifndef _SHADERFEATURE_H_
#include "shaderGen/shaderFeature.h"
#endif
#ifndef _SHADERCOMP_H_
#include "shaderGen/shaderComp.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
#ifndef _AUTOPTR_H_
#include "core/util/autoPtr.h"
#endif
#ifndef _TSINGLETON_H_
#include "core/util/tSingleton.h"
#endif
#ifndef _VOLUME_H_
#include "core/volume.h"
#endif
#ifndef _MATERIALFEATUREDATA_H_
#include "materials/materialFeatureData.h"
#endif
/// Base class used by shaderGen to be API agnostic. Subclasses implement the various methods
/// in an API specific way.
class ShaderGenPrinter
{
public:
virtual ~ShaderGenPrinter() {}
/// Prints a simple header, including the engine name, language type, and
/// the fact that the shader was procedurally generated
virtual void printShaderHeader(Stream& stream) = 0;
/// Prints a comment block specifying the beginning of the main() function (or equivalent)
virtual void printMainComment(Stream& stream) = 0;
/// Prints the final line of the vertex shader, e.g. return OUT; }, }, END
virtual void printVertexShaderCloser(Stream& stream) = 0;
/// Prints the output struct for the pixel shader. Probably only used in HLSL/Cg.
virtual void printPixelShaderOutputStruct(Stream& stream, const MaterialFeatureData &featureData) = 0;
/// Prints the final line of the pixel shader.
virtual void printPixelShaderCloser(Stream& stream) = 0;
// Prints a line into the shader adding the proper terminator.
virtual void printLine(Stream& stream, const String& line) = 0;
};
/// Abstract factory for created (and initializating, if necessary) shader components.
class ShaderGenComponentFactory
{
public:
virtual ~ShaderGenComponentFactory() {}
/// Creates and initializes a vertex input connector with the specified flags
virtual ShaderComponent* createVertexInputConnector( const GFXVertexFormat &vertexFormat ) = 0;
/// Creates and names a vertex/pixel connector
virtual ShaderComponent* createVertexPixelConnector() = 0;
/// Creates an instance of VertexParamsDef
virtual ShaderComponent* createVertexParamsDef() = 0;
/// Creates an instance of PixelParamsDef
virtual ShaderComponent* createPixelParamsDef() = 0;
};
//**************************************************************************
/*!
The ShaderGen class takes shader feature data (usually created by
MatInstance) and creates a vertex/pixel shader pair in text files
to be later compiled by a shader manager.
It accomplishes this task by creating a group of shader "components" and
"features" that output bits of high level shader code. Shader components
translate to structures in HLSL that indicate incoming vertex data,
data that is output from the vertex shader to the pixel shader, and data
such as constants and textures that are passed directly to the shader
from the app.
Shader features are separable shader functions that can be turned on or
off. Examples would be bumpmapping and specular highlights. See
MaterialFeatureData for the current list of features supported.
ShaderGen processes all of the features that are present for a desired
shader, and then prints them out to the respective vertex or pixel
shader file.
For more information on shader features and components see the
ShaderFeature and ShaderComponent classes.
*/
//**************************************************************************
//**************************************************************************
// Shader generator
//**************************************************************************
class ShaderGen
{
public:
virtual ~ShaderGen();
/// Parameter 1 is the ShaderGen instance to initialize.
typedef Delegate<void (ShaderGen*)> ShaderGenInitDelegate;
/// Register an initialization delegate for adapterType. This should setPrinter/ComponentFactory/etc, and register
/// shader features.
void registerInitDelegate(GFXAdapterType adapterType, ShaderGenInitDelegate& initDelegate);
/// Signal used to notify systems to register features.
typedef Signal<void(GFXAdapterType type)> FeatureInitSignal;
/// Returns the signal used to notify systems to register features.
FeatureInitSignal& getFeatureInitSignal() { return mFeatureInitSignal; }
/// vertFile and pixFile are filled in by this function. They point to
/// the vertex and pixel shader files. pixVersion is also filled in by
/// this function.
/// @param assignNum used to assign a specific number as the filename
void generateShader( const MaterialFeatureData &featureData,
char *vertFile,
char *pixFile,
F32 *pixVersion,
const GFXVertexFormat *vertexFormat,
const char* cacheName,
Vector<GFXShaderMacro> &macros );
// Returns a shader that implements the features listed by dat.
GFXShader* getShader( const MaterialFeatureData &dat, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros );
// This will delete all of the procedural shaders that we have. Used to regenerate shaders when
// the ShaderFeatures have changed (due to lighting system change, or new plugin)
virtual void flushProceduralShaders();
void setPrinter(ShaderGenPrinter* printer) { mPrinter = printer; }
void setComponentFactory(ShaderGenComponentFactory* factory) { mComponentFactory = factory; }
void setFileEnding(String ending) { mFileEnding = ending; }
protected:
friend class ManagedSingleton<ShaderGen>;
// Shader generation
MaterialFeatureData mFeatureData;
const GFXVertexFormat *mVertexFormat;
Vector< ShaderComponent *> mComponents;
AutoPtr<ShaderGenPrinter> mPrinter;
AutoPtr<ShaderGenComponentFactory> mComponentFactory;
String mFileEnding;
/// The currently processing output.
MultiLine *mOutput;
GFXVertexFormat mInstancingFormat;
/// Init
bool mInit;
ShaderGenInitDelegate mInitDelegates[GFXAdapterType_Count];
FeatureInitSignal mFeatureInitSignal;
bool mRegisteredWithGFX;
Torque::FS::FileSystemRef mMemFS;
/// Map of cache string -> shaders
typedef Map<String, GFXShaderRef> ShaderMap;
ShaderMap mProcShaders;
ShaderGen();
bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);
/// Causes the init delegate to be called.
void initShaderGen();
void _init();
void _uninit();
/// Creates all the various shader components that will be filled in when
/// the shader features are processed.
void _createComponents();
void _printFeatureList(Stream &stream);
/// print out the processed features to the file stream
void _printFeatures( Stream &stream );
void _printDependencies( Stream &stream );
void _processPixFeatures( Vector<GFXShaderMacro> &macros, bool macrosOnly = false );
void _printPixShader( Stream &stream );
void _processVertFeatures( Vector<GFXShaderMacro> &macros, bool macrosOnly = false );
void _printVertShader( Stream &stream );
// For ManagedSingleton.
static const char* getSingletonName() { return "ShaderGen"; }
};
/// Returns the ShaderGen singleton.
#define SHADERGEN ManagedSingleton<ShaderGen>::instance()
#endif // _SHADERGEN_H_

View file

@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "shaderGen/shaderGenVars.h"
const String ShaderGenVars::modelview("$modelview");
const String ShaderGenVars::worldViewOnly("$worldViewOnly");
const String ShaderGenVars::worldToCamera("$worldToCamera");
const String ShaderGenVars::worldToObj("$worldToObj");
const String ShaderGenVars::viewToObj("$viewToObj");
const String ShaderGenVars::cubeTrans("$cubeTrans");
const String ShaderGenVars::objTrans("$objTrans");
const String ShaderGenVars::cubeEyePos("$cubeEyePos");
const String ShaderGenVars::eyePos("$eyePos");
const String ShaderGenVars::eyePosWorld("$eyePosWorld");
const String ShaderGenVars::vEye("$vEye");
const String ShaderGenVars::eyeMat("$eyeMat");
const String ShaderGenVars::oneOverFarplane("$oneOverFarplane");
const String ShaderGenVars::nearPlaneWorld("$nearPlaneWorld");
const String ShaderGenVars::fogData("$fogData");
const String ShaderGenVars::fogColor("$fogColor");
const String ShaderGenVars::detailScale("$detailScale");
const String ShaderGenVars::visibility("$visibility");
const String ShaderGenVars::colorMultiply("$colorMultiply");
const String ShaderGenVars::alphaTestValue("$alphaTestValue");
const String ShaderGenVars::texMat("$texMat");
const String ShaderGenVars::accumTime("$accumTime");
const String ShaderGenVars::minnaertConstant("$minnaertConstant");
const String ShaderGenVars::subSurfaceParams("$subSurfaceParams");
const String ShaderGenVars::diffuseAtlasParams("$diffuseAtlasParams");
const String ShaderGenVars::diffuseAtlasTileParams("$diffuseAtlasTileParams");
const String ShaderGenVars::bumpAtlasParams("$bumpAtlasParams");
const String ShaderGenVars::bumpAtlasTileParams("$bumpAtlasTileParams");
const String ShaderGenVars::targetSize("$targetSize");
const String ShaderGenVars::oneOverTargetSize("$oneOverTargetSize");
const String ShaderGenVars::lightPosition("$inLightPos");
const String ShaderGenVars::lightDiffuse("$inLightColor");
const String ShaderGenVars::lightAmbient("$ambient");
const String ShaderGenVars::lightInvRadiusSq("$inLightInvRadiusSq");
const String ShaderGenVars::lightSpotDir("$inLightSpotDir");
const String ShaderGenVars::lightSpotAngle("$inLightSpotAngle");
const String ShaderGenVars::lightSpotFalloff("$inLightSpotFalloff");
const String ShaderGenVars::specularColor("$specularColor");
const String ShaderGenVars::specularPower("$specularPower");
// These are ignored by the D3D layers.
const String ShaderGenVars::fogMap("$fogMap");
const String ShaderGenVars::dlightMap("$dlightMap");
const String ShaderGenVars::dlightMask("$dlightMask");
const String ShaderGenVars::dlightMapSec("$dlightMapSec");
const String ShaderGenVars::blackfogMap("$blackfogMap");
const String ShaderGenVars::bumpMap("$bumpMap");
const String ShaderGenVars::lightMap("$lightMap");
const String ShaderGenVars::lightNormMap("$lightNormMap");
const String ShaderGenVars::cubeMap("$cubeMap");
const String ShaderGenVars::dLightMap("$dlightMap");
const String ShaderGenVars::dLightMapSec("$dlightMapSec");
const String ShaderGenVars::dLightMask("$dlightMask");
const String ShaderGenVars::toneMap("$toneMap");

View file

@ -0,0 +1,98 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADERGENVARS_H_
#define _SHADERGENVARS_H_
#ifndef _TORQUE_STRING_H_
#include "core/util/str.h"
#endif
///
/// ShaderGenVars, predefined string names for variables that shadergen based shaders use, this avoids
/// misspelling and string creation issues
///
struct ShaderGenVars
{
const static String modelview;
const static String worldViewOnly;
const static String worldToCamera;
const static String worldToObj;
const static String viewToObj;
const static String cubeTrans;
const static String objTrans;
const static String cubeEyePos;
const static String eyePos;
const static String eyePosWorld;
const static String vEye;
const static String eyeMat;
const static String oneOverFarplane;
const static String nearPlaneWorld;
const static String fogData;
const static String fogColor;
const static String detailScale;
const static String visibility;
const static String colorMultiply;
const static String alphaTestValue;
const static String texMat;
const static String accumTime;
const static String minnaertConstant;
const static String subSurfaceParams;
// Texture atlasing parameters
const static String diffuseAtlasParams;
const static String diffuseAtlasTileParams;
const static String bumpAtlasParams;
const static String bumpAtlasTileParams;
// Render target parameters
const static String targetSize;
const static String oneOverTargetSize;
// Lighting parameters used by the default
// RTLighting shader feature.
const static String lightPosition;
const static String lightDiffuse;
const static String lightAmbient;
const static String lightInvRadiusSq;
const static String lightSpotDir;
const static String lightSpotAngle;
const static String lightSpotFalloff;
const static String specularColor;
const static String specularPower;
// Textures
const static String fogMap;
const static String dlightMap;
const static String dlightMask;
const static String dlightMapSec;
const static String blackfogMap;
const static String bumpMap;
const static String lightMap;
const static String lightNormMap;
const static String cubeMap;
const static String dLightMap;
const static String dLightMapSec;
const static String dLightMask;
const static String toneMap;
};
#endif

View file

@ -0,0 +1,158 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "core/strings/stringFunctions.h"
#include <stdarg.h>
#include "shaderOp.h"
//**************************************************************************
// Shader Operations
//**************************************************************************
ShaderOp::ShaderOp( LangElement *in1, LangElement *in2 )
{
mInput[0] = in1;
mInput[1] = in2;
}
//**************************************************************************
// Declaration Operation - for variables
//**************************************************************************
DecOp::DecOp( Var *in1 ) : Parent( in1, NULL )
{
mInput[0] = in1;
}
//--------------------------------------------------------------------------
// Print
//--------------------------------------------------------------------------
void DecOp::print( Stream &stream )
{
Var *var = dynamic_cast<Var*>( mInput[0] );
WRITESTR( (char*)var->type );
WRITESTR( " " );
mInput[0]->print( stream );
}
//**************************************************************************
// Echo operation - deletes incoming statement!
//**************************************************************************
EchoOp::EchoOp( const char * statement ) : Parent( NULL, NULL )
{
mStatement = statement;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
EchoOp::~EchoOp()
{
delete [] mStatement;
}
//--------------------------------------------------------------------------
// Print
//--------------------------------------------------------------------------
void EchoOp::print( Stream &stream )
{
WRITESTR( mStatement );
}
//**************************************************************************
// General operation
//**************************************************************************
GenOp::GenOp( const char * statement, ... ) : Parent( NULL, NULL )
{
VECTOR_SET_ASSOCIATION( mElemList );
va_list args;
va_start(args, statement);
char* lastEntry = (char*)statement;
while( 1 )
{
// search 'statement' for @ symbol
char * str = dStrstr( lastEntry, (char *)"@" );
if( !str )
{
// not found, handle end of line
str = (char*)&statement[ dStrlen( (char*)statement ) ];
U32 diff = str - lastEntry + 1;
if( diff == 1 ) break;
char * newStr = new char[diff];
dMemcpy( (void*)newStr, lastEntry, diff );
mElemList.push_back( new EchoOp( newStr ) );
break;
}
// create and store statement fragment
U32 diff = str - lastEntry + 1;
if( diff == 1 )
{
// store langElement
LangElement *elem = va_arg(args, LangElement* );
AssertFatal( elem, "NULL arguement." );
mElemList.push_back( elem );
lastEntry++;
continue;
}
char * newStr = new char[diff];
dMemcpy( (void*)newStr, lastEntry, diff );
newStr[diff-1] = '\0';
lastEntry = str + 1;
mElemList.push_back( new EchoOp( newStr ) );
// store langElement
LangElement *elem = va_arg(args, LangElement* );
AssertFatal( elem, "NULL argument." );
mElemList.push_back( elem );
}
va_end( args );
}
//--------------------------------------------------------------------------
// Print
//--------------------------------------------------------------------------
void GenOp::print( Stream &stream )
{
for( U32 i=0; i<mElemList.size(); i++ )
{
mElemList[i]->print( stream );
}
}

View file

@ -0,0 +1,151 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SHADEROP_H_
#define _SHADEROP_H_
#ifndef _LANG_ELEMENT_H_
#include "shaderGen/langElement.h"
#endif
//**************************************************************************
/*!
This file contains "shader operation" classes. Originally they were
to represent basic language operations like adding, assignment, etc.
That proved to be far too verbose when implementing shader features,
so they became more generalized helper classes. Along with LangElement
classes, they are the building blocks for the procedurally generated
shaders.
Each shader is a linked list of LangElements. The list is generated
when the features of the shader are processed. When all the features
are processed, then ShaderGen prints them out by traversing the linked
list of LangElement and calling their print() function.
The ShaderOp classes are just extensions of LangElement.
*/
//**************************************************************************
///**************************************************************************
/// Shader operation base class
///**************************************************************************
class ShaderOp : public LangElement
{
protected:
LangElement * mInput[2];
public:
ShaderOp( LangElement *in1, LangElement *in2 );
};
//----------------------------------------------------------------------------
/*!
DecOp - Declaration Operation - Used when declaring a variable in a shader
feature. It will automatically print the type of the variable and then
the variable name. If a shader feature set up code like:
@code
Var *foo = new Var;
foo->setType( "float" );
foo->setName( "foo" );
LangElement *fooDecl = new DecOp( foo );
LangElement *statement = new GenOp( " @ = 8.0 * 5.0;", fooDecl );
@endcode
The output in the shader file would be:
@code
float foo = 8.0 * 5.0;
@endcode
*/
//----------------------------------------------------------------------------
class DecOp : public ShaderOp
{
typedef ShaderOp Parent;
public:
DecOp( Var *in1 );
virtual void print( Stream &stream );
};
//----------------------------------------------------------------------------
/*!
Like the name suggests, EchoOp merely echoes back whatever string it is
assigned.
*/
//----------------------------------------------------------------------------
class EchoOp : public ShaderOp
{
typedef ShaderOp Parent;
const char * mStatement;
public:
EchoOp( const char * statement );
~EchoOp();
virtual void print( Stream &stream );
};
//----------------------------------------------------------------------------
/*!
GenOp - General Operation - Very useful for combining several variables
into one LangElement statement. It uses an elipses as a parameter, so it can
take as many variables as you can throw at it. It takes a string and parses
it for the '@' symbol which it replaces with passed in parameters. Similar
to the C statement printf(). Here's an example:
@code
( assuming three variables var1, var2, var3 exist and their assigned names
are var1Name, var2Name, and var3Name )
LangElement *statement = new GenOp( " @ = @ * @.x + @.y;", var1, var1, var2, var3 );
@endcode
The output in the shader file would be:
@code
var1Name = var1Name * var2Name.x + var3Name.y;
@endcode
*/
//----------------------------------------------------------------------------
class GenOp : public ShaderOp
{
typedef ShaderOp Parent;
Vector<LangElement *> mElemList;
public:
GenOp( const char * statement, ... );
virtual void print( Stream &stream );
};
#endif // _SHADEROP_H_