Merge pull request #1223 from marauder2k9-torque/ShaderConstBuffer-CleanupRefactor

GFX Shader Refactor
This commit is contained in:
Brian Roberts 2024-03-14 10:29:32 -05:00 committed by GitHub
commit b624ec230a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 5021 additions and 2996 deletions

View file

@ -105,6 +105,7 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mLastVertShader = NULL; mLastVertShader = NULL;
mLastPixShader = NULL; mLastPixShader = NULL;
mLastGeoShader = NULL;
mCanCurrentlyRender = false; mCanCurrentlyRender = false;
mTextureManager = NULL; mTextureManager = NULL;
@ -159,6 +160,11 @@ GFXD3D11Device::~GFXD3D11Device()
for (; sampIter != mSamplersMap.end(); ++sampIter) for (; sampIter != mSamplersMap.end(); ++sampIter)
SAFE_RELEASE(sampIter->value); SAFE_RELEASE(sampIter->value);
// Free device buffers
DeviceBufferMap::Iterator bufferIter = mDeviceBufferMap.begin();
for (; bufferIter != mDeviceBufferMap.end(); ++bufferIter)
SAFE_RELEASE(bufferIter->value);
// Free the vertex declarations. // Free the vertex declarations.
VertexDeclMap::Iterator iter = mVertexDecls.begin(); VertexDeclMap::Iterator iter = mVertexDecls.begin();
for (; iter != mVertexDecls.end(); ++iter) for (; iter != mVertexDecls.end(); ++iter)
@ -519,14 +525,16 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
{ {
case D3D_FEATURE_LEVEL_11_1: case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_11_0:
mVertexShaderTarget = "vs_5_0"; mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0"; mPixelShaderTarget = "ps_5_0";
mGeometryShaderTarget = "gs_5_0";
mPixVersion = 5.0f; mPixVersion = 5.0f;
mShaderModel = "50"; mShaderModel = "50";
break; break;
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
mVertexShaderTarget = "vs_4_1"; mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1"; mPixelShaderTarget = "ps_4_1";
mGeometryShaderTarget = "gs_4_1";
mPixVersion = 4.1f; mPixVersion = 4.1f;
mShaderModel = "41"; mShaderModel = "41";
break; break;
@ -1246,6 +1254,12 @@ void GFXD3D11Device::setShader(GFXShader *shader, bool force)
mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0); mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0);
mLastVertShader = d3dShader->mVertShader; mLastVertShader = d3dShader->mVertShader;
} }
if (d3dShader->mGeoShader != mLastGeoShader || force)
{
mD3DDeviceContext->GSSetShader(d3dShader->mGeoShader, NULL, 0);
mLastGeoShader = d3dShader->mGeoShader;
}
} }
else else
{ {
@ -1852,3 +1866,39 @@ const char* GFXD3D11Device::interpretDebugResult(long result)
} }
return error; return error;
} }
ID3D11Buffer* GFXD3D11Device::getDeviceBuffer(const GFXShaderConstDesc desc)
{
String name(desc.name + "_" + String::ToString(desc.size));
DeviceBufferMap::Iterator buf = mDeviceBufferMap.find(name);
if (buf != mDeviceBufferMap.end())
{
mDeviceBufferMap[name]->AddRef();
return mDeviceBufferMap[name];
}
ID3D11Buffer* tempBuf;
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = desc.size;
cbDesc.Usage = D3D11_USAGE_DEFAULT;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = 0;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
HRESULT hr;
hr = D3D11DEVICE->CreateBuffer(&cbDesc, NULL, &tempBuf);
if (FAILED(hr))
{
AssertFatal(false, "Failed to create device buffer.");
}
mDeviceBufferMap[name] = tempBuf;
#ifdef TORQUE_DEBUG
tempBuf->SetPrivateData(WKPDID_D3DDebugObjectName, name.size(), name.c_str());
#endif
return tempBuf;
}

View file

@ -51,6 +51,7 @@ class GFXD3D11Device : public GFXDevice
{ {
public: public:
typedef Map<U32, ID3D11SamplerState*> SamplerMap; typedef Map<U32, ID3D11SamplerState*> SamplerMap;
typedef Map<String, ID3D11Buffer*> DeviceBufferMap;
private: private:
friend class GFXResource; friend class GFXResource;
@ -105,6 +106,7 @@ protected:
/// Used to lookup sampler state for a given hash key /// Used to lookup sampler state for a given hash key
SamplerMap mSamplersMap; SamplerMap mSamplersMap;
DeviceBufferMap mDeviceBufferMap;
ID3D11RenderTargetView* mDeviceBackBufferView; ID3D11RenderTargetView* mDeviceBackBufferView;
ID3D11DepthStencilView* mDeviceDepthStencilView; ID3D11DepthStencilView* mDeviceDepthStencilView;
@ -121,6 +123,7 @@ protected:
ID3D11VertexShader *mLastVertShader; ID3D11VertexShader *mLastVertShader;
ID3D11PixelShader *mLastPixShader; ID3D11PixelShader *mLastPixShader;
ID3D11GeometryShader *mLastGeoShader;
S32 mCreateFenceType; S32 mCreateFenceType;
@ -140,6 +143,7 @@ protected:
// Shader Model targers // Shader Model targers
String mVertexShaderTarget; String mVertexShaderTarget;
String mPixelShaderTarget; String mPixelShaderTarget;
String mGeometryShaderTarget;
// String for use with shader macros in the form of shader model version * 10 // String for use with shader macros in the form of shader model version * 10
String mShaderModel; String mShaderModel;
bool mDebugLayers; bool mDebugLayers;
@ -317,12 +321,16 @@ public:
// Shader Model targers // Shader Model targers
const String &getVertexShaderTarget() const { return mVertexShaderTarget; } const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
const String &getPixelShaderTarget() const { return mPixelShaderTarget; } const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
const String &getGeometryShaderTarget() const { return mGeometryShaderTarget; }
const String &getShaderModel() const { return mShaderModel; } const String &getShaderModel() const { return mShaderModel; }
// grab the sampler map // grab the sampler map
const SamplerMap &getSamplersMap() const { return mSamplersMap; } const SamplerMap &getSamplersMap() const { return mSamplersMap; }
SamplerMap &getSamplersMap(){ return mSamplersMap; } SamplerMap &getSamplersMap(){ return mSamplersMap; }
const char* interpretDebugResult(long result); const char* interpretDebugResult(long result);
// grab device buffer.
ID3D11Buffer* getDeviceBuffer(const GFXShaderConstDesc desc);
}; };
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -29,282 +29,87 @@
#include "core/util/tDictionary.h" #include "core/util/tDictionary.h"
#include "gfx/gfxShader.h" #include "gfx/gfxShader.h"
#include "gfx/gfxResource.h" #include "gfx/gfxResource.h"
#include "gfx/genericConstBuffer.h"
#include "gfx/D3D11/gfxD3D11Device.h" #include "gfx/D3D11/gfxD3D11Device.h"
class GFXD3D11Shader; class GFXD3D11Shader;
enum CONST_CLASS typedef CompoundKey<U32, U32> BufferKey;
struct BufferRange
{ {
D3DPC_SCALAR, U32 mBufMin = U32_MAX;
D3DPC_VECTOR, U32 mBufMax = 0;
D3DPC_MATRIX_ROWS,
D3DPC_MATRIX_COLUMNS,
D3DPC_OBJECT,
D3DPC_STRUCT
};
enum CONST_TYPE inline void addSlot(U32 slot)
{
D3DPT_VOID,
D3DPT_BOOL,
D3DPT_INT,
D3DPT_FLOAT,
D3DPT_STRING,
D3DPT_TEXTURE,
D3DPT_TEXTURE1D,
D3DPT_TEXTURE2D,
D3DPT_TEXTURE3D,
D3DPT_TEXTURECUBE,
D3DPT_SAMPLER,
D3DPT_SAMPLER1D,
D3DPT_SAMPLER2D,
D3DPT_SAMPLER3D,
D3DPT_SAMPLERCUBE,
D3DPT_PIXELSHADER,
D3DPT_VERTEXSHADER,
D3DPT_PIXELFRAGMENT,
D3DPT_VERTEXFRAGMENT
};
enum REGISTER_TYPE
{
D3DRS_BOOL,
D3DRS_INT4,
D3DRS_FLOAT4,
D3DRS_SAMPLER
};
struct ConstantDesc
{
String Name = String::EmptyString;
S32 RegisterIndex = 0;
S32 RegisterCount = 0;
S32 Rows = 0;
S32 Columns = 0;
S32 Elements = 0;
S32 StructMembers = 0;
REGISTER_TYPE RegisterSet = D3DRS_FLOAT4;
CONST_CLASS Class = D3DPC_SCALAR;
CONST_TYPE Type = D3DPT_FLOAT;
U32 Bytes = 0;
};
class ConstantTable
{
public:
bool Create(const void* data);
U32 GetConstantCount() const { return m_constants.size(); }
const String& GetCreator() const { return m_creator; }
const ConstantDesc* GetConstantByIndex(U32 i) const { return &m_constants[i]; }
const ConstantDesc* GetConstantByName(const String& name) const;
void ClearConstants() { m_constants.clear(); }
private:
Vector<ConstantDesc> m_constants;
String m_creator;
};
// Structs
struct CTHeader
{
U32 Size;
U32 Creator;
U32 Version;
U32 Constants;
U32 ConstantInfo;
U32 Flags;
U32 Target;
};
struct CTInfo
{
U32 Name;
U16 RegisterSet;
U16 RegisterIndex;
U16 RegisterCount;
U16 Reserved;
U32 TypeInfo;
U32 DefaultValue;
};
struct CTType
{
U16 Class;
U16 Type;
U16 Rows;
U16 Columns;
U16 Elements;
U16 StructMembers;
U32 StructMemberInfo;
};
// Shader instruction opcodes
const U32 SIO_COMMENT = 0x0000FFFE;
const U32 SIO_END = 0x0000FFFF;
const U32 SI_OPCODE_MASK = 0x0000FFFF;
const U32 SI_COMMENTSIZE_MASK = 0x7FFF0000;
const U32 CTAB_CONSTANT = 0x42415443;
// Member functions
inline bool ConstantTable::Create(const void* data)
{
const U32* ptr = static_cast<const U32*>(data);
while(*++ptr != SIO_END)
{ {
if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT) mBufMin = getMin(mBufMin, slot);
{ mBufMax = getMax(mBufMax, slot);
// Check for CTAB comment
U32 comment_size = (*ptr & SI_COMMENTSIZE_MASK) >> 16;
if(*(ptr+1) != CTAB_CONSTANT)
{
ptr += comment_size;
continue;
}
// Read header
const char* ctab = reinterpret_cast<const char*>(ptr+2);
size_t ctab_size = (comment_size-1)*4;
const CTHeader* header = reinterpret_cast<const CTHeader*>(ctab);
if(ctab_size < sizeof(*header) || header->Size != sizeof(*header))
return false;
m_creator = ctab + header->Creator;
// Read constants
m_constants.reserve(header->Constants);
const CTInfo* info = reinterpret_cast<const CTInfo*>(ctab + header->ConstantInfo);
for(U32 i = 0; i < header->Constants; ++i)
{
const CTType* type = reinterpret_cast<const CTType*>(ctab + info[i].TypeInfo);
// Fill struct
ConstantDesc desc;
desc.Name = ctab + info[i].Name;
desc.RegisterSet = static_cast<REGISTER_TYPE>(info[i].RegisterSet);
desc.RegisterIndex = info[i].RegisterIndex;
desc.RegisterCount = info[i].RegisterCount;
desc.Rows = type->Rows;
desc.Class = static_cast<CONST_CLASS>(type->Class);
desc.Type = static_cast<CONST_TYPE>(type->Type);
desc.Columns = type->Columns;
desc.Elements = type->Elements;
desc.StructMembers = type->StructMembers;
desc.Bytes = 4 * desc.Elements * desc.Rows * desc.Columns;
m_constants.push_back(desc);
}
return true;
}
} }
return false;
}
inline const ConstantDesc* ConstantTable::GetConstantByName(const String& name) const inline bool isValid() const { return mBufMin <= mBufMax; }
};
struct ConstantBuffer
{ {
Vector<ConstantDesc>::const_iterator it; U8* data;
for(it = m_constants.begin(); it != m_constants.end(); ++it)
{
if(it->Name == name)
return &(*it);
}
return NULL;
}
/////////////////// Constant Buffers /////////////////////////////
// Maximum number of CBuffers ($Globals & $Params)
const U32 CBUFFER_MAX = 2;
struct ConstSubBufferDesc
{
U32 start;
U32 size; U32 size;
bool isDirty;
ConstSubBufferDesc() : start(0), size(0){}
};
class GFXD3D11ConstBufferLayout : public GenericConstBufferLayout
{
public:
GFXD3D11ConstBufferLayout();
/// Get our constant sub buffer data
Vector<ConstSubBufferDesc> &getSubBufferDesc(){ return mSubBuffers; }
/// We need to manually set the size due to D3D11 alignment
void setSize(U32 size){ mBufferSize = size;}
/// Set a parameter, given a base pointer
virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
protected:
/// Set a matrix, given a base pointer
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
Vector<ConstSubBufferDesc> mSubBuffers;
}; };
class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
{ {
friend class GFXD3D11Shader;
public: public:
typedef Map<GFXShaderStage, GFXShaderConstDesc> DescMap;
// GFXShaderConstHandle GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader);
const String& getName() const; GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
GFXShaderConstType getType() const; const GFXShaderConstDesc& desc);
U32 getArraySize() const;
WeakRefPtr<GFXD3D11Shader> mShader; virtual ~GFXD3D11ShaderConstHandle();
void addDesc(GFXShaderStage stage, const GFXShaderConstDesc& desc);
const GFXShaderConstDesc getDesc(GFXShaderStage stage);
const String& getName() const { return mDesc.name; }
GFXShaderConstType getType() const { return mDesc.constType; }
U32 getArraySize() const { return mDesc.arraySize; }
bool mVertexConstant; U32 getSize() const { return mDesc.size; }
GenericConstBufferLayout::ParamDesc mVertexHandle; void setValid(bool valid) { mValid = valid; }
bool mPixelConstant; /// @warning This will always return the value assigned when the shader was
GenericConstBufferLayout::ParamDesc mPixelHandle; /// initialized. If the value is later changed this method won't reflect that.
S32 getSamplerRegister() const { return (!isSampler() || !mValid) ? -1 : mDesc.samplerReg; }
/// Is true if this constant is for hardware mesh instancing.
///
/// Note: We currently store its settings in mPixelHandle.
///
bool mInstancingConstant;
void setValid( bool valid ) { mValid = valid; }
S32 getSamplerRegister() const;
// Returns true if this is a handle to a sampler register. // Returns true if this is a handle to a sampler register.
bool isSampler() const bool isSampler() const
{ {
return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) || ( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler ); return (getType() >= GFXSCT_Sampler);
} }
/// Restore to uninitialized state. /// Restore to uninitialized state.
void clear() void clear()
{ {
mShader = NULL; mShader = NULL;
mVertexConstant = false;
mPixelConstant = false;
mInstancingConstant = false; mInstancingConstant = false;
mVertexHandle.clear();
mPixelHandle.clear();
mValid = false; mValid = false;
} }
GFXD3D11ShaderConstHandle(); GFXShaderConstDesc mDesc;
GFXD3D11Shader* mShader;
DescMap mDescMap;
U32 mStageFlags;
bool mInstancingConstant;
}; };
/// The D3D11 implementation of a shader constant buffer. /// The D3D11 implementation of a shader constant buffer.
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
{ {
friend class GFXD3D11Shader;
// Cache device context // Cache device context
ID3D11DeviceContext* mDeviceContext; ID3D11DeviceContext* mDeviceContext;
public: public:
typedef Map<BufferKey, ConstantBuffer> BufferMap;
GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader, GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader);
GFXD3D11ConstBufferLayout* vertexLayout,
GFXD3D11ConstBufferLayout* pixelLayout);
virtual ~GFXD3D11ShaderConstBuffer(); virtual ~GFXD3D11ShaderConstBuffer();
@ -312,8 +117,7 @@ public:
/// @param mPrevShaderBuffer The previously active buffer /// @param mPrevShaderBuffer The previously active buffer
void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer); void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
/// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty. void addBuffer(const GFXShaderConstDesc desc);
bool isDirty();
/// Called from GFXD3D11Shader when constants have changed and need /// Called from GFXD3D11Shader when constants have changed and need
/// to be the shader this buffer references is reloaded. /// to be the shader this buffer references is reloaded.
@ -344,33 +148,20 @@ public:
// GFXResource // GFXResource
virtual const String describeSelf() const; virtual const String describeSelf() const;
virtual void zombify(); virtual void zombify() {}
virtual void resurrect(); virtual void resurrect() {}
protected: protected:
friend class GFXD3D11Shader;
void _createBuffers();
template<class T>
inline void SET_CONSTANT(GFXShaderConstHandle* handle,
const T& fv,
GenericConstBuffer *vBuffer,
GenericConstBuffer *pBuffer);
// Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers
ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX];
ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX];
/// We keep a weak reference to the shader /// We keep a weak reference to the shader
/// because it will often be deleted. /// because it will often be deleted.
WeakRefPtr<GFXD3D11Shader> mShader; WeakRefPtr<GFXD3D11Shader> mShader;
BufferMap mBufferMap;
//vertex void setMatrix(const GFXShaderConstDesc& handle, const U32 inSize, const void* data, U8* basePointer);
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout; void internalSet(GFXShaderConstHandle* handle, const U32 inSize, const void* data);
GenericConstBuffer* mVertexConstBuffer;
//pixel ID3D11Buffer* mBoundBuffers[6][16];
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
GenericConstBuffer* mPixelConstBuffer;
}; };
class gfxD3D11Include; class gfxD3D11Include;
@ -385,6 +176,7 @@ class GFXD3D11Shader : public GFXShader
public: public:
typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap; typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
typedef Map<String, GFXShaderConstDesc> BufferMap;
GFXD3D11Shader(); GFXD3D11Shader();
virtual ~GFXD3D11Shader(); virtual ~GFXD3D11Shader();
@ -395,7 +187,6 @@ public:
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name); virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name); virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const; virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual bool getDisassembly( String &outStr ) const;
// GFXResource // GFXResource
virtual void zombify(); virtual void zombify();
@ -405,69 +196,34 @@ protected:
virtual bool _init(); virtual bool _init();
static const U32 smCompiledShaderTag;
ConstantTable table;
ID3D11VertexShader *mVertShader; ID3D11VertexShader *mVertShader;
ID3D11PixelShader *mPixShader; ID3D11PixelShader *mPixShader;
ID3D11GeometryShader *mGeoShader;
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
static gfxD3DIncludeRef smD3DInclude; static gfxD3DIncludeRef smD3DInclude;
HandleMap mHandles; HandleMap mHandles;
BufferMap mBuffers;
/// The shader disassembly from DX when this shader is compiled.
/// We only store this data in non-release builds.
String mDissasembly;
/// Vector of sampler type descriptions consolidated from _compileShader.
Vector<GFXShaderConstDesc> mSamplerDescriptions;
/// Vector of descriptions (consolidated for the getShaderConstDesc call) /// Vector of descriptions (consolidated for the getShaderConstDesc call)
Vector<GFXShaderConstDesc> mShaderConsts; Vector<GFXShaderConstDesc> mShaderConsts;
Vector<GFXShaderConstDesc> mSamplerDescriptions;
// These two functions are used when compiling shaders from hlsl // These two functions are used when compiling shaders from hlsl
virtual bool _compileShader( const Torque::Path &filePath, virtual bool _compileShader( const Torque::Path &filePath,
const String &target, GFXShaderStage shaderStage,
const D3D_SHADER_MACRO *defines, const D3D_SHADER_MACRO *defines);
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
void _getShaderConstants( ID3D11ShaderReflection* refTable, void _getShaderConstants( ID3D11ShaderReflection* refTable,
GenericConstBufferLayout *bufferLayout, GFXShaderStage shaderStage);
Vector<GFXShaderConstDesc> &samplerDescriptions );
bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc);
bool _saveCompiledOutput( const Torque::Path &filePath,
ID3DBlob *buffer,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
// Loads precompiled shaders
bool _loadCompiledOutput( const Torque::Path &filePath,
const String &target,
GenericConstBufferLayout *bufferLayoutF,
Vector<GFXShaderConstDesc> &samplerDescriptions );
// This is used in both cases // This is used in both cases
virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst); virtual void _buildShaderConstantHandles();
virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
/// Used to build the instancing shader constants from
/// the instancing vertex format.
void _buildInstancingShaderConstantHandles(); void _buildInstancingShaderConstantHandles();
GFXShaderConstType convertConstType(D3D11_SHADER_TYPE_DESC typeDesc);
}; };
inline bool GFXD3D11Shader::getDisassembly(String &outStr) const
{
outStr = mDissasembly;
return (outStr.isNotEmpty());
}
#endif #endif

View file

@ -34,6 +34,9 @@
#define STBIWDEF static inline #define STBIWDEF static inline
#endif #endif
#pragma warning( push )
#pragma warning( disable : 4505 ) // unreferenced function removed.
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_STATIC #define STB_IMAGE_STATIC
#include "stb_image.h" #include "stb_image.h"
@ -42,6 +45,8 @@
#define STB_IMAGE_WRITE_STATIC #define STB_IMAGE_WRITE_STATIC
#include "stb_image_write.h" #include "stb_image_write.h"
#pragma warning(pop)
static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap); static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap);
static bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len); static bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len);
@ -399,8 +404,6 @@ bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel)
String ext = path.getExtension(); String ext = path.getExtension();
U32 stride = width * bytes;
// we always have at least 1 // we always have at least 1
U32 comp = 1; U32 comp = 1;
@ -554,7 +557,6 @@ void DeferredPNGWriter::append(GBitmap* bitmap, U32 rows)
mData->channels = bitmap->getBytesPerPixel(); mData->channels = bitmap->getBytesPerPixel();
} }
const U32 height = getMin(bitmap->getHeight(), rows);
const dsize_t dataChuckSize = bitmap->getByteSize(); const dsize_t dataChuckSize = bitmap->getByteSize();
const U8* pSrcData = bitmap->getBits(); const U8* pSrcData = bitmap->getBits();

View file

@ -1,289 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "gfx/genericConstBuffer.h"
#include "platform/profiler.h"
#include "core/stream/stream.h"
GenericConstBufferLayout::GenericConstBufferLayout()
{
VECTOR_SET_ASSOCIATION( mParams );
mBufferSize = 0;
mCurrentIndex = 0;
mTimesCleared = 0;
}
void GenericConstBufferLayout::addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue)
{
#ifdef TORQUE_DEBUG
// Make sure we don't have overlapping parameters
S32 start = offset;
S32 end = offset + size;
for (Params::iterator i = mParams.begin(); i != mParams.end(); i++)
{
const ParamDesc& dp = *i;
S32 pstart = dp.offset;
S32 pend = pstart + dp.size;
pstart -= start;
pend -= end;
// This is like a minkowski sum for two line segments, if the newly formed line contains
// the origin, then they intersect
bool intersect = ((pstart >= 0 && 0 >= pend) || ((pend >= 0 && 0 >= pstart)));
AssertFatal(!intersect, "Overlapping shader parameter!");
}
#endif
ParamDesc desc;
desc.name = name;
desc.constType = constType;
desc.offset = offset;
desc.size = size;
desc.arraySize = arraySize;
desc.alignValue = alignValue;
desc.index = mCurrentIndex++;
mParams.push_back(desc);
mBufferSize = getMax(desc.offset + desc.size, mBufferSize);
AssertFatal(mBufferSize, "Empty constant buffer!");
}
bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
{
PROFILE_SCOPE(GenericConstBufferLayout_set);
// Shader compilers like to optimize float4x4 uniforms into float3x3s.
// So long as the real paramater is a matrix of-some-type and the data
// passed in is a MatrixF ( which is will be ), we DO NOT have a
// mismatched const type.
AssertFatal( pd.constType == constType ||
(
( pd.constType == GFXSCT_Float2x2 ||
pd.constType == GFXSCT_Float3x3 ||
pd.constType == GFXSCT_Float3x4 ||
pd.constType == GFXSCT_Float4x3 ||
pd.constType == GFXSCT_Float4x4 ) &&
( constType == GFXSCT_Float2x2 ||
constType == GFXSCT_Float3x3 ||
constType == GFXSCT_Float3x4 ||
constType == GFXSCT_Float4x3 ||
constType == GFXSCT_Float4x4 )
), "Mismatched const type!" );
// This "cute" bit of code allows us to support 2x3 and 3x3 matrices in shader constants but use our MatrixF class. Yes, a hack. -BTR
switch (pd.constType)
{
case GFXSCT_Float2x2 :
case GFXSCT_Float3x3 :
case GFXSCT_Float4x3 :
case GFXSCT_Float4x4 :
return setMatrix(pd, constType, size, data, basePointer);
break;
default :
break;
}
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
// Ok, we only set data if it's different than the data we already have, this maybe more expensive than just setting the data, but
// we'll have to do some timings to see. For example, the lighting shader constants rarely change, but we can't assume that at the
// renderInstMgr level, but we can check down here. -BTR
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
{
dMemcpy(basePointer+pd.offset, data, size);
return true;
}
return false;
}
bool GenericConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
{
PROFILE_SCOPE(GenericConstBufferLayout_setMatrix);
// We're generic, so just copy the full MatrixF in
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
// Matrices are an annoying case because of the alignment issues. There are alignment issues in the matrix itself, and then potential inter matrices alignment issues.
// So GL and DX will need to derive their own GenericConstBufferLayout classes and override this method to deal with that stuff. For GenericConstBuffer, copy the whole
// 4x4 matrix regardless of the target case.
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
{
dMemcpy(basePointer+pd.offset, data, size);
return true;
}
return false;
}
bool GenericConstBufferLayout::getDesc(const String& name, ParamDesc& param) const
{
for (U32 i = 0; i < mParams.size(); i++)
{
if (mParams[i].name.equal(name))
{
param = mParams[i];
return true;
}
}
return false;
}
bool GenericConstBufferLayout::getDesc(const U32 index, ParamDesc& param) const
{
if ( index < mParams.size() )
{
param = mParams[index];
return true;
}
return false;
}
bool GenericConstBufferLayout::write(Stream* s)
{
// Write out the size of the ParamDesc structure as a sanity check.
if (!s->write((U32) sizeof(ParamDesc)))
return false;
// Next, write out the number of elements we've got.
if (!s->write(mParams.size()))
return false;
for (U32 i = 0; i < mParams.size(); i++)
{
s->write(mParams[i].name);
if (!s->write(mParams[i].offset))
return false;
if (!s->write(mParams[i].size))
return false;
U32 t = (U32) mParams[i].constType;
if (!s->write(t))
return false;
if (!s->write(mParams[i].arraySize))
return false;
if (!s->write(mParams[i].alignValue))
return false;
if (!s->write(mParams[i].index))
return false;
}
return true;
}
/// Load this layout from a stream
bool GenericConstBufferLayout::read(Stream* s)
{
U32 structSize;
if (!s->read(&structSize))
return false;
if (structSize != sizeof(ParamDesc))
{
AssertFatal(false, "Invalid shader layout structure size!");
return false;
}
U32 numParams;
if (!s->read(&numParams))
return false;
mParams.setSize(numParams);
mBufferSize = 0;
mCurrentIndex = 0;
for (U32 i = 0; i < mParams.size(); i++)
{
s->read(&mParams[i].name);
if (!s->read(&mParams[i].offset))
return false;
if (!s->read(&mParams[i].size))
return false;
U32 t;
if (!s->read(&t))
return false;
mParams[i].constType = (GFXShaderConstType) t;
if (!s->read(&mParams[i].arraySize))
return false;
if (!s->read(&mParams[i].alignValue))
return false;
if (!s->read(&mParams[i].index))
return false;
mBufferSize = getMax(mParams[i].offset + mParams[i].size, mBufferSize);
mCurrentIndex = getMax(mParams[i].index, mCurrentIndex);
}
mCurrentIndex++;
return true;
}
void GenericConstBufferLayout::clear()
{
mParams.clear();
mBufferSize = 0;
mCurrentIndex = 0;
mTimesCleared++;
}
GenericConstBuffer::GenericConstBuffer(GenericConstBufferLayout* layout)
: mLayout( layout ),
mBuffer( NULL ),
mDirtyStart( U32_MAX ),
mDirtyEnd( 0 )
{
if ( layout && layout->getBufferSize() > 0 )
{
mBuffer = new U8[mLayout->getBufferSize()];
// Always set a default value, that way our isEqual checks
// will work in release as well.
dMemset( mBuffer, 0xFFFF, mLayout->getBufferSize() );
#ifdef TORQUE_DEBUG
// Clear the debug assignment tracking.
mWasAssigned.setSize( layout->getParameterCount() );
dMemset( mWasAssigned.address(), 0, mWasAssigned.memSize() );
#endif
}
}
GenericConstBuffer::~GenericConstBuffer()
{
delete [] mBuffer;
}
#ifdef TORQUE_DEBUG
void GenericConstBuffer::assertUnassignedConstants( const char *shaderName )
{
for ( U32 i=0; i < mWasAssigned.size(); i++ )
{
if ( mWasAssigned[i] )
continue;
GenericConstBufferLayout::ParamDesc pd;
mLayout->getDesc( i, pd );
// Assert on the unassigned constant.
//AssertFatal( false, avar( "The '%s' shader constant in shader '%s' was unassigned!",
// pd.name.c_str(), shaderName ) );
}
}
#endif

View file

@ -1,374 +0,0 @@
//-----------------------------------------------------------------------------
// 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 _GENERICCONSTBUFFER_H_
#define _GENERICCONSTBUFFER_H_
#ifndef _TORQUE_STRING_H_
#include "core/util/str.h"
#endif
#ifndef _TDICTIONARY_H_
#include "core/util/tDictionary.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _ALIGNEDARRAY_H_
#include "core/util/tAlignedArray.h"
#endif
#ifndef _COLOR_H_
#include "core/color.h"
#endif
#ifndef _MMATRIX_H_
#include "math/mMatrix.h"
#endif
#ifndef _MPOINT2_H_
#include "math/mPoint2.h"
#endif
#ifndef _GFXENUMS_H_
#include "gfx/gfxEnums.h"
#endif
class Stream;
/// This class defines the memory layout for a GenericConstBuffer.
class GenericConstBufferLayout
{
public:
/// Describes the parameters we contain
struct ParamDesc
{
ParamDesc()
: name(),
offset( 0 ),
size( 0 ),
constType( GFXSCT_Float ),
arraySize( 0 ),
alignValue( 0 ),
index( 0 )
{
}
void clear()
{
name = String::EmptyString;
offset = 0;
size = 0;
constType = GFXSCT_Float;
arraySize = 0;
alignValue = 0;
index = 0;
}
/// Parameter name
String name;
/// Offset into the memory block
U32 offset;
/// Size of the block
U32 size;
/// Type of data
GFXShaderConstType constType;
// For arrays, how many elements
U32 arraySize;
// Array element alignment value
U32 alignValue;
/// 0 based index of this param, in order of addParameter calls.
U32 index;
};
GenericConstBufferLayout();
virtual ~GenericConstBufferLayout() {}
/// Add a parameter to the buffer
virtual void addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue);
/// Get the size of the buffer
inline U32 getBufferSize() const { return mBufferSize; }
/// Get the number of parameters
inline U32 getParameterCount() const { return mParams.size(); }
/// Returns the ParamDesc of a parameter
bool getDesc(const String& name, ParamDesc& param) const;
/// Returns the ParamDesc of a parameter
bool getDesc(const U32 index, ParamDesc& param) const;
/// Set a parameter, given a base pointer
virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
/// Save this layout to a stream
bool write(Stream* s);
/// Load this layout from a stream
bool read(Stream* s);
/// Restore to initial state.
void clear();
protected:
/// Set a matrix, given a base pointer.
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
/// Vector of parameter descriptions.
typedef Vector<ParamDesc> Params;
/// Vector of parameter descriptions.
Params mParams;
U32 mBufferSize;
U32 mCurrentIndex;
// This if for debugging shader reloading and can be removed later.
U32 mTimesCleared;
};
/// This class manages shader constant data in a system memory buffer. It is
/// used by device specific classes for batching together many constant changes
/// which are then copied to the device thru a single API call.
///
/// @see GenericConstBufferLayout
///
class GenericConstBuffer
{
public:
GenericConstBuffer(GenericConstBufferLayout* layout);
~GenericConstBuffer();
/// @name Set shader constant values
/// @{
/// Actually set shader constant values
/// @param name Name of the constant, this should be a name contained in the array returned in getShaderConstDesc,
/// if an invalid name is used, its ignored, but it's not an error.
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const F32 f) { internalSet(pd, GFXSCT_Float, sizeof(F32), &f); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2F& fv) { internalSet(pd, GFXSCT_Float2, sizeof(Point2F), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3F& fv) { internalSet(pd, GFXSCT_Float3, sizeof(Point3F), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4F& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const PlaneF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(PlaneF), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const LinearColorF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const S32 f) { internalSet(pd, GFXSCT_Int, sizeof(S32), &f); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2I& fv) { internalSet(pd, GFXSCT_Int2, sizeof(Point2I), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3I& fv) { internalSet(pd, GFXSCT_Int3, sizeof(Point3I), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4I& fv) { internalSet(pd, GFXSCT_Int4, sizeof(Point4I), &fv); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<F32>& fv) { internalSet(pd, GFXSCT_Float, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2F>& fv) { internalSet(pd, GFXSCT_Float2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3F>& fv) { internalSet(pd, GFXSCT_Float3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4F>& fv) { internalSet(pd, GFXSCT_Float4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<S32>& fv) { internalSet(pd, GFXSCT_Int, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2I>& fv) { internalSet(pd, GFXSCT_Int2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3I>& fv) { internalSet(pd, GFXSCT_Int3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4I>& fv) { internalSet(pd, GFXSCT_Int4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF& mat, const GFXShaderConstType matrixType )
{
AssertFatal( matrixType == GFXSCT_Float2x2 ||
matrixType == GFXSCT_Float3x3 ||
matrixType == GFXSCT_Float3x4 ||
matrixType == GFXSCT_Float4x3 ||
matrixType == GFXSCT_Float4x4,
"GenericConstBuffer::set() - Invalid matrix type!" );
internalSet( pd, matrixType, sizeof(MatrixF), &mat );
}
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType )
{
AssertFatal( matrixType == GFXSCT_Float2x2 ||
matrixType == GFXSCT_Float3x3 ||
matrixType == GFXSCT_Float3x4 ||
matrixType == GFXSCT_Float4x3 ||
matrixType == GFXSCT_Float4x4,
"GenericConstBuffer::set() - Invalid matrix type!" );
internalSet( pd, matrixType, sizeof(MatrixF)*arraySize, mat );
}
/// Gets the dirty buffer range and clears the dirty
/// state at the same time.
inline const U8* getDirtyBuffer( U32 *start, U32 *size );
/// Gets the entire buffer ignoring dirty range
inline const U8* getEntireBuffer();
/// Sets the entire buffer as dirty or clears the dirty state.
inline void setDirty( bool dirty );
/// Returns true if the buffer has been modified since the
/// last call to getDirtyBuffer or setDirty. The buffer is
/// not dirty on initial creation.
///
/// @see getDirtyBuffer
/// @see setDirty
inline bool isDirty() const { return mDirtyEnd != 0; }
/// Returns true if have the same layout and hold the same
/// data as the input buffer.
inline bool isEqual( const GenericConstBuffer *buffer ) const;
/// Returns our layout object.
inline GenericConstBufferLayout* getLayout() const { return mLayout; }
#ifdef TORQUE_DEBUG
/// Helper function used to assert on unset constants.
void assertUnassignedConstants( const char *shaderName );
#endif
protected:
/// Returns a pointer to the raw buffer
inline const U8* getBuffer() const { return mBuffer; }
/// Called by the inlined set functions above to do the
/// real dirty work of copying the data to the right location
/// within the buffer.
inline void internalSet( const GenericConstBufferLayout::ParamDesc &pd,
const GFXShaderConstType constType,
const U32 size,
const void *data );
/// The buffer layout.
GenericConstBufferLayout *mLayout;
/// The pointer to the contant store or
/// NULL if the layout is empty.
U8 *mBuffer;
/// The byte offset to the start of the dirty
/// range within the buffer or U32_MAX if the
/// buffer is not dirty.
U32 mDirtyStart;
/// The btye offset to the end of the dirty
/// range within the buffer or 0 if the buffer
/// is not dirty.
U32 mDirtyEnd;
#ifdef TORQUE_DEBUG
/// A vector used to keep track if a constant
/// has beed assigned a value or not.
///
/// @see assertUnassignedConstants
Vector<bool> mWasAssigned;
#endif
};
// NOTE: These inlines below are here to get the very best possible
// performance when setting the device shader constants and can be
// called 4000-8000 times per frame or more.
//
// You need a very good reason to consider changing them.
inline void GenericConstBuffer::internalSet( const GenericConstBufferLayout::ParamDesc &pd,
const GFXShaderConstType constType,
const U32 size,
const void *data )
{
// NOTE: We should have never gotten here if the buffer
// was null as no valid shader constant could have been
// assigned.
//
// If this happens its a bug in another part of the code.
//
AssertFatal( mBuffer, "GenericConstBuffer::internalSet - The buffer is NULL!" );
if ( mLayout->set( pd, constType, size, data, mBuffer ) )
{
#ifdef TORQUE_DEBUG
// Update the debug assignment tracking.
mWasAssigned[ pd.index ] = true;
#endif
// Keep track of the dirty range so it can be queried
// later in GenericConstBuffer::getDirtyBuffer.
mDirtyStart = getMin( pd.offset, mDirtyStart );
mDirtyEnd = getMax( pd.offset + pd.size, mDirtyEnd );
}
}
inline void GenericConstBuffer::setDirty( bool dirty )
{
if ( !mBuffer )
return;
if ( dirty )
{
mDirtyStart = 0;
mDirtyEnd = mLayout->getBufferSize();
}
else if ( !dirty )
{
mDirtyStart = U32_MAX;
mDirtyEnd = 0;
}
}
inline const U8* GenericConstBuffer::getDirtyBuffer( U32 *start, U32 *size )
{
AssertFatal( isDirty(), "GenericConstBuffer::getDirtyBuffer() - Buffer is not dirty!" );
AssertFatal( mDirtyEnd > mDirtyStart, "GenericConstBuffer::getDirtyBuffer() - Dirty range is invalid!" );
AssertFatal( mBuffer, "GenericConstBuffer::getDirtyBuffer() - Buffer is empty!" );
// Use the area we calculated during internalSet.
*size = mDirtyEnd - mDirtyStart;
*start = mDirtyStart;
const U8 *buffer = mBuffer + mDirtyStart;
// Clear the dirty state while we're here.
mDirtyStart = U32_MAX;
mDirtyEnd = 0;
return buffer;
}
inline const U8* GenericConstBuffer::getEntireBuffer()
{
AssertFatal(mBuffer, "GenericConstBuffer::getDirtyBuffer() - Buffer is empty!");
return mBuffer;
}
inline bool GenericConstBuffer::isEqual( const GenericConstBuffer *buffer ) const
{
U32 bsize = mLayout->getBufferSize();
if ( bsize != buffer->mLayout->getBufferSize() )
return false;
return dMemcmp( mBuffer, buffer->getBuffer(), bsize ) == 0;
}
#endif // _GENERICCONSTBUFFER_H_

View file

@ -34,7 +34,7 @@
#include "gfx/gfxPrimitiveBuffer.h" #include "gfx/gfxPrimitiveBuffer.h"
#include "gfx/primBuilder.h" #include "gfx/primBuilder.h"
#include "gfx/gfxDebugEvent.h" #include "gfx/gfxDebugEvent.h"
#include "materials/shaderData.h"
#include "math/mPolyhedron.impl.h" #include "math/mPolyhedron.impl.h"
@ -90,6 +90,33 @@ void GFXDrawUtil::_setupStateBlocks()
rectFill.setZReadWrite(false); rectFill.setZReadWrite(false);
rectFill.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); rectFill.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
mRectFillSB = mDevice->createStateBlock(rectFill); mRectFillSB = mDevice->createStateBlock(rectFill);
// Find ShaderData
ShaderData* shaderData;
mRoundRectangleShader = Sim::findObject("RoundedRectangleGUI", shaderData) ? shaderData->getShader() : NULL;
if (!mRoundRectangleShader)
{
Con::errorf("GFXDrawUtil - could not find Rounded Rectangle shader");
}
// Create ShaderConstBuffer and Handles
mRoundRectangleShaderConsts = mRoundRectangleShader->allocConstBuffer();
mCircleShader = Sim::findObject("CircularGUI", shaderData) ? shaderData->getShader() : NULL;
if (!mCircleShader)
{
Con::errorf("GFXDrawUtil - could not find circle shader");
}
// Create ShaderConstBuffer and Handles
mCircleShaderConsts = mCircleShader->allocConstBuffer();
mThickLineShader = Sim::findObject("ThickLineGUI", shaderData) ? shaderData->getShader() : NULL;
if (!mThickLineShader)
{
Con::errorf("GFXDrawUtil - could not find Thick line shader");
}
// Create ShaderConstBuffer and Handles
mThickLineShaderConsts = mThickLineShader->allocConstBuffer();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -513,57 +540,99 @@ void GFXDrawUtil::drawRect( const Point2F &upperLeft, const Point2F &lowerRight,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Draw Rectangle Fill // Draw Rectangle Fill
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void GFXDrawUtil::drawRectFill( const RectF &rect, const ColorI &color ) void GFXDrawUtil::drawRectFill(const RectF& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{ {
drawRectFill(rect.point, Point2F(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color ); drawRoundedRect(0.0f, rect.point, Point2F(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
} }
void GFXDrawUtil::drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color ) void GFXDrawUtil::drawRectFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{ {
drawRectFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color); drawRoundedRect(0.0f, Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, borderSize, borderColor);
} }
void GFXDrawUtil::drawRectFill( const RectI &rect, const ColorI &color ) void GFXDrawUtil::drawRectFill(const RectI& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{ {
drawRectFill(rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color ); drawRoundedRect(0.0f, rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
} }
void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color ) void GFXDrawUtil::drawRectFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, const F32& borderSize,const ColorI& borderColor)
{
// draw a rounded rect with 0 radiuse.
drawRoundedRect(0.0f, upperLeft, lowerRight, color, borderSize, borderColor);
}
void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius, const RectI& rect, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{
drawRoundedRect(cornerRadius, rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, borderSize, borderColor);
}
void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius, const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{
drawRoundedRect(cornerRadius, Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, borderSize, borderColor);
}
void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius,
const Point2F& upperLeft,
const Point2F& lowerRight,
const ColorI& color,
const F32& borderSize,
const ColorI& borderColor)
{ {
//
// Convert Box a----------x
// | |
// x----------b
// Into Quad
// v0---------v1
// | a x |
// | |
// | x b |
// v2---------v3
//
// NorthWest and NorthEast facing offset vectors // NorthWest and NorthEast facing offset vectors
Point2F nw(-0.5,-0.5); /* \ */ Point2F nw(-0.5, -0.5); /* \ */
Point2F ne(0.5,-0.5); /* / */ Point2F ne(0.5, -0.5); /* / */
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile); GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
verts.lock(); verts.lock();
F32 ulOffset = 0.5f - mDevice->getFillConventionOffset(); F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
verts[0].point.set( upperLeft.x+nw.x + ulOffset, upperLeft.y+nw.y + ulOffset, 0.0f ); verts[0].point.set(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset, 0.0f);
verts[1].point.set( lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f); verts[1].point.set(lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
verts[2].point.set( upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f); verts[2].point.set(upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
verts[3].point.set( lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f); verts[3].point.set(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
for (S32 i = 0; i < 4; i++) for (S32 i = 0; i < 4; i++)
verts[i].color = color; verts[i].color = color;
verts.unlock(); verts.unlock();
mDevice->setVertexBuffer(verts);
mDevice->setStateBlock(mRectFillSB); mDevice->setStateBlock(mRectFillSB);
mDevice->setVertexBuffer( verts );
mDevice->setupGenericShaders(); Point2F topLeftCorner(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset);
mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 ); Point2F bottomRightCorner(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset);
/*mDevice->setupGenericShaders();*/
GFX->setShader(mRoundRectangleShader);
GFX->setShaderConstBuffer(mRoundRectangleShaderConsts);
MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
Point2F size((F32)(bottomRightCorner.x - topLeftCorner.x), (F32)(bottomRightCorner.y - topLeftCorner.y));
F32 minExtent = mMin(size.x, size.y);
F32 radius = cornerRadius;
if ((minExtent * 0.5) < radius)
{
radius = mClampF(radius, 0.0f, (minExtent * 0.5));
}
mRoundRectangleShaderConsts->set(mRoundRectangleShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$radius"), radius);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$sizeUni"), size);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$borderSize"), borderSize);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$borderCol"), borderColor);
Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0)));
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$rectCenter"), rectCenter);
const Point2I& resolution = GFX->getActiveRenderTarget()->getSize();
Point2F TargetSize(1.0 / (F32)resolution.x, 1.0 / (F32)resolution.y);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$oneOverViewport"), TargetSize);
mDevice->drawPrimitive(GFXTriangleStrip, 0, 2);
} }
void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle ) void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle )
@ -608,7 +677,73 @@ void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinA
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Draw Line // Draw Circle : FILL
//-----------------------------------------------------------------------------
void GFXDrawUtil::drawCircleFill(const RectI& rect, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
{
drawCircleFill(rect.point, Point2I(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color, radius, borderSize, borderColor);
}
void GFXDrawUtil::drawCircleFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
{
drawCircleFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color, radius, borderSize, borderColor);
}
void GFXDrawUtil::drawCircleFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, F32 radius, const F32& borderSize, const ColorI& borderColor)
{
// NorthWest and NorthEast facing offset vectors
Point2F nw(-0.5, -0.5); /* \ */
Point2F ne(0.5, -0.5); /* / */
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile);
verts.lock();
F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
verts[0].point.set(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset, 0.0f);
verts[1].point.set(lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
verts[2].point.set(upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
verts[3].point.set(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
for (S32 i = 0; i < 4; i++)
verts[i].color = color;
verts.unlock();
mDevice->setVertexBuffer(verts);
mDevice->setStateBlock(mRectFillSB);
Point2F topLeftCorner(upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset);
Point2F bottomRightCorner(lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset);
/*mDevice->setupGenericShaders();*/
GFX->setShader(mCircleShader);
GFX->setShaderConstBuffer(mCircleShaderConsts);
MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
Point2F size((F32)(bottomRightCorner.x - topLeftCorner.x), (F32)(bottomRightCorner.y - topLeftCorner.y));
Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0)));
mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$rectCenter"), rectCenter);
F32 minExtent = mMin(size.x, size.y);
F32 shaderRadius = radius;
if ((minExtent * 0.5) < shaderRadius)
{
shaderRadius = mClampF(radius, 0.0f, (minExtent * 0.5));
}
mCircleShaderConsts->set(mCircleShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$radius"), shaderRadius);
mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$sizeUni"), size);
mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$borderSize"), borderSize);
mCircleShaderConsts->setSafe(mCircleShader->getShaderConstHandle("$borderCol"), borderColor);
mDevice->drawPrimitive(GFXTriangleStrip, 0, 2);
}
//-----------------------------------------------------------------------------
// Draw Lines : Single Pixel
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void GFXDrawUtil::drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color ) void GFXDrawUtil::drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color )
{ {
@ -648,6 +783,55 @@ void GFXDrawUtil::drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, cons
mDevice->drawPrimitive( GFXLineList, 0, 1 ); mDevice->drawPrimitive( GFXLineList, 0, 1 );
} }
//-----------------------------------------------------------------------------
// Draw Lines : Thick
//-----------------------------------------------------------------------------
void GFXDrawUtil::drawThickLine(const Point2I& startPt, const Point2I& endPt, const ColorI& color, const F32& thickness)
{
drawThickLine(startPt.x, startPt.y, 0.0f, endPt.x, endPt.y, 0.0f, color, thickness);
}
void GFXDrawUtil::drawThickLine(const Point2F& startPt, const Point2F& endPt, const ColorI& color, const F32& thickness)
{
drawThickLine(startPt.x, startPt.y, 0.0f, endPt.x, endPt.y, 0.0f, color, thickness);
}
void GFXDrawUtil::drawThickLine(F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI& color, const F32& thickness)
{
// less than 2 just draw an ordinary line... why you ever here....
if (thickness < 2.0f)
{
drawLine(x1, y1, z1, x2, y2, z2, color);
return;
}
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 2, GFXBufferTypeVolatile);
verts.lock();
verts[0].point.set(x1, y1, z1);
verts[1].point.set(x2, y2, z2);
verts[0].color = color;
verts[1].color = color;
verts.unlock();
mDevice->setVertexBuffer(verts);
mDevice->setStateBlock(mRectFillSB);
GFX->setShader(mThickLineShader);
GFX->setShaderConstBuffer(mThickLineShaderConsts);
MatrixF tempMatrix = GFX->getProjectionMatrix() * GFX->getViewMatrix() * GFX->getWorldMatrix();
mThickLineShaderConsts->set(mThickLineShader->getShaderConstHandle("$modelView"), tempMatrix, GFXSCT_Float4x4);
mThickLineShaderConsts->setSafe(mThickLineShader->getShaderConstHandle("$thickness"), thickness);
const Point2I& resolution = GFX->getActiveRenderTarget()->getSize();
Point2F TargetSize(1.0 / (F32)resolution.x, 1.0 / (F32)resolution.y);
mThickLineShaderConsts->setSafe(mThickLineShader->getShaderConstHandle("$oneOverViewport"), TargetSize);
mDevice->drawPrimitive(GFXLineList, 0, 1);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// 3D World Draw Misc // 3D World Draw Misc
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1110,7 +1294,7 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
Point3F cubePts[8]; Point3F cubePts[8];
for (U32 i = 0; i < 8; i++) for (U32 i = 0; i < 8; i++)
{ {
cubePts[i] = cubePoints[i]/2; cubePts[i] = cubePoints[i]/2;
} }
// 8 corner points of the box // 8 corner points of the box

View file

@ -31,12 +31,12 @@
#include "math/mPolyhedron.h" #include "math/mPolyhedron.h"
#endif #endif
class FontRenderBatcher; class FontRenderBatcher;
class Frustum; class Frustum;
/// Helper class containing utility functions for useful drawing routines /// Helper class containing utility functions for useful drawing routines
/// (line, box, rect, billboard, text). /// (line, box, rect, billboard, text).
class GFXDrawUtil class GFXDrawUtil
@ -46,22 +46,36 @@ public:
~GFXDrawUtil(); ~GFXDrawUtil();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Draw Rectangles // Draw Rectangles : OUTLINE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void drawRect( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color ); void drawRect(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color);
void drawRect( const RectF &rect, const ColorI &color ); void drawRect(const RectF& rect, const ColorI& color);
void drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color ); void drawRect(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color);
void drawRect( const RectI &rect, const ColorI &color ); void drawRect(const RectI& rect, const ColorI& color);
void drawRectFill( const Point2F &upperL, const Point2F &lowerR, const ColorI &color );
void drawRectFill( const RectF &rect, const ColorI &color );
void drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color );
void drawRectFill( const RectI &rect, const ColorI &color );
void draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle = 0.0f );
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Draw Lines // Draw Rectangles : FILL
//-----------------------------------------------------------------------------
void drawRectFill(const Point2F& upperL, const Point2F& lowerR, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRectFill(const RectF& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRectFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRectFill(const RectI& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRoundedRect(const F32& cornerRadius, const RectI& rect, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRoundedRect(const F32& cornerRadius, const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawRoundedRect(const F32& cornerRadius, const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void draw2DSquare(const Point2F& screenPoint, F32 width, F32 spinAngle = 0.0f);
//-----------------------------------------------------------------------------
// Draw Circle : FILL
//-----------------------------------------------------------------------------
void drawCircleFill(const RectI& rect, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawCircleFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
void drawCircleFill(const Point2F& upperLeft, const Point2F& lowerRight, const ColorI& color, F32 radius, const F32& borderSize = 0.0f, const ColorI& borderColor = ColorI(0, 0, 0, 0));
//-----------------------------------------------------------------------------
// Draw Lines : Single Pixel
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color ); void drawLine( const Point3F &startPt, const Point3F &endPt, const ColorI &color );
void drawLine( const Point2F &startPt, const Point2F &endPt, const ColorI &color ); void drawLine( const Point2F &startPt, const Point2F &endPt, const ColorI &color );
@ -69,6 +83,13 @@ public:
void drawLine( F32 x1, F32 y1, F32 x2, F32 y2, const ColorI &color ); void drawLine( F32 x1, F32 y1, F32 x2, F32 y2, const ColorI &color );
void drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color ); void drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color );
//-----------------------------------------------------------------------------
// Draw Lines : Thick
//-----------------------------------------------------------------------------
void drawThickLine(const Point2I& startPt, const Point2I& endPt, const ColorI& color, const F32& thickness);
void drawThickLine(const Point2F& startPt, const Point2F& endPt, const ColorI& color, const F32& thickness);
void drawThickLine(F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI& color, const F32& thickness);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Draw Text // Draw Text
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -176,6 +197,19 @@ protected:
GFXStateBlockRef mRectFillSB; GFXStateBlockRef mRectFillSB;
FontRenderBatcher* mFontRenderBatcher; FontRenderBatcher* mFontRenderBatcher;
// Expanded shaders
// rounded rectangle.
GFXShaderRef mRoundRectangleShader;
GFXShaderConstBufferRef mRoundRectangleShaderConsts;
// thick line.
GFXShaderRef mCircleShader;
GFXShaderConstBufferRef mCircleShaderConsts;
// thick line.
GFXShaderRef mThickLineShader;
GFXShaderConstBufferRef mThickLineShaderConsts;
}; };
#endif // _GFX_GFXDRAWER_H_ #endif // _GFX_GFXDRAWER_H_

View file

@ -312,7 +312,9 @@ enum GFXMatrixType
enum GFXShaderConstType enum GFXShaderConstType
{ {
GFXSCT_Uknown,
/// GFX"S"hader"C"onstant"T"ype /// GFX"S"hader"C"onstant"T"ype
GFXSCT_ConstBuffer,
// Scalar // Scalar
GFXSCT_Float, GFXSCT_Float,
// Vectors // Vectors
@ -331,6 +333,18 @@ enum GFXShaderConstType
GFXSCT_Int2, GFXSCT_Int2,
GFXSCT_Int3, GFXSCT_Int3,
GFXSCT_Int4, GFXSCT_Int4,
// Scalar
GFXSCT_UInt,
// Vectors
GFXSCT_UInt2,
GFXSCT_UInt3,
GFXSCT_UInt4,
// Scalar
GFXSCT_Bool,
// Vectors
GFXSCT_Bool2,
GFXSCT_Bool3,
GFXSCT_Bool4,
// Samplers // Samplers
GFXSCT_Sampler, GFXSCT_Sampler,
GFXSCT_SamplerCube, GFXSCT_SamplerCube,

View file

@ -59,13 +59,18 @@ bool GFXShader::init( const Torque::Path &vertFile,
} }
#endif #endif
bool GFXShader::init( const Torque::Path &vertFile, bool GFXShader::init( F32 pixVersion,
const Torque::Path &pixFile,
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 ); if(!mVertexFile.isEmpty())
Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged ); 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;
} }
@ -161,6 +168,24 @@ 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();

View file

@ -65,13 +65,28 @@ class GFXShader;
class GFXVertexFormat; 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 /// Instances of this struct are returned GFXShaderConstBuffer
struct GFXShaderConstDesc struct GFXShaderConstDesc
{ {
public: public:
String name; String name = String::EmptyString;
GFXShaderConstType constType; GFXShaderConstType constType = GFXSCT_Uknown;
U32 arraySize; // > 1 means it is an array! 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. /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
@ -234,6 +249,9 @@ protected:
/// 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;
@ -307,9 +325,7 @@ public:
#endif #endif
/// ///
bool init( const Torque::Path &vertFile, bool init( F32 pixVersion,
const Torque::Path &pixFile,
F32 pixVersion,
const Vector<GFXShaderMacro> &macros, const Vector<GFXShaderMacro> &macros,
const Vector<String> &samplerNames, const Vector<String> &samplerNames,
GFXVertexFormat *instanceFormat = NULL ); GFXVertexFormat *instanceFormat = NULL );
@ -349,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(); }

View file

@ -258,6 +258,7 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
mModelViewProjSC[i] = NULL; mModelViewProjSC[i] = NULL;
mOpenglStateCache = new GFXGLStateCache; mOpenglStateCache = new GFXGLStateCache;
mCurrentConstBuffer = NULL;
} }
GFXGLDevice::~GFXGLDevice() GFXGLDevice::~GFXGLDevice()
@ -291,6 +292,11 @@ GFXGLDevice::~GFXGLDevice()
mTextureManager->kill(); mTextureManager->kill();
} }
// Free device buffers
DeviceBufferMap::Iterator bufferIter = mDeviceBufferMap.begin();
for (; bufferIter != mDeviceBufferMap.end(); ++bufferIter)
glDeleteBuffers(1, &bufferIter->value);
GFXResource* walk = mResourceListHead; GFXResource* walk = mResourceListHead;
while(walk) while(walk)
{ {
@ -306,6 +312,23 @@ GFXGLDevice::~GFXGLDevice()
SAFE_DELETE( mOpenglStateCache ); SAFE_DELETE( mOpenglStateCache );
} }
GLuint GFXGLDevice::getDeviceBuffer(const GFXShaderConstDesc desc)
{
String name(desc.name + "_" + String::ToString(desc.size));
DeviceBufferMap::Iterator buf = mDeviceBufferMap.find(name);
if (buf != mDeviceBufferMap.end())
{
return mDeviceBufferMap[name];
}
GLuint uboHandle;
glGenBuffers(1, &uboHandle);
mDeviceBufferMap[name] = uboHandle;
return uboHandle;
}
void GFXGLDevice::zombify() void GFXGLDevice::zombify()
{ {
mTextureManager->zombify(); mTextureManager->zombify();
@ -959,8 +982,19 @@ void GFXGLDevice::setShader(GFXShader *shader, bool force)
void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
{ {
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal); if (buffer)
static_cast<GFXGLShaderConstBuffer*>(buffer)->activate(); {
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal);
AssertFatal(static_cast<GFXGLShaderConstBuffer*>(buffer), "Incorrect shader const buffer type for this device!");
GFXGLShaderConstBuffer* oglBuffer = static_cast<GFXGLShaderConstBuffer*>(buffer);
oglBuffer->activate(mCurrentConstBuffer);
mCurrentConstBuffer = oglBuffer;
}
else
{
mCurrentConstBuffer = NULL;
}
} }
U32 GFXGLDevice::getNumSamplers() const U32 GFXGLDevice::getNumSamplers() const

View file

@ -43,9 +43,11 @@ class GFXGLCubemap;
class GFXGLCubemapArray; class GFXGLCubemapArray;
class GFXGLStateCache; class GFXGLStateCache;
class GFXGLVertexDecl; class GFXGLVertexDecl;
class GFXGLShaderConstBuffer;
class GFXGLDevice : public GFXDevice class GFXGLDevice : public GFXDevice
{ {
public: public:
struct GLCapabilities struct GLCapabilities
{ {
@ -59,6 +61,11 @@ public:
}; };
GLCapabilities mCapabilities; GLCapabilities mCapabilities;
// UBO map
typedef Map<String, GLuint> DeviceBufferMap;
// grab device buffer.
GLuint getDeviceBuffer(const GFXShaderConstDesc desc);
void zombify(); void zombify();
void resurrect(); void resurrect();
GFXGLDevice(U32 adapterIndex); GFXGLDevice(U32 adapterIndex);
@ -200,6 +207,8 @@ protected:
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ); virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
virtual void setVertexStreamFrequency( U32 stream, U32 frequency ); virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
StrongRefPtr<GFXGLShaderConstBuffer> mCurrentConstBuffer;
DeviceBufferMap mDeviceBufferMap;
private: private:
typedef GFXDevice Parent; typedef GFXDevice Parent;

File diff suppressed because it is too large Load diff

View file

@ -29,95 +29,95 @@
#include "core/util/tSignal.h" #include "core/util/tSignal.h"
#include "core/util/tDictionary.h" #include "core/util/tDictionary.h"
class GFXGLShaderConstHandle;
class FileStream; class FileStream;
class GFXGLShaderConstBuffer;
class GFXGLDevice; class GFXGLDevice;
class GFXGLShader;
class GFXGLShader : public GFXShader struct BufferRange
{ {
typedef Map<String, GFXGLShaderConstHandle*> HandleMap; U32 mBufMin = U32_MAX;
U32 mBufMax = 0;
inline void addSlot(U32 slot)
{
mBufMin = getMin(mBufMin, slot);
mBufMax = getMax(mBufMax, slot);
}
inline bool isValid() const { return mBufMin <= mBufMax; }
};
struct ConstantBuffer
{
GLuint bufHandle;
U8* data;
U32 size;
bool isDirty;
};
class GFXGLShaderConstHandle : public GFXShaderConstHandle
{
friend class GFXGLShader;
public: public:
GFXGLShader(GFXGLDevice* device); // DX side needs the description map as the same uniform can exist across stages. for gl it is program wide.
virtual ~GFXGLShader(); GFXGLShaderConstHandle(GFXGLShader* shader);
GFXGLShaderConstHandle(GFXGLShader* shader,
const GFXShaderConstDesc& desc);
/// @name GFXShader interface void reinit(const GFXShaderConstDesc& desc);
/// @{
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
/// Returns our list of shader constants, the material can get this and just set the constants it knows about virtual ~GFXGLShaderConstHandle();
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const; const GFXShaderConstDesc getDesc();
const String& getName() const { return mDesc.name; }
GFXShaderConstType getType() const { return mDesc.constType; }
U32 getArraySize() const { return mDesc.arraySize; }
/// Returns the alignment value for constType U32 getSize() const { return mDesc.size; }
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const; void setValid(bool valid) { mValid = valid; }
/// @warning This will always return the value assigned when the shader was
/// initialized. If the value is later changed this method won't reflect that.
S32 getSamplerRegister() const { return (!isSampler() || !mValid) ? -1 : mDesc.samplerReg; }
virtual GFXShaderConstBufferRef allocConstBuffer(); // Returns true if this is a handle to a sampler register.
bool isSampler() const
{
return (getType() >= GFXSCT_Sampler);
}
/// @} /// Restore to uninitialized state.
void clear()
{
mShader = NULL;
mInstancingConstant = false;
mValid = false;
}
/// @name GFXResource interface GFXShaderConstDesc mDesc;
/// @{ GFXGLShader* mShader;
virtual void zombify(); bool mUBOUniform;
virtual void resurrect() { reload(); } bool mInstancingConstant;
virtual const String describeSelf() const;
/// @}
/// Activates this shader in the GL context.
void useProgram();
protected:
friend class GFXGLShaderConstBuffer;
friend class GFXGLShaderConstHandle;
virtual bool _init();
bool initShader( const Torque::Path &file,
bool isVertex,
const Vector<GFXShaderMacro> &macros );
void clearShaders();
void initConstantDescs();
void initHandles();
void setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer);
static char* _handleIncludes( const Torque::Path &path, FileStream *s );
static bool _loadShaderFromStream( GLuint shader,
const Torque::Path& path,
FileStream* s,
const Vector<GFXShaderMacro>& macros );
/// @name Internal GL handles
/// @{
GLuint mVertexShader;
GLuint mPixelShader;
GLuint mProgram;
/// @}
Vector<GFXShaderConstDesc> mConstants;
U32 mConstBufferSize;
U8* mConstBuffer;
HandleMap mHandles;
GFXGLDevice* mDevice;
Vector<GFXGLShaderConstHandle*> mValidHandles;
}; };
class GFXGLShaderConstBuffer : public GFXShaderConstBuffer class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
{ {
public: public:
GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants); // -1 is the global buffer.
typedef Map<S32, ConstantBuffer> BufferMap;
GFXGLShaderConstBuffer(GFXGLShader* shader);
~GFXGLShaderConstBuffer(); ~GFXGLShaderConstBuffer();
/// Called by GFXGLDevice to activate this buffer. /// Called by GFXGLDevice to activate this buffer.
void activate(); void activate(GFXGLShaderConstBuffer* prevShaderBuffer);
void addBuffer(const GFXShaderConstDesc desc);
/// Called when the shader this buffer references is reloaded. /// Called when the shader this buffer references is reloaded.
void onShaderReload( GFXGLShader *shader ); void onShaderReload(GFXGLShader* shader);
// GFXShaderConstBuffer // GFXShaderConstBuffer
virtual GFXShader* getShader() { return mShader; } virtual GFXShader* getShader();
virtual void set(GFXShaderConstHandle* handle, const F32 fv); virtual void set(GFXShaderConstHandle* handle, const F32 fv);
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv); virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv); virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
@ -147,8 +147,9 @@ public:
private: private:
friend class GFXGLShader; friend class GFXGLShader;
U8* mBuffer;
WeakRefPtr<GFXGLShader> mShader; WeakRefPtr<GFXGLShader> mShader;
BufferMap mBufferMap;
template<typename ConstType> template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const ConstType& param); void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
@ -157,4 +158,80 @@ private:
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv); void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
}; };
class GFXGLShader : public GFXShader
{
friend class GFXGLShaderConstBuffer;
friend class GFXGLShaderConstHandle;
public:
typedef Map<String, GFXGLShaderConstHandle*> HandleMap;
typedef Map<String, GFXShaderConstDesc> BufferMap;
GFXGLShader(GFXGLDevice* device);
virtual ~GFXGLShader();
/// @name GFXShader interface
/// @{
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
/// 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;
/// Returns the alignment value for constType
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual GFXShaderConstBufferRef allocConstBuffer();
/// @}
/// @name GFXResource interface
/// @{
virtual void zombify();
virtual void resurrect() { reload(); }
virtual const String describeSelf() const;
/// @}
/// Activates this shader in the GL context.
void useProgram();
protected:
virtual bool _init();
bool initShader(const Torque::Path& file,
GFXShaderStage stage,
const Vector<GFXShaderMacro>& macros);
void clearShaders();
void initConstantDescs();
void initHandles();
void setConstantsFromBuffer(U8* buffer);
static char* _handleIncludes(const Torque::Path& path, FileStream* s);
static bool _loadShaderFromStream(GLuint shader,
const Torque::Path& path,
FileStream* s,
const Vector<GFXShaderMacro>& macros);
/// @name Internal GL handles
/// @{
GLuint mVertexShader;
GLuint mPixelShader;
GLuint mGeometryShader;
GLuint mProgram;
/// @}
U8* mGlobalConstBuffer;
Vector<GFXShaderConstDesc> mShaderConsts;
HandleMap mHandles;
BufferMap mBuffers;
GFXGLDevice* mDevice;
GFXShaderConstType convertConstType(GLenum constType);
};
#endif // _GFXGLSHADER_H_ #endif // _GFXGLSHADER_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,147 @@
//-----------------------------------------------------------------------------
// 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 _GUISHADEREDITOR_H_
#define _GUISHADEREDITOR_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
#ifndef _UNDO_H_
#include "util/undo.h"
#endif
#ifndef _GFX_GFXDRAWER_H_
#include "gfx/gfxDrawUtil.h"
#endif
#ifndef _SHADERNODE_H_
#include "gui/shaderEditor/guiShaderNode.h"
#endif // !_SHADERNODE_H_
struct NodeConnection
{
// keep track of the nodes hit.
GuiShaderNode* nodeA = NULL;
GuiShaderNode* nodeB = NULL;
// keep track of the sockets.
NodeInput* inSocket = NULL;
NodeOutput* outSocket = NULL;
};
class GuiShaderEditor : public GuiControl
{
public:
typedef GuiControl Parent;
enum mouseModes { Selecting, MovingSelection, DragPanning, DragConnection, DragSelecting, DragClone };
protected:
// list
typedef Vector<GuiShaderNode*> ShaderNodeVector;
typedef Vector<NodeConnection*> ShderNodeConnections;
// all nodes in this graph.
ShaderNodeVector mCurrNodes;
ShderNodeConnections mCurrConnections;
NodeConnection* mTempConnection;
// Undo
SimGroup* mTrash;
// view controls
Point2I mViewOffset;
F32 mZoomScale;
// mouse interaction
mouseModes mMouseDownMode;
Point2I mLastMousePos;
Point2I mLastDragPos;
Point2I mSelectionAnchor;
Point2I mDragBeginPoint;
Vector<Point2I> mDragBeginPoints;
bool mDragAddSelection;
bool mDragMoveUndo;
bool mFullBoxSelection;
S32 mNodeSize;
ShaderNodeVector mSelectedNodes;
void renderNodes(Point2I offset, const RectI& updateRect);
void renderConnections(Point2I offset, const RectI& updateRect);
// functions for handling mouse events.
GuiShaderNode* findHitNode(const Point2I& pt);
bool findHitSocket(const Point2I& pt);
U32 finishConnection(const Point2I& pt);
bool hasConnection(NodeSocket* inSocket);
bool hasConnection(NodeSocket* inSocket, Vector<NodeConnection*>& conn);
bool hasConnection(NodeSocket* inSocket, NodeConnection*& conn);
void findNodesInRect(const RectI& rect, Vector<GuiShaderNode*>& outResult);
void getDragRect(RectI& box);
void startDragMove(const Point2I& startPoint);
void startDragRectangle(const Point2I& startPoint);
void startDragClone(const Point2I& startPoint);
void setMouseMode(mouseModes mode);
void addNode(GuiShaderNode* newNode);
public:
GuiShaderEditor();
DECLARE_CONOBJECT(GuiShaderEditor);
DECLARE_CATEGORY("Shader Editor");
DECLARE_DESCRIPTION("Implements a shader node based editor.");
bool onWake();
void onSleep();
static void initPersistFields();
virtual bool onAdd() override;
virtual void onRemove() override;
virtual void onPreRender() override;
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;
// interaction
virtual bool onKeyDown(const GuiEvent& event) override;
virtual void onMouseDown(const GuiEvent& event) override;
virtual void onMouseUp(const GuiEvent& event) override;
virtual void onMouseDragged(const GuiEvent& event) override;
virtual void onMiddleMouseDown(const GuiEvent& event) override;
virtual void onMiddleMouseUp(const GuiEvent& event) override;
virtual void onMiddleMouseDragged(const GuiEvent& event) override;
virtual bool onMouseWheelUp(const GuiEvent& event) override;
virtual bool onMouseWheelDown(const GuiEvent& event) override;
RectI getSelectionBounds();
void deleteSelection();
void moveSelection(const Point2I& delta, bool callback = true);
void clearSelection();
void cloneSelection();
void addSelectionAtPoint(const Point2I& pos);
void addSelection(GuiShaderNode* inNode);
bool selectionContains(GuiShaderNode* inNode);
void removeSelection(GuiShaderNode* inNode);
void canHitSelectedNodes(bool state = true);
};
#endif _GUISHADEREDITOR_H_

View file

@ -0,0 +1,203 @@
//-----------------------------------------------------------------------------
// 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 "gui/shaderEditor/guiShaderNode.h"
#include "gui/core/guiCanvas.h"
IMPLEMENT_CONOBJECT(GuiShaderNode);
ConsoleDocClass(GuiShaderNode,
"@brief Base class for all nodes to derive from.\n\n"
"Editor use only.\n\n"
"@internal"
);
GuiShaderNode::GuiShaderNode()
{
VECTOR_SET_ASSOCIATION(mInputNodes);
VECTOR_SET_ASSOCIATION(mOutputNodes);
mTitle = "Default Node";
mSelected = false;
mNodeType = NodeTypes::Default;
GuiControlProfile* profile = NULL;
if (Sim::findObject("GuiShaderEditorProfile", profile))
setControlProfile(profile);
// fixed extent for all nodes, only height should be changed
setExtent(180, 35);
mPrevNodeSize = -1;
}
bool GuiShaderNode::onWake()
{
if (!Parent::onWake())
return false;
return true;
}
void GuiShaderNode::onSleep()
{
Parent::onSleep();
}
void GuiShaderNode::initPersistFields()
{
docsURL;
Parent::initPersistFields();
}
bool GuiShaderNode::onAdd()
{
if (!Parent::onAdd())
return false;
return true;
}
void GuiShaderNode::onRemove()
{
Parent::onRemove();
}
void GuiShaderNode::renderNode(Point2I offset, const RectI& updateRect, const S32 nodeSize)
{
if (!mProfile)
return Parent::onRender(offset, updateRect);
GFXDrawUtil* drawer = GFX->getDrawUtil();
// draw background.
// Get our rect.
RectI winRect;
winRect.point = offset;
winRect.extent = getExtent();
ColorI border = mProfile->mBorderColor;
if (mSelected)
border = mProfile->mBorderColorSEL;
drawer->drawRoundedRect(15.0f, winRect, mProfile->mFillColor, 5.0f, border);
// draw header
ColorI header(50, 50, 50, 128);
switch (mNodeType)
{
case NodeTypes::Default:
header = ColorI(128, 50, 128, 128);
break;
case NodeTypes::Uniform:
header = ColorI(50, 100, 128, 128);
break;
case NodeTypes::Input:
header = ColorI(128, 100, 50, 128);
break;
case NodeTypes::Output:
header = ColorI(50, 100, 50, 128);
break;
case NodeTypes::TextureSampler:
header = ColorI(50, 50, 128, 128);
break;
case NodeTypes::MathOperation:
header = ColorI(128, 0, 128, 128);
break;
case NodeTypes::Procedural:
header = ColorI(128, 100, 0, 128);
break;
case NodeTypes::Generator:
header = ColorI(0, 100, 128, 128);
break;
default:
header = ColorI(128, 0, 0, 128);
break;
}
RectI headRect;
U32 headerSize = 30;
headRect.point = offset;
headRect.extent = Point2I(getExtent().x, headerSize);
drawer->drawRoundedRect(15.0f, headRect, header);
// draw header text.
U32 strWidth = mProfile->mFont->getStrWidth(mTitle.c_str());
Point2I headerPos = Point2I((getExtent().x / 2) - (strWidth / 2), (headerSize / 2) - (mProfile->mFont->getFontSize() / 2));
drawer->setBitmapModulation(mProfile->mFontColor);
drawer->drawText(mProfile->mFont, headerPos + offset, mTitle);
drawer->clearBitmapModulation();
if (mInputNodes.size() > 0 || mOutputNodes.size() > 0)
{
U32 textPadX = nodeSize, textPadY = mProfile->mFont->getFontSize() + (nodeSize / 2);
Point2I slotPos(textPadX, headerSize + (nodeSize / 2));
drawer->setBitmapModulation(mProfile->mFontColor);
for (NodeInput* input : mInputNodes)
{
drawer->drawText(mProfile->mFont, slotPos + offset, input->name);
if (input->pos == Point2I::Zero || mPrevNodeSize != nodeSize)
input->pos = Point2I(-(nodeSize / 2) + 1, slotPos.y + ((mProfile->mFont->getFontSize() / 2) - (nodeSize / 2)));
slotPos.y += textPadY;
}
U32 inputY = slotPos.y;
slotPos = Point2I(getExtent().x, headerSize + (nodeSize / 2));
for (NodeOutput* output : mOutputNodes)
{
strWidth = mProfile->mFont->getStrWidth(output->name.c_str());
slotPos.x = getExtent().x - strWidth - textPadX;
drawer->drawText(mProfile->mFont, slotPos + offset, output->name);
if (output->pos == Point2I::Zero || mPrevNodeSize != nodeSize)
output->pos = Point2I(getExtent().x - (nodeSize / 2) - 1 , slotPos.y + ((mProfile->mFont->getFontSize() / 2) - (nodeSize / 2)));
slotPos.y += textPadY;
}
drawer->clearBitmapModulation();
U32 outputY = slotPos.y;
if (getExtent().y < slotPos.y || mPrevNodeSize != nodeSize)
setExtent(Point2I(getExtent().x, mMax(inputY, outputY)));
mPrevNodeSize = nodeSize;
}
}
void GuiShaderNode::write(Stream& stream, U32 tabStop, U32 flags)
{
}
void GuiShaderNode::read(Stream& stream)
{
}

View file

@ -0,0 +1,159 @@
//-----------------------------------------------------------------------------
// 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 _SHADERNODE_H_
#define _SHADERNODE_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
#ifndef _SIMBASE_H_
#include "console/simBase.h"
#endif
#ifndef _GFX_GFXDRAWER_H_
#include "gfx/gfxDrawUtil.h"
#endif
enum class NodeTypes
{
Default,
Uniform,
Input,
Output,
TextureSampler,
MathOperation,
Procedural,
Generator
};
enum class DataDimensions
{
Dynamic, // can be any dimension, usually defined by what was connected to it.
Scalar,
Vector2,
Vector3,
Vector4,
Mat4x4,
};
// parent class for sockets detection in shaderEditor.
struct NodeSocket
{
String name;
DataDimensions dimensions;
ColorI col = ColorI::WHITE;
NodeSocket()
:name(String::EmptyString), dimensions(DataDimensions::Dynamic)
{}
NodeSocket(String inName, DataDimensions inDim)
:name(inName), dimensions(inDim)
{
switch (inDim)
{
case DataDimensions::Dynamic:
col = ColorI(200, 200, 200, 128);
break;
case DataDimensions::Scalar:
col = ColorI(210, 105, 30, 128);
break;
case DataDimensions::Vector2:
col = ColorI(152, 251,152, 128);
break;
case DataDimensions::Vector3:
col = ColorI(127, 255, 212, 128);
break;
case DataDimensions::Vector4:
col = ColorI(100, 149, 237, 128);
break;
case DataDimensions::Mat4x4:
col = ColorI(153, 50, 204, 128);
break;
default:
break;
}
}
public:
virtual ~NodeSocket() {}
};
struct NodeInput : NodeSocket
{
Point2I pos = Point2I::Zero;
NodeInput()
:NodeSocket()
{}
NodeInput(String inName , DataDimensions inDim)
:NodeSocket(inName , inDim)
{}
};
struct NodeOutput : NodeSocket
{
Point2I pos = Point2I::Zero;
NodeOutput()
:NodeSocket()
{}
NodeOutput(String inName, DataDimensions inDim)
:NodeSocket(inName, inDim)
{}
};
class GuiShaderNode : public GuiControl
{
private:
typedef GuiControl Parent;
protected:
String mTitle;
NodeTypes mNodeType;
S32 mPrevNodeSize;
public:
Vector<NodeInput*> mInputNodes;
Vector<NodeOutput*> mOutputNodes;
GuiShaderNode();
bool onWake();
void onSleep();
static void initPersistFields();
virtual bool onAdd() override;
virtual void onRemove() override;
void renderNode(Point2I offset, const RectI& updateRect, const S32 nodeSize);
// Serialization functions
void write(Stream& stream, U32 tabStop = 0, U32 flags = 0);
void read(Stream& stream);
// is the parent that all other nodes are derived from.
DECLARE_CONOBJECT(GuiShaderNode);
DECLARE_CATEGORY("Shader Core");
DECLARE_DESCRIPTION("Base class for all shader nodes.");
bool mSelected;
};
#endif // !_SHADERNODE_H_

View file

@ -0,0 +1,51 @@
//-----------------------------------------------------------------------------
// 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 "gui/shaderEditor/nodes/materialOutputNode.h"
//-----------------------------------------------------------------
// BRDF Output Node.
//-----------------------------------------------------------------
IMPLEMENT_CONOBJECT(BRDFOutputNode);
ConsoleDocClass(BRDFOutputNode,
"@brief Deferred Material output.\n\n"
"Editor use only.\n\n"
"@internal"
);
BRDFOutputNode::BRDFOutputNode()
: GuiShaderNode()
{
mNodeType = NodeTypes::Output;
mInputNodes.push_back(new NodeInput("Albedo", DataDimensions::Vector3));
mInputNodes.push_back(new NodeInput("Normal", DataDimensions::Vector3));
mInputNodes.push_back(new NodeInput("Ambient Occlusion", DataDimensions::Scalar));
mInputNodes.push_back(new NodeInput("Metallic", DataDimensions::Scalar));
mInputNodes.push_back(new NodeInput("Roughness", DataDimensions::Scalar));
mInputNodes.push_back(new NodeInput("Emissive Color", DataDimensions::Vector3));
mInputNodes.push_back(new NodeInput("Opacity", DataDimensions::Scalar));
mTitle = "Standard BRDF";
}

View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// 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 "gui/shaderEditor/guiShaderNode.h"
//-----------------------------------------------------------------
// Put all material output nodes here.
//-----------------------------------------------------------------
class BRDFOutputNode : public GuiShaderNode
{
typedef GuiShaderNode Parent;
public:
BRDFOutputNode();
// is the parent that all other nodes are derived from.
DECLARE_CONOBJECT(BRDFOutputNode);
DECLARE_CATEGORY("Shader Output");
DECLARE_DESCRIPTION("Deferred Material output.");
};

View file

@ -0,0 +1,49 @@
//-----------------------------------------------------------------------------
// 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 "gui/shaderEditor/nodes/mathNode.h"
//-----------------------------------------------------------------
// Math addition Node.
//-----------------------------------------------------------------
IMPLEMENT_CONOBJECT(MathAddNode);
ConsoleDocClass(MathAddNode,
"@brief Math addition node.\n\n"
"Editor use only.\n\n"
"@internal"
);
MathAddNode::MathAddNode()
: GuiShaderNode()
{
mNodeType = NodeTypes::MathOperation;
mInputNodes.push_back(new NodeInput("A", DataDimensions::Dynamic));
mInputNodes.push_back(new NodeInput("B", DataDimensions::Dynamic));
mOutputNodes.push_back(new NodeOutput("Result", DataDimensions::Dynamic));
mTitle = "Math Node";
}

View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// 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 "gui/shaderEditor/guiShaderNode.h"
//-----------------------------------------------------------------
// Put all Math nodes here.
//-----------------------------------------------------------------
class MathAddNode : public GuiShaderNode
{
typedef GuiShaderNode Parent;
public:
MathAddNode();
// is the parent that all other nodes are derived from.
DECLARE_CONOBJECT(MathAddNode);
DECLARE_CATEGORY("Shader Math");
DECLARE_DESCRIPTION("Math addition node.");
};

View file

@ -35,7 +35,6 @@
#include "materials/materialParameters.h" #include "materials/materialParameters.h"
#include "gfx/sim/gfxStateBlockData.h" #include "gfx/sim/gfxStateBlockData.h"
#include "core/util/safeDelete.h" #include "core/util/safeDelete.h"
#include "gfx/genericConstBuffer.h"
#include "console/simFieldDictionary.h" #include "console/simFieldDictionary.h"
#include "console/propertyParsing.h" #include "console/propertyParsing.h"
#include "gfx/util/screenspace.h" #include "gfx/util/screenspace.h"

View file

@ -26,7 +26,6 @@
#include "core/util/safeDelete.h" #include "core/util/safeDelete.h"
#include "gfx/sim/cubemapData.h" #include "gfx/sim/cubemapData.h"
#include "gfx/gfxShader.h" #include "gfx/gfxShader.h"
#include "gfx/genericConstBuffer.h"
#include "gfx/gfxPrimitiveBuffer.h" #include "gfx/gfxPrimitiveBuffer.h"
#include "scene/sceneRenderState.h" #include "scene/sceneRenderState.h"
#include "shaderGen/shaderFeature.h" #include "shaderGen/shaderFeature.h"

View file

@ -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" " DXVertexShaderFile = $Core::CommonShaderPath @ \"/cloudLayerV.hlsl\";\n"
" DXPixelShaderFile = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n" " DXPixelShaderFile = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n"
" OGLVertexShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerV.glsl\";\n" " DXGeometryShaderFile = $Core::CommonShaderPath @ \"/cloudLayerG.hlsl\";\n"
" OGLPixelShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerP.glsl\";\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), addField("DXVertexShaderFile", TypeStringFilename, Offset(mDXVertexShaderName, ShaderData),
"@brief %Path to the DirectX vertex shader file to use for this ShaderData.\n\n" "@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 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 " "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."); "filename extension of .hlsl, otherwise its assumed to be an assembly file.");
addField("DXPixelShaderFile", TypeStringFilename, Offset(mDXPixelShaderName, ShaderData), addField("DXPixelShaderFile", TypeStringFilename, Offset(mDXPixelShaderName, ShaderData),
"@brief %Path to the DirectX pixel shader file to use for this ShaderData.\n\n" "@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 " "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 " "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."); "must have a filename extension of .hlsl, otherwise its assumed to be an assembly file.");
addField("OGLVertexShaderFile", TypeStringFilename, Offset(mOGLVertexShaderName, ShaderData), addField("DXGeometryShaderFile", TypeStringFilename, Offset(mDXGeometryShaderName, ShaderData),
"@brief %Path to an OpenGL vertex shader file to use for this ShaderData.\n\n" "@brief %Path to the DirectX geometry 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("OGLPixelShaderFile", TypeStringFilename, Offset(mOGLPixelShaderName, ShaderData), addField("OGLVertexShaderFile", TypeStringFilename, Offset(mOGLVertexShaderName, ShaderData),
"@brief %Path to an OpenGL pixel shader file to use for this ShaderData.\n\n" "@brief %Path to an OpenGL vertex shader file to use for this ShaderData.\n\n"
"It must contain only one program and no vertex shader, just the pixel " "It must contain only one program and no pixel shader, just the vertex shader.");
"shader.");
addField("useDevicePixVersion", TypeBool, Offset(mUseDevicePixVersion, ShaderData), addField("OGLPixelShaderFile", TypeStringFilename, Offset(mOGLPixelShaderName, ShaderData),
"@brief If true, the maximum pixel shader version offered by the graphics card will be used.\n\n" "@brief %Path to an OpenGL pixel shader file to use for this ShaderData.\n\n"
"Otherwise, the script-defined pixel shader version will be used.\n\n"); "It must contain only one program and no vertex shader, just the pixel "
"shader.");
addField("pixVersion", TypeF32, Offset(mPixVersion, ShaderData), addField("OGLGeometryShaderFile", TypeStringFilename, Offset(mOGLGeometryShaderName, ShaderData),
"@brief Indicates target level the shader should be compiled.\n\n" "@brief %Path to the OpenGL Geometry shader file to use for this ShaderData.\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), addField("useDevicePixVersion", TypeBool, Offset(mUseDevicePixVersion, ShaderData),
"@brief String of case-sensitive defines passed to the shader compiler.\n\n" "@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" "singleton ShaderData( FlashShader )\n"
"{\n" "{\n"
"DXVertexShaderFile = $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n" "DXVertexShaderFile = $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n"
"DXPixelShaderFile = $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n" "DXPixelShaderFile = $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n"
" //Define setting the color of WHITE_COLOR.\n" "DXGeometryShaderFile = $shaderGen::cachePath @ \"/postFx/flashG.hlsl\";\n\n"
"defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n" " //Define setting the color of WHITE_COLOR.\n"
"pixVersion = 2.0\n" "defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\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()
@ -237,9 +256,13 @@ GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
{ {
case Direct3D11: case Direct3D11:
{ {
success = shader->init( mDXVertexShaderName, if (mDXVertexShaderName != String::EmptyString)
mDXPixelShaderName, shader->setShaderStageFile(GFXShaderStage::VERTEX_SHADER, mDXVertexShaderName);
pixver, 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,9 +270,14 @@ GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
case OpenGL: case OpenGL:
{ {
success = shader->init( mOGLVertexShaderName, if(mOGLVertexShaderName != String::EmptyString)
mOGLPixelShaderName, shader->setShaderStageFile(GFXShaderStage::VERTEX_SHADER, mOGLVertexShaderName);
pixver, 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;

View file

@ -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.
@ -82,14 +82,14 @@ protected:
/// 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, void _stringizeMacros(const Vector<GFXShaderMacro>& macros,
String *outString ); 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
{ {
@ -99,21 +99,21 @@ protected:
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();

View file

@ -77,8 +77,8 @@ namespace CPUInfo {
return CONFIG_SingleCoreAndHTNotCapable; return CONFIG_SingleCoreAndHTNotCapable;
} }
#pragma push #pragma warning( push )
#pragma warning (disable: 6011) #pragma warning( disable: 6011 )
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
DWORD byteOffset = 0; DWORD byteOffset = 0;
@ -95,7 +95,7 @@ namespace CPUInfo {
} }
free( buffer ); free( buffer );
#pragma pop #pragma warning( pop )
EConfig StatusFlag = CONFIG_SingleCoreAndHTNotCapable; EConfig StatusFlag = CONFIG_SingleCoreAndHTNotCapable;

View file

@ -71,7 +71,7 @@ struct SceneBinRange
inline bool isGlobal() const inline bool isGlobal() const
{ {
return minCoord[0] == 0 && return minCoord[0] == 0 &&
minCoord[0] == 0 && minCoord[1] == 0 &&
maxCoord[0] == 0xFFFF && maxCoord[0] == 0xFFFF &&
maxCoord[1] == 0xFFFF; maxCoord[1] == 0xFFFF;
} }

View file

@ -122,13 +122,13 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
if (fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit]) if (fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit])
return; return;
MultiLine* meta = new MultiLine; MultiLine* newMeta = new MultiLine;
// Now the wsPosition and wsView. // Now the wsPosition and wsView.
Var* worldToTangent = getInWorldToTangent(componentList); Var* worldToTangent = getInWorldToTangent(componentList);
Var* wsNormal = getInWorldNormal(componentList); Var* wsNormal = getInWorldNormal(componentList);
Var* wsPosition = getInWsPosition(componentList); Var* wsPosition = getInWsPosition(componentList);
Var* wsView = getWsView(wsPosition, meta); Var* wsView = getWsView(wsPosition, newMeta);
//Reflection Probe WIP //Reflection Probe WIP
U32 MAX_FORWARD_PROBES = 4; U32 MAX_FORWARD_PROBES = 4;
@ -153,32 +153,32 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
Var* showAttenVar = new Var("showAttenVar", "int"); Var* showAttenVar = new Var("showAttenVar", "int");
char buf[64]; char buf[64];
dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showAtten); dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showAtten);
meta->addStatement(new GenOp(buf, new DecOp(showAttenVar))); newMeta->addStatement(new GenOp(buf, new DecOp(showAttenVar)));
Var* showContribVar = new Var("showContribVar", "int"); Var* showContribVar = new Var("showContribVar", "int");
dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showContrib); dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showContrib);
meta->addStatement(new GenOp(buf, new DecOp(showContribVar))); newMeta->addStatement(new GenOp(buf, new DecOp(showContribVar)));
Var* showSpecVar = new Var("showSpecVar", "int"); Var* showSpecVar = new Var("showSpecVar", "int");
dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showSpec); dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showSpec);
meta->addStatement(new GenOp(buf, new DecOp(showSpecVar))); newMeta->addStatement(new GenOp(buf, new DecOp(showSpecVar)));
Var* showDiffVar = new Var("showDiffVar", "int"); Var* showDiffVar = new Var("showDiffVar", "int");
dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showDiff); dSprintf(buf, sizeof(buf), " @ = %s;\r\n", showDiff);
meta->addStatement(new GenOp(buf, new DecOp(showDiffVar))); newMeta->addStatement(new GenOp(buf, new DecOp(showDiffVar)));
String computeForwardProbes = String(" @ = debugVizForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t"); String computeForwardProbes = String(" @ = debugVizForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t"); computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t");
computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@), @, @, @, @).rgb; \r\n"); computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@), @, @, @, @).rgb; \r\n");
meta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, newMeta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
skylightCubemapIdx, BRDFTexture, skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR, irradianceCubemapAR, specularCubemapAR,
showAttenVar, showContribVar, showSpecVar, showDiffVar)); showAttenVar, showContribVar, showSpecVar, showDiffVar));
meta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", color, ibl)); newMeta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", color, ibl));
output = meta; output = newMeta;
return; return;
} }
} }

View file

@ -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;

View file

@ -150,3 +150,41 @@ singleton ShaderData( CubemapSaveShader )
pixVersion = 3.0; pixVersion = 3.0;
}; };
//-----------------------------------------------------------------------------
// GUI shaders
//-----------------------------------------------------------------------------
singleton ShaderData( RoundedRectangleGUI )
{
DXVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
DXPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/roundedRectangleP.hlsl";
OGLVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/colorV.glsl";
OGLPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/roundedRectangleP.glsl";
pixVersion = 3.0;
};
singleton ShaderData( CircularGUI )
{
DXVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
DXPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/circleP.hlsl";
OGLVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/colorV.glsl";
OGLPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/circleP.glsl";
pixVersion = 3.0;
};
singleton ShaderData( ThickLineGUI )
{
DXVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/colorV.hlsl";
DXGeometryShaderFile = $Core::CommonShaderPath @ "/fixedFunction/thickLineG.hlsl";
DXPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/thickLineP.hlsl";
OGLVertexShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/colorV.glsl";
OGLGeometryShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/thickLineG.glsl";
OGLPixelShaderFile = $Core::CommonShaderPath @ "/fixedFunction/gl/thickLineP.glsl";
pixVersion = 3.0;
};

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.
//-----------------------------------------------------------------------------
#include "../shaderModel.hlsl"
struct Conn
{
float4 HPOS : TORQUE_POSITION;
float4 color : COLOR;
};
uniform float2 sizeUni;
uniform float radius;
uniform float2 rectCenter;
uniform float borderSize;
uniform float4 borderCol;
float circle(float2 p, float2 center, float r)
{
return length(p - center);
}
float4 main(Conn IN) : TORQUE_TARGET0
{
float distance = circle(IN.HPOS.xy, rectCenter, radius);
float4 fromColor = borderCol;
float4 toColor = float4(0.0, 0.0, 0.0, 0.0);
if(distance < radius)
{
distance = abs(distance) - radius;
if(distance < (radius - (borderSize)))
{
toColor = IN.color;
distance = abs(distance) - (borderSize);
}
float blend = smoothstep(0.0, 1.0, distance);
return lerp(fromColor, toColor, blend);
}
distance = abs(distance) - radius;
float blend = smoothstep(0.0, 1.0, distance);
return lerp(fromColor, toColor, blend);
}

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.
//-----------------------------------------------------------------------------
in vec4 color;
out vec4 OUT_col;
uniform vec2 sizeUni;
uniform float radius;
uniform vec2 rectCenter;
uniform float borderSize;
uniform vec4 borderCol;
float circle(vec2 p, vec2 center, float r)
{
return length(p - center);
}
void main()
{
float dist = circle(gl_FragCoord.xy, rectCenter, radius);
vec4 fromColor = borderCol;
vec4 toColor = vec4(0.0, 0.0, 0.0, 0.0);
if(dist < radius)
{
dist = abs(dist) - radius;
if(dist < (radius - (borderSize)))
{
toColor = color;
dist = abs(dist) - (borderSize);
}
float blend = smoothstep(0.0, 1.0, dist);
OUT_col = mix(fromColor, toColor, blend);
}
dist = abs(dist) - radius;
float blend = smoothstep(0.0, 1.0, dist);
OUT_col = mix(fromColor, toColor, blend);
}

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.
//-----------------------------------------------------------------------------
in vec4 color;
out vec4 OUT_col;
uniform vec2 sizeUni;
uniform vec2 rectCenter;
uniform vec2 oneOverViewport;
uniform float radius;
uniform float borderSize;
uniform vec4 borderCol;
float RoundedRectSDF(vec2 p, vec2 size, float radius)
{
// Calculate distance to each side of the rectangle
vec2 dist = abs(p) - size + vec2(radius, radius);
// Compute the distance to the rounded corners
float cornerDist = length(max(dist, 0.0));
// Return the minimum distance (negative inside, positive outside)
return min(max(dist.x, dist.y), 0.0) + cornerDist - radius;
}
void main()
{
vec2 p = gl_FragCoord.xy;
float halfBorder = borderSize * 0.5;
vec2 halfSize = sizeUni * 0.5;
p -= rectCenter;
// Calculate signed distance field for rounded rectangle
vec4 fromColor = borderCol;
// alpha
vec4 toColor = vec4(0.0, 0.0, 0.0, 0.0);
float cornerRadius = radius;
// if ((p.y < 0.0 && p.x < 0.0) || // top left corner
// (p.y < 0.0 && p.x > 0.0) || // top right corner
// (p.y > 0.0 && p.x > 0.0) || // bottom right corner.
// (p.y > 0.0 && p.x < 0.0)) // bottom left corner
// {
// cornerRadius = radius;
// }
if(cornerRadius > 0.0 || halfBorder > 0.0)
{
float sdf = RoundedRectSDF(p, halfSize, cornerRadius - halfBorder);
if(halfBorder > 0.0)
{
if(sdf < 0.0)
{
// if ((p.y >= -halfSize.y - radius + halfBorder && p.y <= -halfSize.y + radius - halfBorder) || // top border
// (p.y >= halfSize.y - radius + halfBorder && p.y <= halfSize.y + radius - halfBorder) || // bottom border
// (p.x >= -halfSize.x - radius + halfBorder && p.x <= -halfSize.x + radius - halfBorder) || // left border
// (p.x >= halfSize.x - radius + halfBorder && p.x <= halfSize.x + radius - halfBorder) ) { // right border
// }
toColor = color;
sdf = abs(sdf) / borderSize;
}
}
else{
fromColor = color;
}
float alpha = smoothstep(-1.0, 1.0, sdf);
OUT_col = mix(fromColor, toColor, alpha);
}
else
{
OUT_col = color;
}
}

View file

@ -0,0 +1,67 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;
in VS_OUT {
vec4 color;
} gs_in[];
out vec4 fragColor;
uniform float thickness;
uniform vec2 oneOverViewport;
void main()
{
// Calculate the direction of the line segment
vec2 direction = normalize(gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy);
// Calculate perpendicular direction
vec2 perpendicular = normalize(vec2(-direction.y, direction.x));
// Calculate offset for thickness
vec2 offset = vec2(thickness * oneOverViewport.x, thickness * oneOverViewport.y) * perpendicular;
// Calculate vertices for the line with thickness
vec2 p0 = gl_in[0].gl_Position.xy + offset;
vec2 p1 = gl_in[0].gl_Position.xy - offset;
vec2 p2 = gl_in[1].gl_Position.xy + offset;
vec2 p3 = gl_in[1].gl_Position.xy - offset;
fragColor = gs_in[0].color;
gl_Position = vec4(p0, 0.0f, 1.0f);
EmitVertex();
gl_Position = vec4(p1, 0.0f, 1.0f);
EmitVertex();
gl_Position = vec4(p2, 0.0f, 1.0f);
EmitVertex();
gl_Position = vec4(p3, 0.0f, 1.0f);
EmitVertex();
EndPrimitive();
}

View file

@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
in vec4 fragColor;
out vec4 OUT_col;
void main()
{
OUT_col = fragColor;
}

View file

@ -0,0 +1,103 @@
//-----------------------------------------------------------------------------
// 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 "../shaderModel.hlsl"
struct Conn
{
float4 HPOS : TORQUE_POSITION;
float4 color : COLOR;
};
uniform float2 sizeUni;
uniform float2 rectCenter;
uniform float2 oneOverViewport;
uniform float radius;
uniform float borderSize;
uniform float4 borderCol;
float RoundedRectSDF(float2 p, float2 size, float radius)
{
// Calculate distance to each side of the rectangle
float2 dist = abs(p) - size + float2(radius, radius);
// Compute the distance to the rounded corners
float cornerDist = length(max(dist, 0.0));
// Return the minimum distance (negative inside, positive outside)
return min(max(dist.x, dist.y), 0.0) + cornerDist - radius;
}
float4 main(Conn IN) : TORQUE_TARGET0
{
float2 p = IN.HPOS.xy;
float halfBorder = borderSize * 0.5;
float2 halfSize = sizeUni * 0.5;
p -= rectCenter;
// Calculate signed distance field for rounded rectangle
float4 fromColor = borderCol;
// alpha
float4 toColor = float4(0.0, 0.0, 0.0, 0.0);
float cornerRadius = radius;
// if ((p.y < 0.0 && p.x < 0.0) || // top left corner
// (p.y < 0.0 && p.x > 0.0) || // top right corner
// (p.y > 0.0 && p.x > 0.0) || // bottom right corner.
// (p.y > 0.0 && p.x < 0.0)) // bottom left corner
// {
// cornerRadius = radius;
// }
if(cornerRadius > 0.0 || halfBorder > 0.0)
{
float sdf = RoundedRectSDF(p, halfSize, cornerRadius - halfBorder);
if(halfBorder > 0.0)
{
if(sdf < 0.0)
{
// if ((p.y >= -halfSize.y - radius + halfBorder && p.y <= -halfSize.y + radius - halfBorder) || // top border
// (p.y >= halfSize.y - radius + halfBorder && p.y <= halfSize.y + radius - halfBorder) || // bottom border
// (p.x >= -halfSize.x - radius + halfBorder && p.x <= -halfSize.x + radius - halfBorder) || // left border
// (p.x >= halfSize.x - radius + halfBorder && p.x <= halfSize.x + radius - halfBorder) ) { // right border
// }
toColor = IN.color;
sdf = abs(sdf) / borderSize;
}
}
else{
fromColor = IN.color;
}
float alpha = smoothstep(-1.0, 1.0, sdf);
return lerp(fromColor, toColor, alpha);
}
else
{
return IN.color;
}
}

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.
//-----------------------------------------------------------------------------
#include "../shaderModel.hlsl"
struct Conn
{
float4 HPOS : TORQUE_POSITION;
float4 color : COLOR;
};
struct PSConn
{
float4 HPOS : TORQUE_POSITION;
float4 color : COLOR;
};
uniform float thickness;
uniform float2 oneOverViewport;
[maxvertexcount(4)]
void main(line Conn lineSegment[2], inout TriangleStream<PSConn> outstream)
{
// Calculate the direction of the line segment
float2 direction = normalize(lineSegment[1].HPOS.xy - lineSegment[0].HPOS.xy);
// Calculate perpendicular direction
float2 perpendicular = normalize(float2(-direction.y, direction.x));
// Calculate offset for thickness
float2 offset = float2(thickness * oneOverViewport.x, thickness * oneOverViewport.y) * perpendicular;
// Calculate vertices for the line with thickness
float2 p0 = lineSegment[0].HPOS.xy + offset;
float2 p1 = lineSegment[0].HPOS.xy - offset;
float2 p2 = lineSegment[1].HPOS.xy + offset;
float2 p3 = lineSegment[1].HPOS.xy - offset;
PSConn output;
output.HPOS = float4(p0, 0.0f, 1.0f);
output.color = lineSegment[0].color;
outstream.Append(output);
output.HPOS = float4(p1, 0.0f, 1.0f);
output.color = lineSegment[0].color;
outstream.Append(output);
output.HPOS = float4(p2, 0.0f, 1.0f);
output.color = lineSegment[1].color;
outstream.Append(output);
output.HPOS = float4(p3, 0.0f, 1.0f);
output.color = lineSegment[1].color;
outstream.Append(output);
outstream.RestartStrip();
}

View file

@ -0,0 +1,34 @@
//-----------------------------------------------------------------------------
// 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 "../shaderModel.hlsl"
struct PSConn
{
float4 HPOS : TORQUE_POSITION;
float4 color : COLOR;
};
float4 main(PSConn IN) : TORQUE_TARGET0
{
return IN.color;
}

View file

@ -943,6 +943,16 @@ singleton GuiControlProfile( GuiBackFillProfile )
category = "Editor"; category = "Editor";
}; };
singleton GuiControlProfile(GuiShaderEditorProfile : ToolsGuiDefaultProfile)
{
opaque = true;
canKeyFocus = true;
border = true;
borderColor = "128 128 128 128";
borderColorHL = "128 128 0";
borderColorSEL = "128 0 128 128";
};
singleton GuiControlProfile( GuiControlListPopupProfile ) singleton GuiControlProfile( GuiControlListPopupProfile )
{ {
opaque = true; opaque = true;

View file

@ -0,0 +1,7 @@
<GUIAsset
canSave="true"
canSaveDynamicFields="true"
AssetName="ShaderEditorGui, EditorGuiGroup"
scriptFile="@assetFile=shaderEditorGui.ed.gui"
GUIFile="@assetFile=shaderEditorGui.ed.gui"
VersionId="1"/>

View file

@ -0,0 +1,122 @@
//--- OBJECT WRITE BEGIN ---
$guiContent = new GuiControl(ShaderEditorGui) {
extent = "1280 720";
profile = "GuiDefaultProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
isContainer = "1";
canSaveDynamicFields = "1";
new GuiFrameSetCtrl() {
columns = "0 320 1000";
borderWidth = "2";
borderColor = "10 10 10 0";
autoBalance = "1";
extent = "1280 720";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiFrameSetProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
new GuiControl() {
extent = "318 720";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiDefaultProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
isContainer = "1";
new GuiSplitContainer() {
orientation = "Horizontal";
splitPoint = "0 200";
extent = "317 720";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiDefaultProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
new GuiPanel(ShaderEditorPreview) {
docking = "Client";
extent = "317 198";
profile = "ToolsGuiButtonProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
internalName = "Panel1";
};
new GuiPanel(ShaderEditorInspector) {
docking = "Client";
position = "0 202";
extent = "317 518";
profile = "ToolsGuiButtonProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
internalName = "panel2";
};
};
};
new GuiControl() {
position = "320 0";
extent = "678 720";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiButtonProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
isContainer = "1";
new GuiShaderEditor(ShaderNodeGraph) {
extent = "678 720";
horizSizing = "width";
vertSizing = "height";
profile = "GuiShaderEditorProfile";
tooltipProfile = "GuiToolTipProfile";
};
};
new GuiControl(ShaderEditorSidebar) {
position = "1000 0";
extent = "280 720";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiDefaultProfile";
tooltipProfile = "ToolsGuiButtonProfile";
isContainer = "1";
new GuiTabBookCtrl(ShaderEditorTabBook) {
tabHeight = "20";
allowReorder = "1";
selectedPage = "0";
position = "3 5";
extent = "271 520";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiTabBookProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
new GuiTabPageCtrl() {
fitBook = "1";
text = "Library";
position = "0 20";
extent = "271 500";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiTabPageProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
new GuiScrollCtrl() {
hScrollBar = "dynamic";
childMargin = "0 2";
extent = "271 490";
horizSizing = "width";
vertSizing = "height";
profile = "ToolsGuiScrollProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
new GuiStackControl(ShaderToolbox) {
extent = "591 1000";
horizSizing = "width";
profile = "ToolsGuiDefaultProfile";
tooltipProfile = "ToolsGuiToolTipProfile";
};
};
};
};
};
};
};
//--- OBJECT WRITE END ---

View file

@ -4,7 +4,8 @@ option(TORQUE_TOOLS "Enable Torque Tools" ON)
if(TORQUE_TOOLS) if(TORQUE_TOOLS)
message("Enabling Torque Tools Module") message("Enabling Torque Tools Module")
file(GLOB_RECURSE TORQUE_TOOLS_SOURCES "gui/editor/*.cpp" "gui/editor/*.h" "gui/worldEditor/*.cpp" "gui/worldEditor/*.h") file(GLOB_RECURSE TORQUE_TOOLS_SOURCES "gui/editor/*.cpp" "gui/editor/*.h" "gui/worldEditor/*.cpp" "gui/worldEditor/*.h" "gui/shaderEditor/*.cpp" "gui/shaderEditor/*.h"
"gui/shaderEditor/nodes/*.cpp" "gui/shaderEditor/nodes/*.h")
file(GLOB_RECURSE TORQUE_TOOLS_SOURCES2 "environment/editors/*.cpp" "environment/editors/*.h") file(GLOB_RECURSE TORQUE_TOOLS_SOURCES2 "environment/editors/*.cpp" "environment/editors/*.h")
file(GLOB_RECURSE TORQUE_TOOLS_SOURCES3 "forest/editor/*.cpp" "forest/editor/*.h") file(GLOB_RECURSE TORQUE_TOOLS_SOURCES3 "forest/editor/*.cpp" "forest/editor/*.h")