gfxShader.h

Engine/source/gfx/gfxShader.h

More...

Classes:

class

GFXShaderConstBuffer is a collection of shader data which are sent to the device in one call in most cases.

class

Instances of this struct are returned GFXShaderConstBuffer.

class

This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.

Public Typedefs

GFXShaderConstBufferRef 
GFXShaderRef 

A strong pointer to a reference counted GFXShader.

GFXShaderWeakRef 

A weak pointer to a reference counted GFXShader.

Detailed Description

Public Typedefs

typedef StrongRefPtr< GFXShaderConstBuffer > GFXShaderConstBufferRef 
typedef StrongRefPtr< GFXShader > GFXShaderRef 

A strong pointer to a reference counted GFXShader.

typedef WeakRefPtr< GFXShader > GFXShaderWeakRef 

A weak pointer to a reference counted GFXShader.

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _GFXSHADER_H_
 25#define _GFXSHADER_H_
 26
 27#ifndef _GFXRESOURCE_H_
 28#include "gfx/gfxResource.h"
 29#endif
 30#ifndef _TORQUE_STRING_H_
 31#include "core/util/str.h"
 32#endif
 33#ifndef _TVECTOR_H_
 34#include "core/util/tVector.h"
 35#endif
 36#ifndef _ALIGNEDARRAY_H_
 37#include "core/util/tAlignedArray.h"
 38#endif
 39#ifndef _MMATRIX_H_
 40#include "math/mMatrix.h"
 41#endif
 42#ifndef _GFXENUMS_H_
 43#include "gfx/gfxEnums.h"
 44#endif
 45#ifndef _GFXSTRUCTS_H_
 46#include "gfx/gfxStructs.h"
 47#endif
 48#ifndef _COLOR_H_
 49#include "core/color.h"
 50#endif
 51#ifndef _REFBASE_H_
 52#include "core/util/refBase.h"
 53#endif
 54#ifndef _PATH_H_
 55#include "core/util/path.h"
 56#endif
 57#ifndef _TSIGNAL_H_
 58#include "core/util/tSignal.h"
 59#endif
 60
 61class Point2I;
 62class Point2F;
 63class LinearColorF;
 64class MatrixF;
 65class GFXShader;
 66class GFXVertexFormat;
 67
 68
 69/// Instances of this struct are returned GFXShaderConstBuffer
 70struct GFXShaderConstDesc 
 71{
 72public:
 73   String name;
 74   GFXShaderConstType constType;   
 75   U32 arraySize; // > 1 means it is an array!
 76};
 77
 78/// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
 79/// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
 80/// (or shader).  Client code should not free these.
 81class GFXShaderConstHandle 
 82{
 83public:
 84
 85   GFXShaderConstHandle() { mValid = false; }
 86   virtual ~GFXShaderConstHandle() {}
 87
 88   /// Returns true if this constant is valid and can
 89   /// be set on the shader.
 90   bool isValid() const { return mValid; }   
 91   
 92   /// Returns the name of the constant handle.
 93   virtual const String& getName() const = 0;
 94
 95   /// Returns the type of the constant handle.
 96   virtual GFXShaderConstType getType() const = 0;
 97
 98   virtual U32 getArraySize() const = 0;
 99   
100   /// Returns -1 if this handle does not point to a Sampler.
101   virtual S32 getSamplerRegister() const = 0;
102
103protected:
104
105   /// The state of the constant which is
106   /// set from the derived class.
107   bool mValid;
108   
109};
110
111
112/// GFXShaderConstBuffer is a collection of shader data which
113/// are sent to the device in one call in most cases.
114///
115/// The content of the buffer is persistant and if a value
116/// does not change frequently there is a savings in not setting
117/// the value every frame.
118///
119class GFXShaderConstBuffer : public GFXResource, public StrongRefBase
120{
121protected:
122
123   /// The lost state of the buffer content.
124   ///
125   /// Derived classes need to set the lost state
126   /// on first creation of the buffer and shader
127   /// reloads.
128   ///
129   /// @see wasLost
130   bool mWasLost;
131
132   GFXShaderConstBuffer()   
133      :  mWasLost( true ),
134         mInstPtr( NULL )
135   {
136   }
137
138public:
139
140   /// Return the shader that created this buffer
141   virtual GFXShader* getShader() = 0;
142
143   /// The content of the buffer is in the lost state when
144   /// first created or when the shader is reloaded.  When 
145   /// the content is lost you must refill the buffer
146   /// with all the constants used by your shader.
147   ///
148   /// Use this property to avoid setting constants which do 
149   /// not changefrom one frame to the next.
150   ///
151   bool wasLost() const { return mWasLost; }
152
153   /// An inline helper which ensures the handle is valid 
154   /// before the virtual set method is called.
155   ///
156   /// You should prefer using this method unless your sure the
157   /// handle is always valid or if your doing your own test.
158   ///
159   template< typename VALUE >
160   inline void setSafe( GFXShaderConstHandle *handle, const VALUE& v )
161   {
162      if ( handle->isValid() )
163         set( handle, v );
164   }
165
166   /// Set a shader constant.
167   ///
168   /// The constant handle is assumed to be valid.
169   ///
170   /// Perfer using setSafe unless you can check the handle
171   /// validity yourself and skip a significat amount of work.
172   ///   
173   /// @see GFXShaderConstHandle::isValid()
174   ///
175   virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
176   virtual void set(GFXShaderConstHandle* handle, const Point2F& fv) = 0;
177   virtual void set(GFXShaderConstHandle* handle, const Point3F& fv) = 0;
178   virtual void set(GFXShaderConstHandle* handle, const Point4F& fv) = 0;
179   virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv) = 0;
180   virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv) = 0;
181   virtual void set(GFXShaderConstHandle* handle, const S32 f) = 0;
182   virtual void set(GFXShaderConstHandle* handle, const Point2I& fv) = 0;
183   virtual void set(GFXShaderConstHandle* handle, const Point3I& fv) = 0;
184   virtual void set(GFXShaderConstHandle* handle, const Point4I& fv) = 0;
185   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv) = 0;
186   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv) = 0;
187   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv) = 0;
188   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv) = 0;
189   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv) = 0;
190   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
191   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
192   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
193   
194   /// Set a variable sized matrix shader constant.   
195   virtual void set( GFXShaderConstHandle* handle, 
196                     const MatrixF& mat, 
197                     const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
198   
199   /// Set a variable sized matrix shader constant from
200   /// an array of matricies.   
201   virtual void set( GFXShaderConstHandle* handle, 
202                     const MatrixF* mat, 
203                     const U32 arraySize, 
204                     const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
205   
206   // TODO: Make this protected and put a real API around it.
207   U8 *mInstPtr;
208};
209
210typedef StrongRefPtr<GFXShaderConstBuffer> GFXShaderConstBufferRef;
211
212
213//**************************************************************************
214// Shader
215//**************************************************************************
216class GFXShader : public StrongRefBase, public GFXResource
217{
218   friend class GFXShaderConstBuffer;
219
220protected:
221  
222   /// These are system wide shader macros which are 
223   /// merged with shader specific macros at creation.
224   static Vector<GFXShaderMacro> smGlobalMacros;
225
226   /// If true the shader errors are spewed to the console.
227   static bool smLogErrors;
228
229   /// If true the shader warnings are spewed to the console.
230   static bool smLogWarnings;
231
232   /// The vertex shader file.
233   Torque::Path mVertexFile;  
234
235   /// The pixel shader file.
236   Torque::Path mPixelFile;  
237
238   /// The macros to be passed to the shader.      
239   Vector<GFXShaderMacro> mMacros;
240
241   /// Ordered SamplerNames
242   /// We need to store a list of sampler for allow OpenGL to
243   /// assign correct location for each sampler.
244   /// GLSL 150 not allow explicit uniform location.
245   /// Only used on OpenGL   
246   Vector<String> mSamplerNamesOrdered;
247
248   /// The pixel version this is compiled for.
249   F32 mPixVersion;
250
251   ///
252   String mDescription;
253
254   /// Counter that is incremented each time this shader is reloaded.
255   U32 mReloadKey;
256
257   Signal<void()> mReloadSignal;
258
259   /// Vector of buffers that reference this shader.
260   /// It is the responsibility of the derived shader class to populate this 
261   /// vector and to notify them when this shader is reloaded.  Classes
262   /// derived from GFXShaderConstBuffer should call _unlinkBuffer from
263   /// their destructor.
264   Vector<GFXShaderConstBuffer*> mActiveBuffers;
265
266   GFXVertexFormat *mInstancingFormat;
267
268   /// A protected constructor so it cannot be instantiated.
269   GFXShader();
270
271public:  
272
273   /// Adds a global shader macro which will be merged with
274   /// the script defined macros on every shader reload.
275   ///
276   /// The macro will replace the value of an existing macro
277   /// of the same name.
278   ///
279   /// For the new macro to take effect all the shaders/materials
280   /// in the system need to be reloaded.
281   ///
282   /// @see MaterialManager::flushAndReInitInstances
283   /// @see ShaderData::reloadAll
284   static void addGlobalMacro( const String &name, const String &value = String::EmptyString );
285
286   /// Removes an existing global macro by name.
287   /// @see addGlobalMacro
288   static bool removeGlobalMacro( const String &name );
289
290   /// Toggle logging for shader errors.
291   static void setLogging( bool logErrors,
292                           bool logWarning ) 
293   {
294      smLogErrors = logErrors; 
295      smLogWarnings = logWarning;
296   }
297
298   /// The destructor.
299   virtual ~GFXShader();
300
301   ///
302   /// Deprecated. Remove on T3D 4.0
303#ifndef TORQUE_OPENGL
304   bool init(  const Torque::Path &vertFile, 
305               const Torque::Path &pixFile, 
306               F32 pixVersion, 
307               const Vector<GFXShaderMacro> &macros );
308#endif
309
310   ///
311   bool init(  const Torque::Path &vertFile, 
312               const Torque::Path &pixFile, 
313               F32 pixVersion, 
314               const Vector<GFXShaderMacro> &macros,
315               const Vector<String> &samplerNames,
316               GFXVertexFormat *instanceFormat = NULL );
317
318   /// Reloads the shader from disk.
319   bool reload();
320
321   Signal<void()> getReloadSignal() { return mReloadSignal; }
322
323   /// Allocate a constant buffer
324   virtual GFXShaderConstBufferRef allocConstBuffer() = 0;  
325
326   /// Returns our list of shader constants, the material can get this and just set the constants it knows about
327   virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
328
329   /// Returns a shader constant handle for the name constant.
330   ///
331   /// Since shaders can reload and later have handles that didn't 
332   /// exist originally this will return a handle in an invalid state
333   /// if the constant doesn't exist at this time.
334   virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0; 
335
336   /// Returns a shader constant handle for the name constant, if the variable doesn't exist NULL is returned.
337   virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
338
339   /// Returns the alignment value for constType
340   virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;   
341
342   /// Returns the required vertex format for this shader.
343   /// Returns the pixel shader version.
344   F32 getPixVersion() const { return mPixVersion; }
345
346   /// Returns a counter which is incremented each time this shader is reloaded.
347   U32 getReloadKey() const { return mReloadKey; }
348
349   /// Device specific shaders can override this method to return
350   /// the shader disassembly.
351   virtual bool getDisassembly( String &outStr ) const { return false; }
352
353   /// Returns the vertex shader file path.
354   const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
355
356   /// Returns the pixel shader file path.
357   const String& getPixelShaderFile() const { return mPixelFile.getFullPath(); }
358
359   // GFXResource
360   const String describeSelf() const { return mDescription; }
361
362   // Get instancing vertex format
363   GFXVertexFormat *getInstancingFormat() { return mInstancingFormat; }
364
365protected:
366
367   /// Called when the shader files change on disk.
368   void _onFileChanged( const Torque::Path &path ) { reload(); }
369
370   /// Internal initialization function overloaded for
371   /// each GFX device type.
372   virtual bool _init() = 0;
373
374   /// Buffers call this from their destructor (so we don't have to ref count them).
375   void _unlinkBuffer( GFXShaderConstBuffer *buf );
376
377   /// Called to update the description string after init.
378   void _updateDesc();
379};
380
381/// A strong pointer to a reference counted GFXShader.
382typedef StrongRefPtr<GFXShader> GFXShaderRef;
383
384
385/// A weak pointer to a reference counted GFXShader.
386typedef WeakRefPtr<GFXShader> GFXShaderWeakRef;
387
388
389#endif // GFXSHADER
390