Browse Source

Groundwork for other shaders

Adds the ground work for geometry shaders
Expands shaderData and gfxShader to allow for more shader types

note: when building a GFXShader in source you have to call setShaderStageFile with the shaderStage and the filepath for that stage.

Once we add compute shaders this will become more apparent as compute shaders are a stage of their own and do not require vertex and pixel files whereas other shaders sometimes do.
marauder2k7 1 year ago
parent
commit
808e2f4200

+ 40 - 15
Engine/source/gfx/gfxShader.cpp

@@ -49,9 +49,9 @@ GFXShader::~GFXShader()
 }
 }
 
 
 #ifndef TORQUE_OPENGL
 #ifndef TORQUE_OPENGL
-bool GFXShader::init(   const Torque::Path &vertFile, 
-                        const Torque::Path &pixFile, 
-                        F32 pixVersion, 
+bool GFXShader::init(   const Torque::Path &vertFile,
+                        const Torque::Path &pixFile,
+                        F32 pixVersion,
                         const Vector<GFXShaderMacro> &macros )
                         const Vector<GFXShaderMacro> &macros )
 {
 {
    Vector<String> samplerNames;
    Vector<String> samplerNames;
@@ -59,13 +59,18 @@ bool GFXShader::init(   const Torque::Path &vertFile,
 }
 }
 #endif
 #endif
 
 
-bool GFXShader::init(   const Torque::Path &vertFile, 
-                        const Torque::Path &pixFile, 
-                        F32 pixVersion, 
+bool GFXShader::init(   F32 pixVersion,
                         const Vector<GFXShaderMacro> &macros,
                         const Vector<GFXShaderMacro> &macros,
                         const Vector<String> &samplerNames,
                         const Vector<String> &samplerNames,
                         GFXVertexFormat *instanceFormat)
                         GFXVertexFormat *instanceFormat)
 {
 {
+   // early out.
+   if (mVertexFile.isEmpty() && mPixelFile.isEmpty() && mGeometryFile.isEmpty())
+   {
+      Con::errorf("Shader files empty, please call setShaderStageFile from shaderData");
+      return false;
+   }
+
    // Take care of instancing
    // Take care of instancing
    if (instanceFormat)
    if (instanceFormat)
    {
    {
@@ -74,8 +79,6 @@ bool GFXShader::init(   const Torque::Path &vertFile,
    }
    }
 
 
    // Store the inputs for use in reloading.
    // Store the inputs for use in reloading.
-   mVertexFile = vertFile;
-   mPixelFile = pixFile;
    mPixVersion = pixVersion;
    mPixVersion = pixVersion;
    mMacros = macros;
    mMacros = macros;
    mSamplerNamesOrdered = samplerNames;
    mSamplerNamesOrdered = samplerNames;
@@ -91,8 +94,12 @@ bool GFXShader::init(   const Torque::Path &vertFile,
    _updateDesc();
    _updateDesc();
 
 
    // Add file change notifications for reloads.
    // Add file change notifications for reloads.
-   Torque::FS::AddChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
-   Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
+   if(!mVertexFile.isEmpty())
+      Torque::FS::AddChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
+   if(!mPixelFile.isEmpty())
+      Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
+   if(!mGeometryFile.isEmpty())
+      Torque::FS::AddChangeNotification( mGeometryFile, this, &GFXShader::_onFileChanged);
 
 
    return true;
    return true;
 }
 }
@@ -119,11 +126,11 @@ bool GFXShader::reload()
 
 
 void GFXShader::_updateDesc()
 void GFXShader::_updateDesc()
 {
 {
-   mDescription = String::ToString( "Files: %s, %s Pix Version: %0.2f\nMacros: ", 
+   mDescription = String::ToString( "Files: %s, %s Pix Version: %0.2f\nMacros: ",
       mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), mPixVersion );
       mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), mPixVersion );
 
 
    GFXShaderMacro::stringize( smGlobalMacros, &mDescription );
    GFXShaderMacro::stringize( smGlobalMacros, &mDescription );
-   GFXShaderMacro::stringize( mMacros, &mDescription );   
+   GFXShaderMacro::stringize( mMacros, &mDescription );
 }
 }
 
 
 void GFXShader::addGlobalMacro( const String &name, const String &value )
 void GFXShader::addGlobalMacro( const String &name, const String &value )
@@ -161,8 +168,26 @@ bool GFXShader::removeGlobalMacro( const String &name )
    return false;
    return false;
 }
 }
 
 
+void GFXShader::setShaderStageFile(const GFXShaderStage stage, const Torque::Path& filePath)
+{
+   switch (stage)
+   {
+   case GFXShaderStage::VERTEX_SHADER:
+      mVertexFile = filePath;
+      break;
+   case GFXShaderStage::PIXEL_SHADER:
+      mPixelFile = filePath;
+      break;
+   case GFXShaderStage::GEOMETRY_SHADER:
+      mGeometryFile = filePath;
+      break;
+   default:
+      break;
+   }
+}
+
 void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
 void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
-{   
+{
    Vector<GFXShaderConstBuffer*>::iterator iter = mActiveBuffers.begin();
    Vector<GFXShaderConstBuffer*>::iterator iter = mActiveBuffers.begin();
    for ( ; iter != mActiveBuffers.end(); iter++ )
    for ( ; iter != mActiveBuffers.end(); iter++ )
    {
    {
@@ -177,7 +202,7 @@ void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
 }
 }
 
 
 
 
-DefineEngineFunction( addGlobalShaderMacro, void, 
+DefineEngineFunction( addGlobalShaderMacro, void,
    ( const char *name, const char *value ), ( nullAsType<const char*>() ),
    ( const char *name, const char *value ), ( nullAsType<const char*>() ),
    "Adds a global shader macro which will be merged with the script defined "
    "Adds a global shader macro which will be merged with the script defined "
    "macros on every shader.  The macro will replace the value of an existing "
    "macros on every shader.  The macro will replace the value of an existing "
@@ -189,7 +214,7 @@ DefineEngineFunction( addGlobalShaderMacro, void,
    GFXShader::addGlobalMacro( name, value );
    GFXShader::addGlobalMacro( name, value );
 }
 }
 
 
-DefineEngineFunction( removeGlobalShaderMacro, void, ( const char *name ),, 
+DefineEngineFunction( removeGlobalShaderMacro, void, ( const char *name ),,
    "Removes an existing global macro by name.\n"
    "Removes an existing global macro by name.\n"
    "@see addGlobalShaderMacro\n"
    "@see addGlobalShaderMacro\n"
    "@ingroup Rendering\n" )
    "@ingroup Rendering\n" )

+ 44 - 41
Engine/source/gfx/gfxShader.h

@@ -76,7 +76,7 @@ enum GFXShaderStage
 };
 };
 
 
 /// Instances of this struct are returned GFXShaderConstBuffer
 /// Instances of this struct are returned GFXShaderConstBuffer
-struct GFXShaderConstDesc 
+struct GFXShaderConstDesc
 {
 {
 public:
 public:
    String name;
    String name;
@@ -92,7 +92,7 @@ public:
 /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
 /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
 /// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
 /// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
 /// (or shader).  Client code should not free these.
 /// (or shader).  Client code should not free these.
-class GFXShaderConstHandle 
+class GFXShaderConstHandle
 {
 {
 public:
 public:
 
 
@@ -101,8 +101,8 @@ public:
 
 
    /// Returns true if this constant is valid and can
    /// Returns true if this constant is valid and can
    /// be set on the shader.
    /// be set on the shader.
-   bool isValid() const { return mValid; }   
-   
+   bool isValid() const { return mValid; }
+
    /// Returns the name of the constant handle.
    /// Returns the name of the constant handle.
    virtual const String& getName() const = 0;
    virtual const String& getName() const = 0;
 
 
@@ -110,7 +110,7 @@ public:
    virtual GFXShaderConstType getType() const = 0;
    virtual GFXShaderConstType getType() const = 0;
 
 
    virtual U32 getArraySize() const = 0;
    virtual U32 getArraySize() const = 0;
-   
+
    /// Returns -1 if this handle does not point to a Sampler.
    /// Returns -1 if this handle does not point to a Sampler.
    virtual S32 getSamplerRegister() const = 0;
    virtual S32 getSamplerRegister() const = 0;
 
 
@@ -119,7 +119,7 @@ protected:
    /// The state of the constant which is
    /// The state of the constant which is
    /// set from the derived class.
    /// set from the derived class.
    bool mValid;
    bool mValid;
-   
+
 };
 };
 
 
 
 
@@ -143,7 +143,7 @@ protected:
    /// @see wasLost
    /// @see wasLost
    bool mWasLost;
    bool mWasLost;
 
 
-   GFXShaderConstBuffer()   
+   GFXShaderConstBuffer()
       :  mWasLost( true ),
       :  mWasLost( true ),
          mInstPtr( NULL )
          mInstPtr( NULL )
    {
    {
@@ -155,16 +155,16 @@ public:
    virtual GFXShader* getShader() = 0;
    virtual GFXShader* getShader() = 0;
 
 
    /// The content of the buffer is in the lost state when
    /// The content of the buffer is in the lost state when
-   /// first created or when the shader is reloaded.  When 
+   /// first created or when the shader is reloaded.  When
    /// the content is lost you must refill the buffer
    /// the content is lost you must refill the buffer
    /// with all the constants used by your shader.
    /// with all the constants used by your shader.
    ///
    ///
-   /// Use this property to avoid setting constants which do 
+   /// Use this property to avoid setting constants which do
    /// not changefrom one frame to the next.
    /// not changefrom one frame to the next.
    ///
    ///
    bool wasLost() const { return mWasLost; }
    bool wasLost() const { return mWasLost; }
 
 
-   /// An inline helper which ensures the handle is valid 
+   /// An inline helper which ensures the handle is valid
    /// before the virtual set method is called.
    /// before the virtual set method is called.
    ///
    ///
    /// You should prefer using this method unless your sure the
    /// You should prefer using this method unless your sure the
@@ -183,7 +183,7 @@ public:
    ///
    ///
    /// Perfer using setSafe unless you can check the handle
    /// Perfer using setSafe unless you can check the handle
    /// validity yourself and skip a significat amount of work.
    /// validity yourself and skip a significat amount of work.
-   ///   
+   ///
    /// @see GFXShaderConstHandle::isValid()
    /// @see GFXShaderConstHandle::isValid()
    ///
    ///
    virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
    virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
@@ -204,19 +204,19 @@ public:
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
    virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
-   
-   /// Set a variable sized matrix shader constant.   
-   virtual void set( GFXShaderConstHandle* handle, 
-                     const MatrixF& mat, 
+
+   /// Set a variable sized matrix shader constant.
+   virtual void set( GFXShaderConstHandle* handle,
+                     const MatrixF& mat,
                      const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
                      const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
-   
+
    /// Set a variable sized matrix shader constant from
    /// Set a variable sized matrix shader constant from
-   /// an array of matricies.   
-   virtual void set( GFXShaderConstHandle* handle, 
-                     const MatrixF* mat, 
-                     const U32 arraySize, 
+   /// an array of matricies.
+   virtual void set( GFXShaderConstHandle* handle,
+                     const MatrixF* mat,
+                     const U32 arraySize,
                      const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
                      const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
-   
+
    // TODO: Make this protected and put a real API around it.
    // TODO: Make this protected and put a real API around it.
    U8 *mInstPtr;
    U8 *mInstPtr;
 };
 };
@@ -232,8 +232,8 @@ class GFXShader : public StrongRefBase, public GFXResource
    friend class GFXShaderConstBuffer;
    friend class GFXShaderConstBuffer;
 
 
 protected:
 protected:
-  
-   /// These are system wide shader macros which are 
+
+   /// These are system wide shader macros which are
    /// merged with shader specific macros at creation.
    /// merged with shader specific macros at creation.
    static Vector<GFXShaderMacro> smGlobalMacros;
    static Vector<GFXShaderMacro> smGlobalMacros;
 
 
@@ -244,19 +244,22 @@ protected:
    static bool smLogWarnings;
    static bool smLogWarnings;
 
 
    /// The vertex shader file.
    /// The vertex shader file.
-   Torque::Path mVertexFile;  
+   Torque::Path mVertexFile;
 
 
    /// The pixel shader file.
    /// The pixel shader file.
-   Torque::Path mPixelFile;  
+   Torque::Path mPixelFile;
+
+   // the geometry shader file.
+   Torque::Path mGeometryFile;
 
 
-   /// The macros to be passed to the shader.      
+   /// The macros to be passed to the shader.
    Vector<GFXShaderMacro> mMacros;
    Vector<GFXShaderMacro> mMacros;
 
 
    /// Ordered SamplerNames
    /// Ordered SamplerNames
    /// We need to store a list of sampler for allow OpenGL to
    /// We need to store a list of sampler for allow OpenGL to
    /// assign correct location for each sampler.
    /// assign correct location for each sampler.
    /// GLSL 150 not allow explicit uniform location.
    /// GLSL 150 not allow explicit uniform location.
-   /// Only used on OpenGL   
+   /// Only used on OpenGL
    Vector<String> mSamplerNamesOrdered;
    Vector<String> mSamplerNamesOrdered;
 
 
    /// The pixel version this is compiled for.
    /// The pixel version this is compiled for.
@@ -271,7 +274,7 @@ protected:
    Signal<void()> mReloadSignal;
    Signal<void()> mReloadSignal;
 
 
    /// Vector of buffers that reference this shader.
    /// Vector of buffers that reference this shader.
-   /// It is the responsibility of the derived shader class to populate this 
+   /// It is the responsibility of the derived shader class to populate this
    /// vector and to notify them when this shader is reloaded.  Classes
    /// vector and to notify them when this shader is reloaded.  Classes
    /// derived from GFXShaderConstBuffer should call _unlinkBuffer from
    /// derived from GFXShaderConstBuffer should call _unlinkBuffer from
    /// their destructor.
    /// their destructor.
@@ -282,7 +285,7 @@ protected:
    /// A protected constructor so it cannot be instantiated.
    /// A protected constructor so it cannot be instantiated.
    GFXShader();
    GFXShader();
 
 
-public:  
+public:
 
 
    /// Adds a global shader macro which will be merged with
    /// Adds a global shader macro which will be merged with
    /// the script defined macros on every shader reload.
    /// the script defined macros on every shader reload.
@@ -303,9 +306,9 @@ public:
 
 
    /// Toggle logging for shader errors.
    /// Toggle logging for shader errors.
    static void setLogging( bool logErrors,
    static void setLogging( bool logErrors,
-                           bool logWarning ) 
+                           bool logWarning )
    {
    {
-      smLogErrors = logErrors; 
+      smLogErrors = logErrors;
       smLogWarnings = logWarning;
       smLogWarnings = logWarning;
    }
    }
 
 
@@ -315,16 +318,14 @@ public:
    ///
    ///
    /// Deprecated. Remove on T3D 4.0
    /// Deprecated. Remove on T3D 4.0
 #ifndef TORQUE_OPENGL
 #ifndef TORQUE_OPENGL
-   bool init(  const Torque::Path &vertFile, 
-               const Torque::Path &pixFile, 
-               F32 pixVersion, 
+   bool init(  const Torque::Path &vertFile,
+               const Torque::Path &pixFile,
+               F32 pixVersion,
                const Vector<GFXShaderMacro> &macros );
                const Vector<GFXShaderMacro> &macros );
 #endif
 #endif
 
 
    ///
    ///
-   bool init(  const Torque::Path &vertFile, 
-               const Torque::Path &pixFile, 
-               F32 pixVersion, 
+   bool init( F32 pixVersion,
                const Vector<GFXShaderMacro> &macros,
                const Vector<GFXShaderMacro> &macros,
                const Vector<String> &samplerNames,
                const Vector<String> &samplerNames,
                GFXVertexFormat *instanceFormat = NULL );
                GFXVertexFormat *instanceFormat = NULL );
@@ -335,23 +336,23 @@ public:
    Signal<void()> getReloadSignal() { return mReloadSignal; }
    Signal<void()> getReloadSignal() { return mReloadSignal; }
 
 
    /// Allocate a constant buffer
    /// Allocate a constant buffer
-   virtual GFXShaderConstBufferRef allocConstBuffer() = 0;  
+   virtual GFXShaderConstBufferRef allocConstBuffer() = 0;
 
 
    /// Returns our list of shader constants, the material can get this and just set the constants it knows about
    /// Returns our list of shader constants, the material can get this and just set the constants it knows about
    virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
    virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
 
 
    /// Returns a shader constant handle for the name constant.
    /// Returns a shader constant handle for the name constant.
    ///
    ///
-   /// Since shaders can reload and later have handles that didn't 
+   /// Since shaders can reload and later have handles that didn't
    /// exist originally this will return a handle in an invalid state
    /// exist originally this will return a handle in an invalid state
    /// if the constant doesn't exist at this time.
    /// if the constant doesn't exist at this time.
-   virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0; 
+   virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0;
 
 
    /// Returns a shader constant handle for the name constant, if the variable doesn't exist NULL is returned.
    /// Returns a shader constant handle for the name constant, if the variable doesn't exist NULL is returned.
    virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
    virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
 
 
    /// Returns the alignment value for constType
    /// Returns the alignment value for constType
-   virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;   
+   virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;
 
 
    /// Returns the required vertex format for this shader.
    /// Returns the required vertex format for this shader.
    /// Returns the pixel shader version.
    /// Returns the pixel shader version.
@@ -364,6 +365,8 @@ public:
    /// the shader disassembly.
    /// the shader disassembly.
    virtual bool getDisassembly( String &outStr ) const { return false; }
    virtual bool getDisassembly( String &outStr ) const { return false; }
 
 
+   void setShaderStageFile(const GFXShaderStage stage, const Torque::Path& filePath);
+
    /// Returns the vertex shader file path.
    /// Returns the vertex shader file path.
    const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
    const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
 
 

+ 3 - 3
Engine/source/gui/shaderEditor/guiShaderEditor.cpp

@@ -134,7 +134,7 @@ void GuiShaderEditor::onPreRender()
    setUpdate();
    setUpdate();
 }
 }
 
 
-void GuiShaderEditor::drawThickLine(const Point2I& pt1, const Point2I& pt2, U32 thickness = 2, ColorI col1 = ColorI(255, 255, 255), ColorI col2 = ColorI(255, 255, 255))
+void GuiShaderEditor::drawThickLine(const Point2I& pt1, const Point2I& pt2, U32 thickness, ColorI col1, ColorI col2)
 {
 {
    Point2F dir = Point2F(pt2.x - pt1.x, pt2.y - pt1.y);
    Point2F dir = Point2F(pt2.x - pt1.x, pt2.y - pt1.y);
    if (dir == Point2F::Zero)
    if (dir == Point2F::Zero)
@@ -292,7 +292,7 @@ void GuiShaderEditor::renderConnections(Point2I offset, const RectI& updateRect)
       start += Point2I(mNodeSize / 2, mNodeSize / 2);
       start += Point2I(mNodeSize / 2, mNodeSize / 2);
       end += Point2I(mNodeSize / 2, mNodeSize / 2);
       end += Point2I(mNodeSize / 2, mNodeSize / 2);
 
 
-      drawThickLine(start, end);
+      drawThickLine(start, end, mNodeSize/3);
    }
    }
 
 
    // Restore the clip rect to what it was at the start
    // Restore the clip rect to what it was at the start
@@ -328,7 +328,7 @@ void GuiShaderEditor::onRender(Point2I offset, const RectI& updateRect)
 
 
             RectI sockActive(start, Point2I(mNodeSize, mNodeSize));
             RectI sockActive(start, Point2I(mNodeSize, mNodeSize));
             start += Point2I(mNodeSize / 2, mNodeSize / 2);
             start += Point2I(mNodeSize / 2, mNodeSize / 2);
-            drawThickLine(start, mLastMousePos + offset);
+            drawThickLine(start, mLastMousePos + offset, mNodeSize/3);
 
 
             // draw socket overlay over the top of the line.
             // draw socket overlay over the top of the line.
             sockActive.inset(1, 1);
             sockActive.inset(1, 1);

+ 1 - 1
Engine/source/gui/shaderEditor/guiShaderEditor.h

@@ -117,7 +117,7 @@ public:
    virtual void onRemove() override;
    virtual void onRemove() override;
 
 
    virtual void onPreRender() override;
    virtual void onPreRender() override;
-   void drawThickLine(const Point2I& pt1, const Point2I& pt2, U32 thickness, ColorI col1, ColorI col2);
+   void drawThickLine(const Point2I& pt1, const Point2I& pt2, U32 thickness = 2, ColorI col1 = ColorI(255, 255, 255), ColorI col2 = ColorI(255, 255, 255));
    virtual void onRender(Point2I offset, const RectI& updateRect) override;
    virtual void onRender(Point2I offset, const RectI& updateRect) override;
 
 
    // interaction
    // interaction

+ 100 - 72
Engine/source/materials/shaderData.cpp

@@ -48,10 +48,12 @@ ConsoleDocClass( ShaderData,
 	"// Used for the procedural clould system\n"
 	"// Used for the procedural clould system\n"
 	"singleton ShaderData( CloudLayerShader )\n"
 	"singleton ShaderData( CloudLayerShader )\n"
 	"{\n"
 	"{\n"
-   "	DXVertexShaderFile   = $Core::CommonShaderPath @ \"/cloudLayerV.hlsl\";\n"
-   "	DXPixelShaderFile    = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n"
-   "	OGLVertexShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerV.glsl\";\n"
-   "	OGLPixelShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerP.glsl\";\n"
+   "	DXVertexShaderFile      = $Core::CommonShaderPath @ \"/cloudLayerV.hlsl\";\n"
+   "	DXPixelShaderFile       = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n"
+   "	DXGeometryShaderFile    = $Core::CommonShaderPath @ \"/cloudLayerG.hlsl\";\n"
+   "	OGLVertexShaderFile     = $Core::CommonShaderPath @ \"/gl/cloudLayerV.glsl\";\n"
+   "	OGLPixelShaderFile      = $Core::CommonShaderPath @ \"/gl/cloudLayerP.glsl\";\n"
+   "	OGLGeometryShaderFile   = $Core::CommonShaderPath @ \"/gl/cloudLayerG.glsl\";\n"
 	"	pixVersion = 2.0;\n"
 	"	pixVersion = 2.0;\n"
 	"};\n"
 	"};\n"
 	"@endtsexample\n\n"
 	"@endtsexample\n\n"
@@ -67,70 +69,87 @@ ShaderData::ShaderData()
 
 
    for( int i = 0; i < NumTextures; ++i)
    for( int i = 0; i < NumTextures; ++i)
       mRTParams[i] = false;
       mRTParams[i] = false;
+
+   mDXVertexShaderName = StringTable->EmptyString();
+   mDXPixelShaderName = StringTable->EmptyString();
+   mDXGeometryShaderName = StringTable->EmptyString();
+
+   mOGLVertexShaderName = StringTable->EmptyString();
+   mOGLPixelShaderName = StringTable->EmptyString();
+   mOGLGeometryShaderName = StringTable->EmptyString();
 }
 }
 
 
 void ShaderData::initPersistFields()
 void ShaderData::initPersistFields()
 {
 {
    docsURL;
    docsURL;
-   addField("DXVertexShaderFile",   TypeStringFilename,  Offset(mDXVertexShaderName,   ShaderData),
-	   "@brief %Path to the DirectX vertex shader file to use for this ShaderData.\n\n"
-	   "It must contain only one program and no pixel shader, just the vertex shader."
-	   "It can be either an HLSL or assembly level shader. HLSL's must have a "
-	   "filename extension of .hlsl, otherwise its assumed to be an assembly file.");
-
-   addField("DXPixelShaderFile",    TypeStringFilename,  Offset(mDXPixelShaderName,  ShaderData),
-	   "@brief %Path to the DirectX pixel shader file to use for this ShaderData.\n\n"
-	   "It must contain only one program and no vertex shader, just the pixel "
-	   "shader. It can be either an HLSL or assembly level shader. HLSL's "
-	   "must have a filename extension of .hlsl, otherwise its assumed to be an assembly file.");
-
-   addField("OGLVertexShaderFile",  TypeStringFilename,  Offset(mOGLVertexShaderName,   ShaderData),
-	   "@brief %Path to an OpenGL vertex shader file to use for this ShaderData.\n\n"
-	   "It must contain only one program and no pixel shader, just the vertex shader.");
-
-   addField("OGLPixelShaderFile",   TypeStringFilename,  Offset(mOGLPixelShaderName,  ShaderData),
-	   "@brief %Path to an OpenGL pixel shader file to use for this ShaderData.\n\n"
-	   "It must contain only one program and no vertex shader, just the pixel "
-	   "shader.");
-
-   addField("useDevicePixVersion",  TypeBool,            Offset(mUseDevicePixVersion,   ShaderData),
-	   "@brief If true, the maximum pixel shader version offered by the graphics card will be used.\n\n"
-	   "Otherwise, the script-defined pixel shader version will be used.\n\n");
-
-   addField("pixVersion",           TypeF32,             Offset(mPixVersion,   ShaderData),
-	   "@brief Indicates target level the shader should be compiled.\n\n"
-	   "Valid numbers at the time of this writing are 1.1, 1.4, 2.0, and 3.0. "
-	   "The shader will not run properly if the hardware does not support the "
-	   "level of shader compiled.");
-   
-   addField("defines",              TypeRealString,      Offset(mDefines,   ShaderData), 
-	   "@brief String of case-sensitive defines passed to the shader compiler.\n\n"
+   addField("DXVertexShaderFile", TypeStringFilename, Offset(mDXVertexShaderName, ShaderData),
+      "@brief %Path to the DirectX vertex shader file to use for this ShaderData.\n\n"
+      "It must contain only one program and no pixel shader, just the vertex shader."
+      "It can be either an HLSL or assembly level shader. HLSL's must have a "
+      "filename extension of .hlsl, otherwise its assumed to be an assembly file.");
+
+   addField("DXPixelShaderFile", TypeStringFilename, Offset(mDXPixelShaderName, ShaderData),
+      "@brief %Path to the DirectX pixel shader file to use for this ShaderData.\n\n"
+      "It must contain only one program and no vertex shader, just the pixel "
+      "shader. It can be either an HLSL or assembly level shader. HLSL's "
+      "must have a filename extension of .hlsl, otherwise its assumed to be an assembly file.");
+
+   addField("DXGeometryShaderFile", TypeStringFilename, Offset(mDXGeometryShaderName, ShaderData),
+      "@brief %Path to the DirectX geometry shader file to use for this ShaderData.\n\n"
+      "It can be either an HLSL or assembly level shader. HLSL's must have a "
+      "filename extension of .hlsl, otherwise its assumed to be an assembly file.");
+
+   addField("OGLVertexShaderFile", TypeStringFilename, Offset(mOGLVertexShaderName, ShaderData),
+      "@brief %Path to an OpenGL vertex shader file to use for this ShaderData.\n\n"
+      "It must contain only one program and no pixel shader, just the vertex shader.");
+
+   addField("OGLPixelShaderFile", TypeStringFilename, Offset(mOGLPixelShaderName, ShaderData),
+      "@brief %Path to an OpenGL pixel shader file to use for this ShaderData.\n\n"
+      "It must contain only one program and no vertex shader, just the pixel "
+      "shader.");
+
+   addField("OGLGeometryShaderFile", TypeStringFilename, Offset(mOGLGeometryShaderName, ShaderData),
+      "@brief %Path to the OpenGL Geometry shader file to use for this ShaderData.\n\n");
+
+   addField("useDevicePixVersion", TypeBool, Offset(mUseDevicePixVersion, ShaderData),
+      "@brief If true, the maximum pixel shader version offered by the graphics card will be used.\n\n"
+      "Otherwise, the script-defined pixel shader version will be used.\n\n");
+
+   addField("pixVersion", TypeF32, Offset(mPixVersion, ShaderData),
+      "@brief Indicates target level the shader should be compiled.\n\n"
+      "Valid numbers at the time of this writing are 1.1, 1.4, 2.0, and 3.0. "
+      "The shader will not run properly if the hardware does not support the "
+      "level of shader compiled.");
+
+   addField("defines", TypeRealString, Offset(mDefines, ShaderData),
+      "@brief String of case-sensitive defines passed to the shader compiler.\n\n"
       "The string should be delimited by a semicolon, tab, or newline character."
       "The string should be delimited by a semicolon, tab, or newline character."
-      
+
       "@tsexample\n"
       "@tsexample\n"
-       "singleton ShaderData( FlashShader )\n"
-          "{\n"
-              "DXVertexShaderFile 	= $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n"
-              "DXPixelShaderFile 	= $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n"
-              " //Define setting the color of WHITE_COLOR.\n"
-              "defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n"
-              "pixVersion = 2.0\n"
-          "}\n"
+      "singleton ShaderData( FlashShader )\n"
+      "{\n"
+      "DXVertexShaderFile 	   = $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n"
+      "DXPixelShaderFile 	   = $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n"
+      "DXGeometryShaderFile   = $shaderGen::cachePath @ \"/postFx/flashG.hlsl\";\n\n"
+      " //Define setting the color of WHITE_COLOR.\n"
+      "defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n"
+      "pixVersion = 2.0\n"
+      "}\n"
       "@endtsexample\n\n"
       "@endtsexample\n\n"
-      );
+   );
 
 
-   addField("samplerNames",              TypeRealString,      Offset(mSamplerNames,   ShaderData), NumTextures, 
+   addField("samplerNames", TypeRealString, Offset(mSamplerNames, ShaderData), NumTextures,
       "@brief Indicates names of samplers present in shader. Order is important.\n\n"
       "@brief Indicates names of samplers present in shader. Order is important.\n\n"
-	   "Order of sampler names are used to assert correct sampler register/location"
+      "Order of sampler names are used to assert correct sampler register/location"
       "Other objects (GFXStateBlockData, PostEffect...) use index number to link samplers."
       "Other objects (GFXStateBlockData, PostEffect...) use index number to link samplers."
-      );
+   );
 
 
-   addField("rtParams",              TypeBool,      Offset(mRTParams,   ShaderData), NumTextures, "");
+   addField("rtParams", TypeBool, Offset(mRTParams, ShaderData), NumTextures, "");
 
 
    Parent::initPersistFields();
    Parent::initPersistFields();
 
 
    // Make sure we get activation signals.
    // Make sure we get activation signals.
-   LightManager::smActivateSignal.notify( &ShaderData::_onLMActivate );
+   LightManager::smActivateSignal.notify(&ShaderData::_onLMActivate);
 }
 }
 
 
 bool ShaderData::onAdd()
 bool ShaderData::onAdd()
@@ -147,8 +166,8 @@ bool ShaderData::onAdd()
 
 
    for(int i = 0; i < NumTextures; ++i)
    for(int i = 0; i < NumTextures; ++i)
    {
    {
-      if( mSamplerNames[i].isNotEmpty() && !mSamplerNames[i].startsWith("$") )      
-         mSamplerNames[i].insert(0, "$");      
+      if( mSamplerNames[i].isNotEmpty() && !mSamplerNames[i].startsWith("$") )
+         mSamplerNames[i].insert(0, "$");
    }
    }
 
 
    return true;
    return true;
@@ -164,12 +183,12 @@ void ShaderData::onRemove()
 
 
 const Vector<GFXShaderMacro>& ShaderData::_getMacros()
 const Vector<GFXShaderMacro>& ShaderData::_getMacros()
 {
 {
-   // If they have already been processed then 
+   // If they have already been processed then
    // return the cached result.
    // return the cached result.
    if ( mShaderMacros.size() != 0 || mDefines.isEmpty() )
    if ( mShaderMacros.size() != 0 || mDefines.isEmpty() )
       return mShaderMacros;
       return mShaderMacros;
 
 
-   mShaderMacros.clear();  
+   mShaderMacros.clear();
    GFXShaderMacro macro;
    GFXShaderMacro macro;
    const U32 defineCount = StringUnit::getUnitCount( mDefines, ";\n\t" );
    const U32 defineCount = StringUnit::getUnitCount( mDefines, ";\n\t" );
    for ( U32 i=0; i < defineCount; i++ )
    for ( U32 i=0; i < defineCount; i++ )
@@ -195,7 +214,7 @@ GFXShader* ShaderData::getShader( const Vector<GFXShaderMacro> &macros )
 
 
    // Convert the final macro list to a string.
    // Convert the final macro list to a string.
    String cacheKey;
    String cacheKey;
-   GFXShaderMacro::stringize( macros, &cacheKey );   
+   GFXShaderMacro::stringize( macros, &cacheKey );
 
 
    // Lookup the shader for this instance.
    // Lookup the shader for this instance.
    ShaderCache::Iterator iter = mShaders.find( cacheKey );
    ShaderCache::Iterator iter = mShaders.find( cacheKey );
@@ -237,9 +256,13 @@ GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
    {
    {
       case Direct3D11:
       case Direct3D11:
       {
       {
-         success = shader->init( mDXVertexShaderName, 
-                                 mDXPixelShaderName, 
-                                 pixver,
+         if (mDXVertexShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::VERTEX_SHADER, mDXVertexShaderName);
+         if (mDXPixelShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::PIXEL_SHADER, mDXPixelShaderName);
+         if (mDXGeometryShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::GEOMETRY_SHADER, mDXGeometryShaderName);
+         success = shader->init( pixver,
                                  macros,
                                  macros,
                                  samplers);
                                  samplers);
          break;
          break;
@@ -247,14 +270,19 @@ GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
 
 
       case OpenGL:
       case OpenGL:
       {
       {
-         success = shader->init( mOGLVertexShaderName,
-                                 mOGLPixelShaderName,
-                                 pixver,
+         if(mOGLVertexShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::VERTEX_SHADER, mOGLVertexShaderName);
+         if (mOGLPixelShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::PIXEL_SHADER, mOGLPixelShaderName);
+         if (mOGLGeometryShaderName != String::EmptyString)
+            shader->setShaderStageFile(GFXShaderStage::GEOMETRY_SHADER, mOGLGeometryShaderName);
+
+         success = shader->init( pixver,
                                  macros,
                                  macros,
                                  samplers);
                                  samplers);
          break;
          break;
       }
       }
-         
+
       default:
       default:
          // Other device types are assumed to not support shaders.
          // Other device types are assumed to not support shaders.
          success = false;
          success = false;
@@ -268,7 +296,7 @@ GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
    {
    {
       if(descs[i].constType != GFXSCT_Sampler && descs[i].constType != GFXSCT_SamplerCube)
       if(descs[i].constType != GFXSCT_Sampler && descs[i].constType != GFXSCT_SamplerCube)
          continue;
          continue;
-      
+
       GFXShaderConstHandle *handle = shader->findShaderConstHandle(descs[i].name);
       GFXShaderConstHandle *handle = shader->findShaderConstHandle(descs[i].name);
       if(!handle || !handle->isValid())
       if(!handle || !handle->isValid())
          continue;
          continue;
@@ -321,7 +349,7 @@ void ShaderData::_onLMActivate( const char *lm, bool activate )
 
 
 bool ShaderData::hasSamplerDef(const String &_samplerName, int &pos) const
 bool ShaderData::hasSamplerDef(const String &_samplerName, int &pos) const
 {
 {
-   String samplerName = _samplerName.startsWith("$") ? _samplerName : "$"+_samplerName;   
+   String samplerName = _samplerName.startsWith("$") ? _samplerName : "$"+_samplerName;
    for(int i = 0; i < NumTextures; ++i)
    for(int i = 0; i < NumTextures; ++i)
    {
    {
       if( mSamplerNames[i].equal(samplerName, String::NoCase ) )
       if( mSamplerNames[i].equal(samplerName, String::NoCase ) )
@@ -342,9 +370,9 @@ bool ShaderData::_checkDefinition(GFXShader *shader)
    samplers.reserve(NumTextures);
    samplers.reserve(NumTextures);
    bool rtParams[NumTextures];
    bool rtParams[NumTextures];
    for(int i = 0; i < NumTextures; ++i)
    for(int i = 0; i < NumTextures; ++i)
-      rtParams[i] = false;   
+      rtParams[i] = false;
 
 
-   const Vector<GFXShaderConstDesc> &shaderConstDesc = shader->getShaderConstDesc(); 
+   const Vector<GFXShaderConstDesc> &shaderConstDesc = shader->getShaderConstDesc();
 
 
    for(int i = 0; i < shaderConstDesc.size(); ++i)
    for(int i = 0; i < shaderConstDesc.size(); ++i)
    {
    {
@@ -352,7 +380,7 @@ bool ShaderData::_checkDefinition(GFXShader *shader)
       if(desc.constType == GFXSCT_Sampler)
       if(desc.constType == GFXSCT_Sampler)
       {
       {
          samplers.push_back(desc.name );
          samplers.push_back(desc.name );
-      }      
+      }
    }
    }
 
 
    for(int i = 0; i < samplers.size(); ++i)
    for(int i = 0; i < samplers.size(); ++i)
@@ -361,14 +389,14 @@ bool ShaderData::_checkDefinition(GFXShader *shader)
       bool find = hasSamplerDef(samplers[i], pos);
       bool find = hasSamplerDef(samplers[i], pos);
 
 
       if(find && pos >= 0 && mRTParams[pos])
       if(find && pos >= 0 && mRTParams[pos])
-      {              
+      {
          if( !shader->findShaderConstHandle( String::ToString("$rtParams%d", pos)) )
          if( !shader->findShaderConstHandle( String::ToString("$rtParams%d", pos)) )
          {
          {
             String errStr = String::ToString("ShaderData(%s) sampler[%d] used but rtParams%d not used in shader compilation. Possible error", shader->getPixelShaderFile().c_str(), pos, pos);
             String errStr = String::ToString("ShaderData(%s) sampler[%d] used but rtParams%d not used in shader compilation. Possible error", shader->getPixelShaderFile().c_str(), pos, pos);
             Con::errorf(errStr);
             Con::errorf(errStr);
             error = true;
             error = true;
          }
          }
-      }     
+      }
 
 
       if(!find)
       if(!find)
       {
       {
@@ -377,7 +405,7 @@ bool ShaderData::_checkDefinition(GFXShader *shader)
          GFXAssertFatal(0, errStr);
          GFXAssertFatal(0, errStr);
          error = true;
          error = true;
       }
       }
-   }  
+   }
 
 
    return !error;
    return !error;
 }
 }

+ 15 - 15
Engine/source/materials/shaderData.h

@@ -47,7 +47,7 @@ protected:
    ///
    ///
    static Vector<ShaderData*> smAllShaderData;
    static Vector<ShaderData*> smAllShaderData;
 
 
-   typedef HashTable<String,GFXShaderRef> ShaderCache;
+   typedef HashTable<String, GFXShaderRef> ShaderCache;
 
 
    ShaderCache mShaders;
    ShaderCache mShaders;
 
 
@@ -56,12 +56,12 @@ protected:
    F32 mPixVersion;
    F32 mPixVersion;
 
 
    StringTableEntry mDXVertexShaderName;
    StringTableEntry mDXVertexShaderName;
-
    StringTableEntry mDXPixelShaderName;
    StringTableEntry mDXPixelShaderName;
+   StringTableEntry mDXGeometryShaderName;
 
 
    StringTableEntry mOGLVertexShaderName;
    StringTableEntry mOGLVertexShaderName;
-
    StringTableEntry mOGLPixelShaderName;
    StringTableEntry mOGLPixelShaderName;
+   StringTableEntry mOGLGeometryShaderName;
 
 
    /// A semicolon, tab, or newline delimited string of case
    /// A semicolon, tab, or newline delimited string of case
    /// sensitive defines that are passed to the shader compiler.
    /// sensitive defines that are passed to the shader compiler.
@@ -80,40 +80,40 @@ protected:
    /// them if the content has changed.
    /// them if the content has changed.
    const Vector<GFXShaderMacro>& _getMacros();
    const Vector<GFXShaderMacro>& _getMacros();
 
 
-   /// Helper for converting an array of macros 
+   /// Helper for converting an array of macros
    /// into a formatted string.
    /// into a formatted string.
-   void _stringizeMacros(  const Vector<GFXShaderMacro> &macros, 
-                           String *outString );
+   void _stringizeMacros(const Vector<GFXShaderMacro>& macros,
+      String* outString);
 
 
    /// Creates a new shader returning NULL on error.
    /// Creates a new shader returning NULL on error.
-   GFXShader* _createShader( const Vector<GFXShaderMacro> &macros );
+   GFXShader* _createShader(const Vector<GFXShaderMacro>& macros);
 
 
    /// @see LightManager::smActivateSignal
    /// @see LightManager::smActivateSignal
-   static void _onLMActivate( const char *lm, bool activate );
+   static void _onLMActivate(const char* lm, bool activate);
 
 
    enum
    enum
    {
    {
       NumTextures = 16
       NumTextures = 16
    };
    };
 
 
-   String mSamplerNames[NumTextures]; 
+   String mSamplerNames[NumTextures];
    bool mRTParams[NumTextures];
    bool mRTParams[NumTextures];
 
 
-   bool _checkDefinition(GFXShader *shader);   
+   bool _checkDefinition(GFXShader* shader);
 
 
 public:
 public:
 
 
-   void setSamplerName(const String &name, int idx) { mSamplerNames[idx] = name; }
+   void setSamplerName(const String& name, int idx) { mSamplerNames[idx] = name; }
    String getSamplerName(int idx) const { return mSamplerNames[idx]; }
    String getSamplerName(int idx) const { return mSamplerNames[idx]; }
 
 
-   bool hasSamplerDef(const String &samplerName, int &pos) const;
+   bool hasSamplerDef(const String& samplerName, int& pos) const;
    bool hasRTParamsDef(const int pos) const { return mRTParams[pos]; }
    bool hasRTParamsDef(const int pos) const { return mRTParams[pos]; }
 
 
    ShaderData();
    ShaderData();
 
 
-   /// Returns an initialized shader instance or NULL 
+   /// Returns an initialized shader instance or NULL
    /// if the shader failed to be created.
    /// if the shader failed to be created.
-   GFXShader* getShader( const Vector<GFXShaderMacro> &macros = Vector<GFXShaderMacro>() );
+   GFXShader* getShader(const Vector<GFXShaderMacro>& macros = Vector<GFXShaderMacro>());
 
 
    /// Forces a reinitialization of all the instanced shaders.
    /// Forces a reinitialization of all the instanced shaders.
    void reloadShaders();
    void reloadShaders();
@@ -124,7 +124,7 @@ public:
 
 
    /// Returns the required pixel shader version for this shader.
    /// Returns the required pixel shader version for this shader.
    F32 getPixVersion() const { return mPixVersion; }
    F32 getPixVersion() const { return mPixVersion; }
-   
+
    // SimObject
    // SimObject
    virtual bool onAdd();
    virtual bool onAdd();
    virtual void onRemove();
    virtual void onRemove();

+ 22 - 19
Engine/source/shaderGen/shaderGen.cpp

@@ -47,7 +47,7 @@ MODULE_BEGIN( ShaderGen )
    {
    {
       ManagedSingleton< ShaderGen >::createSingleton();
       ManagedSingleton< ShaderGen >::createSingleton();
    }
    }
-   
+
    MODULE_SHUTDOWN
    MODULE_SHUTDOWN
    {
    {
       ManagedSingleton< ShaderGen >::deleteSingleton();
       ManagedSingleton< ShaderGen >::deleteSingleton();
@@ -94,7 +94,7 @@ bool ShaderGen::_handleGFXEvent(GFXDevice::GFXDeviceEventType event)
 }
 }
 
 
 void ShaderGen::initShaderGen()
 void ShaderGen::initShaderGen()
-{   
+{
    if (mInit)
    if (mInit)
       return;
       return;
 
 
@@ -125,7 +125,7 @@ void ShaderGen::initShaderGen()
    {
    {
       // If we didn't get a path then we're gonna cache the shaders to
       // If we didn't get a path then we're gonna cache the shaders to
       // a virtualized memory file system.
       // a virtualized memory file system.
-      mMemFS = new Torque::Mem::MemFileSystem( "shadergen:/" ); 
+      mMemFS = new Torque::Mem::MemFileSystem( "shadergen:/" );
       Torque::FS::Mount( "shadergen", mMemFS );
       Torque::FS::Mount( "shadergen", mMemFS );
    }
    }
    else
    else
@@ -136,8 +136,8 @@ void ShaderGen::initShaderGen()
 }
 }
 
 
 void ShaderGen::generateShader( const MaterialFeatureData &featureData,
 void ShaderGen::generateShader( const MaterialFeatureData &featureData,
-                                char *vertFile, 
-                                char *pixFile, 
+                                char *vertFile,
+                                char *pixFile,
                                 F32 *pixVersion,
                                 F32 *pixVersion,
                                 const GFXVertexFormat *vertexFormat,
                                 const GFXVertexFormat *vertexFormat,
                                 const char* cacheName,
                                 const char* cacheName,
@@ -155,23 +155,23 @@ void ShaderGen::generateShader( const MaterialFeatureData &featureData,
    char pixShaderName[256];
    char pixShaderName[256];
 
 
    // Note:  We use a postfix of _V/_P here so that it sorts the matching
    // Note:  We use a postfix of _V/_P here so that it sorts the matching
-   // vert and pixel shaders together when listed alphabetically.   
+   // vert and pixel shaders together when listed alphabetically.
    dSprintf( vertShaderName, sizeof(vertShaderName), "shadergen:/%s_V.%s", cacheName, mFileEnding.c_str() );
    dSprintf( vertShaderName, sizeof(vertShaderName), "shadergen:/%s_V.%s", cacheName, mFileEnding.c_str() );
    dSprintf( pixShaderName, sizeof(pixShaderName), "shadergen:/%s_P.%s", cacheName, mFileEnding.c_str() );
    dSprintf( pixShaderName, sizeof(pixShaderName), "shadergen:/%s_P.%s", cacheName, mFileEnding.c_str() );
-   
+
    dStrcpy( vertFile, vertShaderName, 256 );
    dStrcpy( vertFile, vertShaderName, 256 );
    dStrcpy( pixFile, pixShaderName, 256 );
    dStrcpy( pixFile, pixShaderName, 256 );
-   
+
    // this needs to change - need to optimize down to ps v.1.1
    // this needs to change - need to optimize down to ps v.1.1
    *pixVersion = GFX->getPixelShaderVersion();
    *pixVersion = GFX->getPixelShaderVersion();
-   
+
    if ( !Con::getBoolVariable( "ShaderGen::GenNewShaders", true ) )
    if ( !Con::getBoolVariable( "ShaderGen::GenNewShaders", true ) )
    {
    {
       // If we are not regenerating the shader we will return here.
       // If we are not regenerating the shader we will return here.
       // But we must fill in the shader macros first!
       // But we must fill in the shader macros first!
 
 
       _processVertFeatures( macros, true );
       _processVertFeatures( macros, true );
-      _processPixFeatures( macros, true );      
+      _processPixFeatures( macros, true );
 
 
       return;
       return;
    }
    }
@@ -190,7 +190,7 @@ void ShaderGen::generateShader( const MaterialFeatureData &featureData,
    _processVertFeatures(macros);
    _processVertFeatures(macros);
    _printVertShader( *s );
    _printVertShader( *s );
    delete s;
    delete s;
-   
+
    ((ShaderConnector*)mComponents[C_CONNECTOR])->reset();
    ((ShaderConnector*)mComponents[C_CONNECTOR])->reset();
    LangElement::deleteElements();
    LangElement::deleteElements();
 
 
@@ -202,7 +202,7 @@ void ShaderGen::generateShader( const MaterialFeatureData &featureData,
       AssertFatal(false, "Failed to open Shader Stream" );
       AssertFatal(false, "Failed to open Shader Stream" );
       delete s;
       delete s;
       return;
       return;
-   }   
+   }
 
 
    mOutput = new MultiLine;
    mOutput = new MultiLine;
    _processPixFeatures(macros);
    _processPixFeatures(macros);
@@ -284,7 +284,7 @@ void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> &macros, bool macro
             mOutput->addStatement( feature->getOutput() );
             mOutput->addStatement( feature->getOutput() );
 
 
          feature->reset();
          feature->reset();
-         mOutput->addStatement( new GenOp( "   \r\n" ) );         
+         mOutput->addStatement( new GenOp( "   \r\n" ) );
       }
       }
    }
    }
 
 
@@ -327,7 +327,7 @@ void ShaderGen::_processPixFeatures( Vector<GFXShaderMacro> &macros, bool macros
          mOutput->addStatement( new GenOp( "   \r\n" ) );
          mOutput->addStatement( new GenOp( "   \r\n" ) );
       }
       }
    }
    }
-   
+
    ShaderConnector *connect = dynamic_cast<ShaderConnector *>( mComponents[C_CONNECTOR] );
    ShaderConnector *connect = dynamic_cast<ShaderConnector *>( mComponents[C_CONNECTOR] );
    connect->sortVars();
    connect->sortVars();
 }
 }
@@ -335,7 +335,7 @@ void ShaderGen::_processPixFeatures( Vector<GFXShaderMacro> &macros, bool macros
 void ShaderGen::_printFeatureList(Stream &stream)
 void ShaderGen::_printFeatureList(Stream &stream)
 {
 {
    mPrinter->printLine(stream, "// Features:");
    mPrinter->printLine(stream, "// Features:");
-      
+
    const FeatureSet &features = mFeatureData.features;
    const FeatureSet &features = mFeatureData.features;
 
 
    for( U32 i=0; i < features.getCount(); i++ )
    for( U32 i=0; i < features.getCount(); i++ )
@@ -376,7 +376,7 @@ void ShaderGen::_printDependencies(Stream &stream)
 
 
       for( U32 j=0; j < dependencies.size(); j++ )
       for( U32 j=0; j < dependencies.size(); j++ )
       {
       {
-         if (  j != i && 
+         if (  j != i &&
                *dependencies[i] == *dependencies[j] )
                *dependencies[i] == *dependencies[j] )
          {
          {
             dup = true;
             dup = true;
@@ -386,7 +386,7 @@ void ShaderGen::_printDependencies(Stream &stream)
 
 
       if ( dup )
       if ( dup )
          dependencies.erase( i );
          dependencies.erase( i );
-      else        
+      else
          i++;
          i++;
    }
    }
 
 
@@ -493,7 +493,10 @@ GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const G
    generateShader( featureData, vertFile, pixFile, &pixVersion, vertexFormat, cacheKey, shaderMacros );
    generateShader( featureData, vertFile, pixFile, &pixVersion, vertexFormat, cacheKey, shaderMacros );
 
 
    GFXShader *shader = GFX->createShader();
    GFXShader *shader = GFX->createShader();
-   if (!shader->init(vertFile, pixFile, pixVersion, shaderMacros, samplers, &mInstancingFormat))
+   shader->setShaderStageFile(GFXShaderStage::VERTEX_SHADER, vertFile);
+   shader->setShaderStageFile(GFXShaderStage::PIXEL_SHADER, pixFile);
+
+   if (!shader->init(pixVersion, shaderMacros, samplers, &mInstancingFormat))
    {
    {
       delete shader;
       delete shader;
       return NULL;
       return NULL;
@@ -508,5 +511,5 @@ void ShaderGen::flushProceduralShaders()
 {
 {
    // The shaders are reference counted, so we
    // The shaders are reference counted, so we
    // just need to clear the map.
    // just need to clear the map.
-   mProcShaders.clear();  
+   mProcShaders.clear();
 }
 }