mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
apparently templated classes need all functions to be inline, otherwise unresolved symbols macro for switching between matrixf and templated few functions that were missed
412 lines
14 KiB
C++
412 lines
14 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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 _GFXSHADER_H_
|
|
#define _GFXSHADER_H_
|
|
|
|
#ifndef _GFXRESOURCE_H_
|
|
#include "gfx/gfxResource.h"
|
|
#endif
|
|
#ifndef _TORQUE_STRING_H_
|
|
#include "core/util/str.h"
|
|
#endif
|
|
#ifndef _TVECTOR_H_
|
|
#include "core/util/tVector.h"
|
|
#endif
|
|
#ifndef _ALIGNEDARRAY_H_
|
|
#include "core/util/tAlignedArray.h"
|
|
#endif
|
|
#ifndef _MMATRIX_H_
|
|
#include "math/mMatrix.h"
|
|
#endif
|
|
#ifndef _GFXENUMS_H_
|
|
#include "gfx/gfxEnums.h"
|
|
#endif
|
|
#ifndef _GFXSTRUCTS_H_
|
|
#include "gfx/gfxStructs.h"
|
|
#endif
|
|
#ifndef _COLOR_H_
|
|
#include "core/color.h"
|
|
#endif
|
|
#ifndef _REFBASE_H_
|
|
#include "core/util/refBase.h"
|
|
#endif
|
|
#ifndef _PATH_H_
|
|
#include "core/util/path.h"
|
|
#endif
|
|
#ifndef _TSIGNAL_H_
|
|
#include "core/util/tSignal.h"
|
|
#endif
|
|
|
|
class Point2I;
|
|
class Point2F;
|
|
class LinearColorF;
|
|
#ifndef USE_TEMPLATE_MATRIX
|
|
class MatrixF;
|
|
#else
|
|
template<typename DATA_TYPE, U32 rows, U32 cols> class Matrix;
|
|
typedef Matrix<F32, 4, 4> MatrixF;
|
|
#endif
|
|
class GFXShader;
|
|
class GFXVertexFormat;
|
|
|
|
|
|
enum GFXShaderStage
|
|
{
|
|
VERTEX_SHADER = BIT(0),
|
|
PIXEL_SHADER = BIT(1),
|
|
GEOMETRY_SHADER = BIT(2),
|
|
DOMAIN_SHADER = BIT(3),
|
|
HULL_SHADER = BIT(4),
|
|
COMPUTE_SHADER = BIT(5)
|
|
};
|
|
|
|
/// Instances of this struct are returned GFXShaderConstBuffer
|
|
struct GFXShaderConstDesc
|
|
{
|
|
public:
|
|
String name = String::EmptyString;
|
|
GFXShaderConstType constType = GFXSCT_Uknown;
|
|
U32 arraySize = 0; // > 1 means it is an array!
|
|
S32 bindPoint = -1; // bind point used for ubo/cb
|
|
S32 samplerReg = -1; // sampler register.
|
|
U32 offset = 0; // offset for vars
|
|
U32 size = 0; // size of buffer/type
|
|
GFXShaderStage shaderStage = VERTEX_SHADER; // only used dx side.not wasting a bit for an unknown?
|
|
};
|
|
|
|
/// 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
|
|
/// (or shader). Client code should not free these.
|
|
class GFXShaderConstHandle
|
|
{
|
|
public:
|
|
|
|
GFXShaderConstHandle() { mValid = false; }
|
|
virtual ~GFXShaderConstHandle() {}
|
|
|
|
/// Returns true if this constant is valid and can
|
|
/// be set on the shader.
|
|
bool isValid() const { return mValid; }
|
|
|
|
/// Returns the name of the constant handle.
|
|
virtual const String& getName() const = 0;
|
|
|
|
/// Returns the type of the constant handle.
|
|
virtual GFXShaderConstType getType() const = 0;
|
|
|
|
virtual U32 getArraySize() const = 0;
|
|
|
|
/// Returns -1 if this handle does not point to a Sampler.
|
|
virtual S32 getSamplerRegister() const = 0;
|
|
|
|
protected:
|
|
|
|
/// The state of the constant which is
|
|
/// set from the derived class.
|
|
bool mValid;
|
|
|
|
};
|
|
|
|
|
|
/// GFXShaderConstBuffer is a collection of shader data which
|
|
/// are sent to the device in one call in most cases.
|
|
///
|
|
/// The content of the buffer is persistant and if a value
|
|
/// does not change frequently there is a savings in not setting
|
|
/// the value every frame.
|
|
///
|
|
class GFXShaderConstBuffer : public GFXResource, public StrongRefBase
|
|
{
|
|
protected:
|
|
|
|
/// The lost state of the buffer content.
|
|
///
|
|
/// Derived classes need to set the lost state
|
|
/// on first creation of the buffer and shader
|
|
/// reloads.
|
|
///
|
|
/// @see wasLost
|
|
bool mWasLost;
|
|
|
|
GFXShaderConstBuffer()
|
|
: mWasLost( true ),
|
|
mInstPtr( NULL )
|
|
{
|
|
}
|
|
|
|
public:
|
|
|
|
/// Return the shader that created this buffer
|
|
virtual GFXShader* getShader() = 0;
|
|
|
|
/// The content of the buffer is in the lost state when
|
|
/// first created or when the shader is reloaded. When
|
|
/// the content is lost you must refill the buffer
|
|
/// with all the constants used by your shader.
|
|
///
|
|
/// Use this property to avoid setting constants which do
|
|
/// not changefrom one frame to the next.
|
|
///
|
|
bool wasLost() const { return mWasLost; }
|
|
|
|
/// An inline helper which ensures the handle is valid
|
|
/// before the virtual set method is called.
|
|
///
|
|
/// You should prefer using this method unless your sure the
|
|
/// handle is always valid or if your doing your own test.
|
|
///
|
|
template< typename VALUE >
|
|
inline void setSafe( GFXShaderConstHandle *handle, const VALUE& v )
|
|
{
|
|
if ( handle->isValid() )
|
|
set( handle, v );
|
|
}
|
|
|
|
/// Set a shader constant.
|
|
///
|
|
/// The constant handle is assumed to be valid.
|
|
///
|
|
/// Perfer using setSafe unless you can check the handle
|
|
/// validity yourself and skip a significat amount of work.
|
|
///
|
|
/// @see GFXShaderConstHandle::isValid()
|
|
///
|
|
virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const S32 f) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv) = 0;
|
|
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& 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<Point4I>& fv) = 0;
|
|
|
|
/// Set a variable sized matrix shader constant.
|
|
virtual void set( GFXShaderConstHandle* handle,
|
|
const MatrixF& mat,
|
|
const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
|
|
|
|
/// Set a variable sized matrix shader constant from
|
|
/// an array of matricies.
|
|
virtual void set( GFXShaderConstHandle* handle,
|
|
const MatrixF* mat,
|
|
const U32 arraySize,
|
|
const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
|
|
|
|
// TODO: Make this protected and put a real API around it.
|
|
U8 *mInstPtr;
|
|
};
|
|
|
|
typedef StrongRefPtr<GFXShaderConstBuffer> GFXShaderConstBufferRef;
|
|
|
|
|
|
//**************************************************************************
|
|
// Shader
|
|
//**************************************************************************
|
|
class GFXShader : public StrongRefBase, public GFXResource
|
|
{
|
|
friend class GFXShaderConstBuffer;
|
|
|
|
protected:
|
|
|
|
/// These are system wide shader macros which are
|
|
/// merged with shader specific macros at creation.
|
|
static Vector<GFXShaderMacro> smGlobalMacros;
|
|
|
|
/// If true the shader errors are spewed to the console.
|
|
static bool smLogErrors;
|
|
|
|
/// If true the shader warnings are spewed to the console.
|
|
static bool smLogWarnings;
|
|
|
|
/// The vertex shader file.
|
|
Torque::Path mVertexFile;
|
|
|
|
/// The pixel shader file.
|
|
Torque::Path mPixelFile;
|
|
|
|
// the geometry shader file.
|
|
Torque::Path mGeometryFile;
|
|
|
|
/// The macros to be passed to the shader.
|
|
Vector<GFXShaderMacro> mMacros;
|
|
|
|
/// Ordered SamplerNames
|
|
/// We need to store a list of sampler for allow OpenGL to
|
|
/// assign correct location for each sampler.
|
|
/// GLSL 150 not allow explicit uniform location.
|
|
/// Only used on OpenGL
|
|
Vector<String> mSamplerNamesOrdered;
|
|
|
|
/// The pixel version this is compiled for.
|
|
F32 mPixVersion;
|
|
|
|
///
|
|
String mDescription;
|
|
|
|
/// Counter that is incremented each time this shader is reloaded.
|
|
U32 mReloadKey;
|
|
|
|
Signal<void()> mReloadSignal;
|
|
|
|
/// Vector of buffers that reference this shader.
|
|
/// It is the responsibility of the derived shader class to populate this
|
|
/// vector and to notify them when this shader is reloaded. Classes
|
|
/// derived from GFXShaderConstBuffer should call _unlinkBuffer from
|
|
/// their destructor.
|
|
Vector<GFXShaderConstBuffer*> mActiveBuffers;
|
|
|
|
GFXVertexFormat *mInstancingFormat;
|
|
|
|
/// A protected constructor so it cannot be instantiated.
|
|
GFXShader();
|
|
|
|
public:
|
|
|
|
/// Adds a global shader macro which will be merged with
|
|
/// the script defined macros on every shader reload.
|
|
///
|
|
/// The macro will replace the value of an existing macro
|
|
/// of the same name.
|
|
///
|
|
/// For the new macro to take effect all the shaders/materials
|
|
/// in the system need to be reloaded.
|
|
///
|
|
/// @see MaterialManager::flushAndReInitInstances
|
|
/// @see ShaderData::reloadAll
|
|
static void addGlobalMacro( const String &name, const String &value = String::EmptyString );
|
|
|
|
/// Removes an existing global macro by name.
|
|
/// @see addGlobalMacro
|
|
static bool removeGlobalMacro( const String &name );
|
|
|
|
/// Toggle logging for shader errors.
|
|
static void setLogging( bool logErrors,
|
|
bool logWarning )
|
|
{
|
|
smLogErrors = logErrors;
|
|
smLogWarnings = logWarning;
|
|
}
|
|
|
|
/// The destructor.
|
|
virtual ~GFXShader();
|
|
|
|
///
|
|
/// Deprecated. Remove on T3D 4.0
|
|
#ifndef TORQUE_OPENGL
|
|
bool init( const Torque::Path &vertFile,
|
|
const Torque::Path &pixFile,
|
|
F32 pixVersion,
|
|
const Vector<GFXShaderMacro> ¯os );
|
|
#endif
|
|
|
|
///
|
|
bool init( F32 pixVersion,
|
|
const Vector<GFXShaderMacro> ¯os,
|
|
const Vector<String> &samplerNames,
|
|
GFXVertexFormat *instanceFormat = NULL );
|
|
|
|
/// Reloads the shader from disk.
|
|
bool reload();
|
|
|
|
Signal<void()> getReloadSignal() { return mReloadSignal; }
|
|
|
|
/// Allocate a constant buffer
|
|
virtual GFXShaderConstBufferRef allocConstBuffer() = 0;
|
|
|
|
/// 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;
|
|
|
|
/// Returns a shader constant handle for the name constant.
|
|
///
|
|
/// Since shaders can reload and later have handles that didn't
|
|
/// exist originally this will return a handle in an invalid state
|
|
/// if the constant doesn't exist at this time.
|
|
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.
|
|
virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
|
|
|
|
/// Returns the alignment value for constType
|
|
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;
|
|
|
|
/// Returns the required vertex format for this shader.
|
|
/// Returns the pixel shader version.
|
|
F32 getPixVersion() const { return mPixVersion; }
|
|
|
|
/// Returns a counter which is incremented each time this shader is reloaded.
|
|
U32 getReloadKey() const { return mReloadKey; }
|
|
|
|
/// Device specific shaders can override this method to return
|
|
/// the shader disassembly.
|
|
virtual bool getDisassembly( String &outStr ) const { return false; }
|
|
|
|
void setShaderStageFile(const GFXShaderStage stage, const Torque::Path& filePath);
|
|
|
|
/// Returns the vertex shader file path.
|
|
const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
|
|
|
|
/// Returns the pixel shader file path.
|
|
const String& getPixelShaderFile() const { return mPixelFile.getFullPath(); }
|
|
|
|
// GFXResource
|
|
const String describeSelf() const override { return mDescription; }
|
|
|
|
// Get instancing vertex format
|
|
GFXVertexFormat *getInstancingFormat() { return mInstancingFormat; }
|
|
|
|
protected:
|
|
|
|
/// Called when the shader files change on disk.
|
|
void _onFileChanged( const Torque::Path &path ) { reload(); }
|
|
|
|
/// Internal initialization function overloaded for
|
|
/// each GFX device type.
|
|
virtual bool _init() = 0;
|
|
|
|
/// Buffers call this from their destructor (so we don't have to ref count them).
|
|
void _unlinkBuffer( GFXShaderConstBuffer *buf );
|
|
|
|
/// Called to update the description string after init.
|
|
void _updateDesc();
|
|
};
|
|
|
|
/// A strong pointer to a reference counted GFXShader.
|
|
typedef StrongRefPtr<GFXShader> GFXShaderRef;
|
|
|
|
|
|
/// A weak pointer to a reference counted GFXShader.
|
|
typedef WeakRefPtr<GFXShader> GFXShaderWeakRef;
|
|
|
|
|
|
#endif // GFXSHADER
|