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;
mLastPixShader = NULL;
mLastGeoShader = NULL;
mCanCurrentlyRender = false;
mTextureManager = NULL;
@ -159,6 +160,11 @@ GFXD3D11Device::~GFXD3D11Device()
for (; sampIter != mSamplersMap.end(); ++sampIter)
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.
VertexDeclMap::Iterator iter = mVertexDecls.begin();
for (; iter != mVertexDecls.end(); ++iter)
@ -202,7 +208,7 @@ GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, cons
features |= D3D11_FORMAT_SUPPORT_BLENDABLE;
if(mustfilter)
features |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
for(U32 i = 0; i < formats.size(); i++)
{
if(GFXD3D11TextureFormat[formats[i]] == DXGI_FORMAT_UNKNOWN)
@ -213,7 +219,7 @@ GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, cons
if(supportFlag & features)
return formats[i];
}
return GFXFormatR8G8B8A8;
}
@ -261,7 +267,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
{
GFXAdapter *toAdd = new GFXAdapter;
toAdd->mType = Direct3D11;
@ -286,7 +292,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
dStrncpy(toAdd->mName, Description.c_str(), GFXAdapter::MaxAdapterNameLen);
dStrncat(toAdd->mName, " (D3D11)", sizeof(toAdd->mName) - strlen(toAdd->mName) - 1);
IDXGIOutput* pOutput = NULL;
IDXGIOutput* pOutput = NULL;
HRESULT hr;
hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
@ -310,7 +316,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
displayModes = new DXGI_MODE_DESC[numModes];
displayModes = new DXGI_MODE_DESC[numModes];
// Get the list
hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
@ -376,7 +382,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
SAFE_RELEASE(DXGIFactory);
}
void GFXD3D11Device::enumerateVideoModes()
void GFXD3D11Device::enumerateVideoModes()
{
mVideoModes.clear();
@ -389,9 +395,9 @@ void GFXD3D11Device::enumerateVideoModes()
if (FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> CreateDXGIFactory1 call failure");
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
{
IDXGIOutput* pOutput = NULL;
IDXGIOutput* pOutput = NULL;
hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
@ -414,7 +420,7 @@ void GFXD3D11Device::enumerateVideoModes()
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
displayModes = new DXGI_MODE_DESC[numModes];
displayModes = new DXGI_MODE_DESC[numModes];
// Get the list
hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
@ -519,14 +525,16 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
{
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
mGeometryShaderTarget = "gs_5_0";
mPixVersion = 5.0f;
mShaderModel = "50";
break;
case D3D_FEATURE_LEVEL_10_1:
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mGeometryShaderTarget = "gs_4_1";
mPixVersion = 4.1f;
mShaderModel = "41";
break;
@ -546,7 +554,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
SAFE_RELEASE(testQuery);
Con::printf("Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No");
mCardProfiler = new GFXD3D11CardProfiler();
mCardProfiler->init();
@ -589,10 +597,10 @@ void GFXD3D11Device::_suppressDebugMessages()
}
}
bool GFXD3D11Device::beginSceneInternal()
bool GFXD3D11Device::beginSceneInternal()
{
mCanCurrentlyRender = true;
return mCanCurrentlyRender;
return mCanCurrentlyRender;
}
GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
@ -739,7 +747,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
_updateRenderTargets();
}
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix);
setShader(mGenericShader[type]);
@ -764,7 +772,7 @@ void GFXD3D11Device::setStateBlockInternal(GFXStateBlock* block, bool force)
if (force)
d3dCurrent = NULL;
d3dBlock->activate(d3dCurrent);
d3dBlock->activate(d3dCurrent);
}
/// Called by base GFXDevice to actually set a const buffer
@ -863,7 +871,7 @@ void GFXD3D11Device::clearColorAttachment(const U32 attachment, const LinearColo
mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
}
void GFXD3D11Device::endSceneInternal()
void GFXD3D11Device::endSceneInternal()
{
mCanCurrentlyRender = false;
}
@ -875,7 +883,7 @@ void GFXD3D11Device::_updateRenderTargets()
if (mRTDeactivate)
{
mRTDeactivate->deactivate();
mRTDeactivate = NULL;
mRTDeactivate = NULL;
}
// NOTE: The render target changes are not really accurate
@ -887,7 +895,7 @@ void GFXD3D11Device::_updateRenderTargets()
mCurrentRT->activate();
mRTDirty = false;
}
}
if (mViewportDirty)
{
@ -906,7 +914,7 @@ void GFXD3D11Device::_updateRenderTargets()
}
}
void GFXD3D11Device::releaseDefaultPoolResources()
void GFXD3D11Device::releaseDefaultPoolResources()
{
// Release all the dynamic vertex buffer arrays
// Forcibly clean up the pools
@ -919,7 +927,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
// We gotta clear the current const buffer else the next
// activate may erroneously think the device is still holding
// this state and fail to set it.
// this state and fail to set it.
mCurrentConstBuffer = NULL;
// Set current VB to NULL and set state dirty
@ -943,7 +951,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
mPrimitiveBufferDirty = true;
// Zombify texture manager (for D3D this only modifies default pool textures)
if( mTextureManager )
if( mTextureManager )
mTextureManager->zombify();
// Set global dirty state so the IB/PB and VB get reset
@ -958,7 +966,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
}
}
void GFXD3D11Device::reacquireDefaultPoolResources()
void GFXD3D11Device::reacquireDefaultPoolResources()
{
// Now do the dynamic index buffers
if( mDynamicPB == NULL )
@ -974,7 +982,7 @@ void GFXD3D11Device::reacquireDefaultPoolResources()
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &mDynamicPB->ib);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate dynamic IB");
}
@ -1020,7 +1028,7 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
newBuff->mDevice = this;
// Requesting it will allocate it.
vertexFormat->getDecl();
vertexFormat->getDecl();
D3D11_BUFFER_DESC desc;
desc.ByteWidth = vertSize * GFX_MAX_DYNAMIC_VERTS;
@ -1032,7 +1040,7 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &newBuff->vb);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate dynamic VB");
}
@ -1042,9 +1050,9 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
//-----------------------------------------------------------------------------
void GFXD3D11Device::setClipRect( const RectI &inRect )
void GFXD3D11Device::setClipRect( const RectI &inRect )
{
// We transform the incoming rect by the view
// We transform the incoming rect by the view
// matrix first, so that it can be used to pan
// and scale the clip rect.
//
@ -1052,7 +1060,7 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
Point3F pos( inRect.point.x, inRect.point.y, 0.0f );
Point3F extent( inRect.extent.x, inRect.extent.y, 0.0f );
getViewMatrix().mulP( pos );
getViewMatrix().mulV( extent );
getViewMatrix().mulV( extent );
RectI rect( pos.x, pos.y, extent.x, extent.y );
// Clip the rect against the renderable size.
@ -1068,8 +1076,8 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
F32 b = F32( mClipRect.point.y + mClipRect.extent.y );
F32 t = F32( mClipRect.point.y );
// Set up projection matrix,
static Point4F pt;
// Set up projection matrix,
static Point4F pt;
pt.set(2.0f / (r - l), 0.0f, 0.0f, 0.0f);
mTempMatrix.setColumn(0, pt);
@ -1085,7 +1093,7 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
setProjectionMatrix( mTempMatrix );
// Set up world/view matrix
mTempMatrix.identity();
mTempMatrix.identity();
setWorldMatrix( mTempMatrix );
setViewport( mClipRect );
@ -1097,7 +1105,7 @@ void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
if ( stream == 0 )
{
// Set the volatile buffer which is used to
// Set the volatile buffer which is used to
// offset the start index when doing draw calls.
if ( d3dBuffer && d3dBuffer->mVolatileStart > 0 )
mVolatileVB = d3dBuffer;
@ -1106,7 +1114,7 @@ void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
}
// NOTE: We do not use the stream offset here for stream 0
// as that feature is *supposedly* not as well supported as
// as that feature is *supposedly* not as well supported as
// using the start index in drawPrimitive.
//
// If we can verify that this is not the case then we should
@ -1125,7 +1133,7 @@ void GFXD3D11Device::setVertexStreamFrequency( U32 stream, U32 frequency )
mDrawInstancesCount = frequency; // instances count
}
void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer )
void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer )
{
mCurrentPB = static_cast<GFXD3D11PrimitiveBuffer *>( buffer );
@ -1160,7 +1168,7 @@ U32 GFXD3D11Device::primCountToIndexCount(GFXPrimitiveType primType, U32 primiti
}
void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
{
// This is done to avoid the function call overhead if possible
if( mStateDirty )
@ -1172,12 +1180,12 @@ void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart,
vertexStart += mVolatileVB->mVolatileStart;
mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
if ( mDrawInstancesCount )
mD3DDeviceContext->DrawInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, vertexStart, 0);
else
mD3DDeviceContext->Draw(primCountToIndexCount(primType, primitiveCount), vertexStart);
mDeviceStatistics.mDrawCalls++;
if ( mVertexBufferFrequency[0] > 1 )
mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
@ -1185,12 +1193,12 @@ void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart,
mDeviceStatistics.mPolyCount += primitiveCount;
}
void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount )
void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount )
{
// This is done to avoid the function call overhead if possible
if( mStateDirty )
@ -1204,11 +1212,11 @@ void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
startVertex += mVolatileVB->mVolatileStart;
mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
if ( mDrawInstancesCount )
mD3DDeviceContext->DrawIndexedInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, mCurrentPB->mVolatileStart + startIndex, startVertex, 0);
else
mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);
mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);
mDeviceStatistics.mDrawCalls++;
if ( mVertexBufferFrequency[0] > 1 )
@ -1245,7 +1253,13 @@ void GFXD3D11Device::setShader(GFXShader *shader, bool force)
{
mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0);
mLastVertShader = d3dShader->mVertShader;
}
}
if (d3dShader->mGeoShader != mLastGeoShader || force)
{
mD3DDeviceContext->GSSetShader(d3dShader->mGeoShader, NULL, 0);
mLastGeoShader = d3dShader->mGeoShader;
}
}
else
{
@ -1308,7 +1322,7 @@ GFXPrimitiveBuffer * GFXD3D11Device::allocPrimitiveBuffer(U32 numIndices, U32 nu
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->ib);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate an index buffer.");
}
@ -1329,12 +1343,12 @@ GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVerte
{
PROFILE_SCOPE( GFXD3D11Device_allocVertexBuffer );
GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer( this,
numVerts,
vertexFormat,
vertSize,
GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer( this,
numVerts,
vertexFormat,
vertSize,
bufferType );
// Determine usage flags
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
@ -1387,7 +1401,7 @@ GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVerte
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->vb);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate VB");
}
@ -1540,16 +1554,16 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
return decl;
U32 elemCount = vertexFormat->getElementCount();
ID3DBlob* code = NULL;
// We have to generate a temporary shader here for now since the input layout creation
// expects a shader to be already compiled to verify the vertex layout structure. The problem
// is that most of the time the regular shaders are compiled AFTER allocVertexDecl is called.
if(!decl)
{
//TODO: Perhaps save/cache the ID3DBlob for later use on identical vertex formats,save creating/compiling the temp shader everytime
String shaderData = _createTempShaderInternal(vertexFormat);
String shaderData = _createTempShaderInternal(vertexFormat);
#ifdef TORQUE_DEBUG
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
@ -1569,11 +1583,11 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
SAFE_RELEASE(errorBlob);
}
AssertFatal(code, "D3D11Device::allocVertexDecl - compiled vert shader code missing!");
// Setup the declaration struct.
U32 stream;
D3D11_INPUT_ELEMENT_DESC *vd = new D3D11_INPUT_ELEMENT_DESC[ elemCount];
@ -1599,7 +1613,7 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
vd[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
vd[i].InstanceDataStepRate = 0;
}
// We force the usage index of 0 for everything but
// We force the usage index of 0 for everything but
// texture coords for now... this may change later.
vd[i].SemanticIndex = 0;
@ -1634,7 +1648,7 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
decl = new D3D11VertexDecl();
HRESULT hr = mD3DDevice->CreateInputLayout(vd, elemCount,code->GetBufferPointer(), code->GetBufferSize(), &decl->decl);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::allocVertexDecl - Failed to create vertex input layout!");
@ -1654,7 +1668,7 @@ void GFXD3D11Device::setVertexDecl( const GFXVertexDecl *decl )
ID3D11InputLayout *dx11Decl = NULL;
if (decl)
dx11Decl = static_cast<const D3D11VertexDecl*>(decl)->decl;
mD3DDeviceContext->IASetInputLayout(dx11Decl);
}
@ -1709,7 +1723,7 @@ GFXFence *GFXD3D11Device::createFence()
}
// CodeReview: At some point I would like a specialized implementation of
// the method used by the general fence, only without the overhead incurred
// the method used by the general fence, only without the overhead incurred
// by using the GFX constructs. Primarily the lock() method on texture handles
// will do a data copy, and this method doesn't require a copy, just a lock
// [5/10/2007 Pat]
@ -1719,12 +1733,12 @@ GFXFence *GFXD3D11Device::createFence()
}
GFXOcclusionQuery* GFXD3D11Device::createOcclusionQuery()
{
{
GFXOcclusionQuery *query;
if (mOcclusionQuerySupported)
query = new GFXD3D11OcclusionQuery( this );
else
return NULL;
return NULL;
query->registerResourceWithDevice(this);
return query;
@ -1794,7 +1808,7 @@ const char* GFXD3D11Device::interpretDebugResult(long result)
//generics
case E_UNEXPECTED:
error = "E_UNEXPECTED";
break;
break;
case E_NOTIMPL:
error = "E_NOTIMPL";
break;
@ -1852,3 +1866,39 @@ const char* GFXD3D11Device::interpretDebugResult(long result)
}
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:
typedef Map<U32, ID3D11SamplerState*> SamplerMap;
typedef Map<String, ID3D11Buffer*> DeviceBufferMap;
private:
friend class GFXResource;
@ -105,6 +106,7 @@ protected:
/// Used to lookup sampler state for a given hash key
SamplerMap mSamplersMap;
DeviceBufferMap mDeviceBufferMap;
ID3D11RenderTargetView* mDeviceBackBufferView;
ID3D11DepthStencilView* mDeviceDepthStencilView;
@ -121,6 +123,7 @@ protected:
ID3D11VertexShader *mLastVertShader;
ID3D11PixelShader *mLastPixShader;
ID3D11GeometryShader *mLastGeoShader;
S32 mCreateFenceType;
@ -140,6 +143,7 @@ protected:
// Shader Model targers
String mVertexShaderTarget;
String mPixelShaderTarget;
String mGeometryShaderTarget;
// String for use with shader macros in the form of shader model version * 10
String mShaderModel;
bool mDebugLayers;
@ -148,7 +152,7 @@ protected:
bool mOcclusionQuerySupported;
U32 mDrawInstancesCount;
U32 mDrawInstancesCount;
/// To manage creating and re-creating of these when device is aquired
void reacquireDefaultPoolResources();
@ -181,11 +185,11 @@ protected:
// Index buffer management
// {
virtual void _setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount );
// }
@ -197,7 +201,7 @@ protected:
String _createTempShaderInternal(const GFXVertexFormat *vertexFormat);
// Supress any debug layer messages we don't want to see
void _suppressDebugMessages();
public:
static GFXDevice *createInstance( U32 adapterIndex );
@ -229,7 +233,7 @@ public:
virtual GFXTextureArray* createTextureArray();
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
virtual void setShader(GFXShader *shader, bool force = false);
virtual U32 getNumSamplers() const { return 16; }
@ -252,10 +256,10 @@ public:
virtual void setClipRect( const RectI &rect );
virtual const RectI& getClipRect() const { return mClipRect; }
// }
// }
/// @name Render Targets
/// @{
virtual void _updateRenderTargets();
@ -263,14 +267,14 @@ public:
// Vertex/Index buffer management
// {
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
GFXBufferType bufferType,
void* data = NULL);
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
U32 numPrimitives,
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
U32 numPrimitives,
GFXBufferType bufferType,
void* data = NULL);
@ -307,7 +311,7 @@ public:
GFXFence *createFence();
GFXOcclusionQuery* createOcclusionQuery();
GFXOcclusionQuery* createOcclusionQuery();
// Default multisample parameters
DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
@ -317,12 +321,16 @@ public:
// Shader Model targers
const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
const String &getGeometryShaderTarget() const { return mGeometryShaderTarget; }
const String &getShaderModel() const { return mShaderModel; }
// grab the sampler map
const SamplerMap &getSamplersMap() const { return mSamplersMap; }
SamplerMap &getSamplersMap(){ return mSamplersMap; }
const char* interpretDebugResult(long result);
// grab device buffer.
ID3D11Buffer* getDeviceBuffer(const GFXShaderConstDesc desc);
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -29,282 +29,87 @@
#include "core/util/tDictionary.h"
#include "gfx/gfxShader.h"
#include "gfx/gfxResource.h"
#include "gfx/genericConstBuffer.h"
#include "gfx/D3D11/gfxD3D11Device.h"
class GFXD3D11Shader;
enum CONST_CLASS
typedef CompoundKey<U32, U32> BufferKey;
struct BufferRange
{
D3DPC_SCALAR,
D3DPC_VECTOR,
D3DPC_MATRIX_ROWS,
D3DPC_MATRIX_COLUMNS,
D3DPC_OBJECT,
D3DPC_STRUCT
};
U32 mBufMin = U32_MAX;
U32 mBufMax = 0;
enum CONST_TYPE
{
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)
inline void addSlot(U32 slot)
{
if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT)
{
// 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;
}
mBufMin = getMin(mBufMin, slot);
mBufMax = getMax(mBufMax, slot);
}
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;
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;
U8* data;
U32 size;
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;
bool isDirty;
};
class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
{
public:
friend class GFXD3D11Shader;
public:
typedef Map<GFXShaderStage, GFXShaderConstDesc> DescMap;
// GFXShaderConstHandle
const String& getName() const;
GFXShaderConstType getType() const;
U32 getArraySize() const;
GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader);
GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
const GFXShaderConstDesc& desc);
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;
GenericConstBufferLayout::ParamDesc mVertexHandle;
bool mPixelConstant;
GenericConstBufferLayout::ParamDesc mPixelHandle;
/// 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;
U32 getSize() const { return mDesc.size; }
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; }
// 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.
void clear()
{
mShader = NULL;
mVertexConstant = false;
mPixelConstant = false;
mInstancingConstant = false;
mVertexHandle.clear();
mPixelHandle.clear();
mValid = false;
}
GFXD3D11ShaderConstHandle();
GFXShaderConstDesc mDesc;
GFXD3D11Shader* mShader;
DescMap mDescMap;
U32 mStageFlags;
bool mInstancingConstant;
};
/// The D3D11 implementation of a shader constant buffer.
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
{
friend class GFXD3D11Shader;
// Cache device context
ID3D11DeviceContext* mDeviceContext;
public:
typedef Map<BufferKey, ConstantBuffer> BufferMap;
GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader,
GFXD3D11ConstBufferLayout* vertexLayout,
GFXD3D11ConstBufferLayout* pixelLayout);
GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader);
virtual ~GFXD3D11ShaderConstBuffer();
@ -312,8 +117,7 @@ public:
/// @param mPrevShaderBuffer The previously active buffer
void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
/// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
bool isDirty();
void addBuffer(const GFXShaderConstDesc desc);
/// Called from GFXD3D11Shader when constants have changed and need
/// to be the shader this buffer references is reloaded.
@ -344,33 +148,20 @@ public:
// GFXResource
virtual const String describeSelf() const;
virtual void zombify();
virtual void resurrect();
virtual void zombify() {}
virtual void resurrect() {}
protected:
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
friend class GFXD3D11Shader;
/// We keep a weak reference to the shader
/// because it will often be deleted.
WeakRefPtr<GFXD3D11Shader> mShader;
BufferMap mBufferMap;
//vertex
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
GenericConstBuffer* mVertexConstBuffer;
//pixel
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
GenericConstBuffer* mPixelConstBuffer;
void setMatrix(const GFXShaderConstDesc& handle, const U32 inSize, const void* data, U8* basePointer);
void internalSet(GFXShaderConstHandle* handle, const U32 inSize, const void* data);
ID3D11Buffer* mBoundBuffers[6][16];
};
class gfxD3D11Include;
@ -385,17 +176,17 @@ class GFXD3D11Shader : public GFXShader
public:
typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
typedef Map<String, GFXShaderConstDesc> BufferMap;
GFXD3D11Shader();
virtual ~GFXD3D11Shader();
virtual ~GFXD3D11Shader();
// GFXShader
virtual GFXShaderConstBufferRef allocConstBuffer();
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual bool getDisassembly( String &outStr ) const;
// GFXResource
virtual void zombify();
@ -403,71 +194,36 @@ public:
protected:
virtual bool _init();
static const U32 smCompiledShaderTag;
ConstantTable table;
virtual bool _init();
ID3D11VertexShader *mVertShader;
ID3D11PixelShader *mPixShader;
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
ID3D11GeometryShader *mGeoShader;
static gfxD3DIncludeRef smD3DInclude;
HandleMap mHandles;
/// 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;
BufferMap mBuffers;
/// Vector of descriptions (consolidated for the getShaderConstDesc call)
Vector<GFXShaderConstDesc> mShaderConsts;
Vector<GFXShaderConstDesc> mSamplerDescriptions;
// These two functions are used when compiling shaders from hlsl
virtual bool _compileShader( const Torque::Path &filePath,
const String &target,
const D3D_SHADER_MACRO *defines,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
virtual bool _compileShader( const Torque::Path &filePath,
GFXShaderStage shaderStage,
const D3D_SHADER_MACRO *defines);
void _getShaderConstants( ID3D11ShaderReflection* refTable,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
void _getShaderConstants( ID3D11ShaderReflection* refTable,
GFXShaderStage shaderStage);
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
virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst);
virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
/// Used to build the instancing shader constants from
/// the instancing vertex format.
virtual void _buildShaderConstantHandles();
void _buildInstancingShaderConstantHandles();
GFXShaderConstType convertConstType(D3D11_SHADER_TYPE_DESC typeDesc);
};
inline bool GFXD3D11Shader::getDisassembly(String &outStr) const
{
outStr = mDissasembly;
return (outStr.isNotEmpty());
}
#endif

View file

@ -34,6 +34,9 @@
#define STBIWDEF static inline
#endif
#pragma warning( push )
#pragma warning( disable : 4505 ) // unreferenced function removed.
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_STATIC
#include "stb_image.h"
@ -42,6 +45,8 @@
#define STB_IMAGE_WRITE_STATIC
#include "stb_image_write.h"
#pragma warning(pop)
static bool sReadSTB(const Torque::Path& path, GBitmap* bitmap);
static bool sReadStreamSTB(Stream& stream, GBitmap* bitmap, U32 len);
@ -147,7 +152,7 @@ bool sReadSTB(const Torque::Path& path, GBitmap* bitmap)
U32 buffSize = readIes->getStreamSize();
char* buffer = new char[buffSize];
readIes->read(buffSize, buffer);
IESFileInfo info;
IESLoadHelper IESLoader;
@ -399,8 +404,6 @@ bool sWriteSTB(const Torque::Path& path, GBitmap* bitmap, U32 compressionLevel)
String ext = path.getExtension();
U32 stride = width * bytes;
// we always have at least 1
U32 comp = 1;
@ -554,7 +557,6 @@ void DeferredPNGWriter::append(GBitmap* bitmap, U32 rows)
mData->channels = bitmap->getBytesPerPixel();
}
const U32 height = getMin(bitmap->getHeight(), rows);
const dsize_t dataChuckSize = bitmap->getByteSize();
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/primBuilder.h"
#include "gfx/gfxDebugEvent.h"
#include "materials/shaderData.h"
#include "math/mPolyhedron.impl.h"
@ -45,7 +45,7 @@ GFXDrawUtil::GFXDrawUtil( GFXDevice * d)
mTextAnchorColor.set(0xFF, 0xFF, 0xFF, 0xFF);
mFontRenderBatcher = new FontRenderBatcher();
_setupStateBlocks();
_setupStateBlocks();
}
GFXDrawUtil::~GFXDrawUtil()
@ -90,6 +90,33 @@ void GFXDrawUtil::_setupStateBlocks()
rectFill.setZReadWrite(false);
rectFill.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
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();
}
//-----------------------------------------------------------------------------
@ -118,13 +145,13 @@ void GFXDrawUtil::setTextAnchorColor( const ColorI &ancColor )
//-----------------------------------------------------------------------------
// Draw Text
//-----------------------------------------------------------------------------
U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
{
return drawTextN( font, ptDraw, in_string, dStrlen(in_string), colorTable, maxColorIndex, rot );
}
U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF8 *in_string,
U32 GFXDrawUtil::drawText( GFont *font, const Point2I &ptDraw, const UTF8 *in_string,
const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
{
return drawTextN( font, ptDraw, in_string, dStrlen(in_string), colorTable, maxColorIndex, rot );
@ -154,7 +181,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF8 *in_s
return drawTextN( font, ptDraw, ubuf, n, colorTable, maxColorIndex, rot );
}
U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_string,
U32 n, const ColorI *colorTable, const U32 maxColorIndex, F32 rot )
{
// return on zero length strings
@ -178,11 +205,11 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
S32 ptX = 0;
// Queue everything for render.
// Queue everything for render.
mFontRenderBatcher->init(font, n);
U32 i;
UTF16 c;
UTF16 c;
for (i = 0, c = in_string[i]; i < n && in_string[i]; i++, c = in_string[i])
{
switch(c)
@ -193,25 +220,25 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
case 14:
{
// Color code
if (colorTable)
if (colorTable)
{
static U8 remap[15] =
{
static U8 remap[15] =
{
0x0, // 0 special null terminator
0x0, // 1 ascii start-of-heading??
0x1,
0x2,
0x3,
0x4,
0x5,
0x6,
0x1,
0x2,
0x3,
0x4,
0x5,
0x6,
0x0, // 8 special backspace
0x0, // 9 special tab
0x0, // a special \n
0x7,
0x7,
0x8,
0x0, // a special \r
0x9
0x9
};
U8 remapped = remap[c];
@ -256,7 +283,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
}
// Tab character
case dT('\t'):
case dT('\t'):
{
if ( tabci == NULL )
tabci = &(font->getCharInfo( dT(' ') ));
@ -272,7 +299,7 @@ U32 GFXDrawUtil::drawTextN( GFont *font, const Point2I &ptDraw, const UTF16 *in_
// Don't draw invalid characters.
default:
{
if( !font->isValidChar( c ) )
if( !font->isValidChar( c ) )
continue;
}
}
@ -354,7 +381,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
{
// Sanity if no texture is specified.
if(!texture)
return;
return;
GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile );
verts.lock();
@ -369,13 +396,13 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
F32 screenTop = dstRect.point.y;
F32 screenBottom = (dstRect.point.y + dstRect.extent.y);
if( in_flip & GFXBitmapFlip_X )
if( in_flip & GFXBitmapFlip_X )
{
F32 temp = texLeft;
texLeft = texRight;
texRight = temp;
}
if( in_flip & GFXBitmapFlip_Y )
if( in_flip & GFXBitmapFlip_Y )
{
F32 temp = texTop;
texTop = texBottom;
@ -435,7 +462,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
AssertFatal(false, "No GFXDrawUtil state block defined for this filter type!");
mDevice->setStateBlock(mBitmapStretchSB);
break;
}
}
mDevice->setTexture( 0, texture );
mDevice->setupGenericShaders( GFXDevice::GSModColorTexture );
@ -445,7 +472,7 @@ void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &d
//-----------------------------------------------------------------------------
// Draw Rectangle
//-----------------------------------------------------------------------------
void GFXDrawUtil::drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color )
void GFXDrawUtil::drawRect( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color )
{
drawRect( Point2F((F32)upperLeft.x,(F32)upperLeft.y),Point2F((F32)lowerRight.x,(F32)lowerRight.y),color);
}
@ -513,57 +540,99 @@ void GFXDrawUtil::drawRect( const Point2F &upperLeft, const Point2F &lowerRight,
//-----------------------------------------------------------------------------
// 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 )
{
drawRectFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color);
void GFXDrawUtil::drawRectFill(const Point2I& upperLeft, const Point2I& lowerRight, const ColorI& color, const F32& borderSize, const ColorI& borderColor)
{
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
Point2F nw(-0.5,-0.5); /* \ */
Point2F ne(0.5,-0.5); /* / */
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);
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);
mDevice->setVertexBuffer( verts );
mDevice->setupGenericShaders();
mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 );
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(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 )
@ -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 )
{
@ -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 );
}
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
@ -713,13 +897,13 @@ void GFXDrawUtil::drawSphere( const GFXStateBlockDesc &desc, F32 radius, const P
//-----------------------------------------------------------------------------
static const Point3F cubePoints[8] =
static const Point3F cubePoints[8] =
{
Point3F(-1, -1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, -1), Point3F(-1, 1, 1),
Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1)
};
static const U32 cubeFaces[6][4] =
static const U32 cubeFaces[6][4] =
{
{ 0, 4, 6, 2 }, { 0, 2, 3, 1 }, { 0, 1, 5, 4 },
{ 3, 2, 6, 7 }, { 7, 6, 4, 5 }, { 3, 7, 5, 1 }
@ -812,7 +996,7 @@ void GFXDrawUtil::drawPolygon( const GFXStateBlockDesc& desc, const Point3F* poi
for( U32 i = 0; i < numPoints; ++ i )
xfm->mulP( verts[ i ].point );
}
if( isWireframe )
{
verts[ numVerts - 1 ].point = verts[ 0 ].point;
@ -899,7 +1083,7 @@ void GFXDrawUtil::_drawSolidCube( const GFXStateBlockDesc &desc, const Point3F &
for(S32 i = 0; i < 6; i++)
{
idx = cubeFaces[i][0];
verts[vertexIndex].point = cubePoints[idx] * halfSize;
verts[vertexIndex].point = cubePoints[idx] * halfSize;
verts[vertexIndex].color = color;
vertexIndex++;
@ -1110,13 +1294,13 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
Point3F cubePts[8];
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
for ( U32 i = 0; i < 8; i++ )
{
//const Point3F &start = cubePoints[i];
//const Point3F &start = cubePoints[i];
// 3 lines per corner point
for ( U32 j = 0; j < 3; j++ )
@ -1128,7 +1312,7 @@ void GFXDrawUtil::drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &s
scaledObjMat.mulP(start);
PrimBuild::vertex3fv(start);
scaledObjMat.mulP(end);
PrimBuild::vertex3fv(end);
PrimBuild::vertex3fv(end);
}
}
@ -1164,10 +1348,10 @@ void GFXDrawUtil::drawCapsule( const GFXStateBlockDesc &desc, const Point3F &cen
}
void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3F &center, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm )
{
{
MatrixF mat;
if ( xfm )
mat = *xfm;
mat = *xfm;
else
mat = MatrixF::Identity;
@ -1176,7 +1360,7 @@ void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3
verts.lock();
for (S32 i=0; i<numPoints + 1; i++)
{
S32 imod = i % numPoints;
S32 imod = i % numPoints;
verts[2 * i].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, height/2 );
verts[2 * i].color = color;
verts[2 * i + 1].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, -height/2 );
@ -1208,7 +1392,7 @@ void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3
if ( xfm )
sphereMat = *xfm;
else
sphereMat = MatrixF::Identity;
sphereMat = MatrixF::Identity;
sphereCenter.set( 0, 0, 0.5f * height );
mat.mulV( sphereCenter );
@ -1284,12 +1468,12 @@ void GFXDrawUtil::_drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F
}
void GFXDrawUtil::drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color )
{
{
VectorF uvec = tipPnt - basePnt;
F32 height = uvec.len();
uvec.normalize();
MatrixF mat( true );
MathUtils::getMatrixFromUpVector( uvec, &mat );
MathUtils::getMatrixFromUpVector( uvec, &mat );
mat.setPosition(basePnt);
Point3F scale( baseRadius, baseRadius, height );
@ -1359,7 +1543,7 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
F32 height = uvec.len();
uvec.normalize();
MatrixF mat( true );
MathUtils::getMatrixFromUpVector( uvec, &mat );
MathUtils::getMatrixFromUpVector( uvec, &mat );
mat.setPosition(basePnt);
Point3F scale( radius, radius, height * 2 );
@ -1425,14 +1609,14 @@ void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &ba
}
void GFXDrawUtil::drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color, F32 baseRad )
{
{
GFXTransformSaver saver;
// Direction and length of the arrow.
VectorF dir = end - start;
F32 len = dir.len();
dir.normalize();
len *= 0.2f;
dir.normalize();
len *= 0.2f;
// Base of the cone will be a distance back from the end of the arrow
// proportional to the total distance of the arrow... 0.3f looks about right.
@ -1464,11 +1648,11 @@ void GFXDrawUtil::drawFrustum( const Frustum &f, const ColorI &color )
// Draw near and far planes.
for (U32 offset = 0; offset < 8; offset+=4)
{
{
drawLine(points[offset+0], points[offset+1], color);
drawLine(points[offset+2], points[offset+3], color);
drawLine(points[offset+0], points[offset+2], color);
drawLine(points[offset+1], points[offset+3], color);
drawLine(points[offset+1], points[offset+3], color);
}
// connect the near and far planes
@ -1512,13 +1696,13 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
U32 vSteps = 0;
if( step.y > 0 )
vSteps = size.y / step.y + 0.5 + 1;
if( uSteps <= 1 || vSteps <= 1 )
return;
const U32 numVertices = uSteps * 2 + vSteps * 2;
const U32 numLines = uSteps + vSteps;
Point3F origin;
switch( plane )
{
@ -1552,14 +1736,14 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
verts[vertCount].point = Point3F( start + step.x * i, origin.y + size.y, origin.z );
else
verts[vertCount].point = Point3F( start + step.x * i, origin.y, origin.z + size.y );
verts[vertCount].color = color;
++vertCount;
}
}
if( plane == PlaneXY || plane == PlaneYZ )
{
{
U32 num;
F32 stp;
if( plane == PlaneXY )
@ -1574,7 +1758,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
}
F32 start = mFloor( origin.y / stp + 0.5f ) * stp;
for ( U32 i = 0; i < num; i++ )
{
verts[vertCount].point = Point3F( origin.x, start + stp * i, origin.z );
@ -1585,7 +1769,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
verts[vertCount].point = Point3F( origin.x + size.x, start + stp * i, origin.z );
else
verts[vertCount].point = Point3F( origin.x, start + stp * i, origin.z + size.x );
verts[vertCount].color = color;
++vertCount;
}
@ -1604,7 +1788,7 @@ void GFXDrawUtil::drawPlaneGrid( const GFXStateBlockDesc &desc, const Point3F &p
verts[vertCount].point = Point3F( origin.x + size.x, origin.y, start + step.y * i );
else
verts[vertCount].point = Point3F( origin.x, origin.y + size.x, start + step.y * i );
verts[vertCount].color = color;
++vertCount;
}
@ -1629,7 +1813,7 @@ void GFXDrawUtil::drawTransform( const GFXStateBlockDesc &desc, const MatrixF &m
GFXVertexBufferHandle<GFXVertexPCT> verts( mDevice, 6, GFXBufferTypeVolatile );
verts.lock();
const static ColorI defColors[3] =
const static ColorI defColors[3] =
{
ColorI::RED,
ColorI::GREEN,
@ -1655,7 +1839,7 @@ void GFXDrawUtil::drawTransform( const GFXStateBlockDesc &desc, const MatrixF &m
{
verts[1].point *= *scale;
verts[3].point *= *scale;
verts[5].point *= *scale;
verts[5].point *= *scale;
}
verts.unlock();

View file

@ -31,12 +31,12 @@
#include "math/mPolyhedron.h"
#endif
class FontRenderBatcher;
class Frustum;
/// Helper class containing utility functions for useful drawing routines
/// (line, box, rect, billboard, text).
class GFXDrawUtil
@ -46,22 +46,36 @@ public:
~GFXDrawUtil();
//-----------------------------------------------------------------------------
// Draw Rectangles
// Draw Rectangles : OUTLINE
//-----------------------------------------------------------------------------
void drawRect( const Point2F &upperLeft, const Point2F &lowerRight, 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 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 );
void drawRect(const Point2F& upperLeft, const Point2F& lowerRight, 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 RectI& rect, const ColorI& color);
//-----------------------------------------------------------------------------
// 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 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 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
//-----------------------------------------------------------------------------
@ -92,7 +113,7 @@ public:
//-----------------------------------------------------------------------------
// Draw Bitmaps
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void drawBitmap( GFXTextureObject*texture, const Point2F &in_rAt, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
void drawBitmapSR( GFXTextureObject*texture, const Point2F &in_rAt, const RectF &srcRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
void drawBitmapStretch( GFXTextureObject*texture, const RectF &dstRect, const GFXBitmapFlip in_flip = GFXBitmapFlip_None, const GFXTextureFilterType filter = GFXTextureFilterPoint , bool in_wrap = true, F32 angle = 0.0f);
@ -108,15 +129,15 @@ public:
//-----------------------------------------------------------------------------
void drawTriangle( const GFXStateBlockDesc &desc, const Point3F &p0, const Point3F &p1, const Point3F &p2, const ColorI &color, const MatrixF *xfm = NULL );
void drawPolygon( const GFXStateBlockDesc& desc, const Point3F* points, U32 numPoints, const ColorI& color, const MatrixF* xfm = NULL );
void drawCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
void drawCube( const GFXStateBlockDesc &desc, const Box3F &box, const ColorI &color, const MatrixF *xfm = NULL );
void drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const MatrixF &objMat, const ColorI &color );
void drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop = true, bool drawBottom = true, const MatrixF *xfm = NULL );
void drawCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm = NULL );
void drawCube( const GFXStateBlockDesc &desc, const Box3F &box, const ColorI &color, const MatrixF *xfm = NULL );
void drawObjectBox( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const MatrixF &objMat, const ColorI &color );
void drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop = true, bool drawBottom = true, const MatrixF *xfm = NULL );
void drawCapsule( const GFXStateBlockDesc &desc, const Point3F &center, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm = NULL );
void drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
void drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
void drawCone( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
void drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 baseRadius, const ColorI &color );
void drawArrow( const GFXStateBlockDesc &desc, const Point3F &start, const Point3F &end, const ColorI &color, F32 baseRad = 0.0f);
void drawFrustum( const Frustum& f, const ColorI &color );
void drawFrustum( const Frustum& f, const ColorI &color );
/// Draw a solid or wireframe (depending on fill mode of @a desc) polyhedron with the given color.
///
@ -128,7 +149,7 @@ public:
/// Draws a solid XY plane centered on the point with the specified dimensions.
void drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const ColorI &color );
enum Plane
{
PlaneXY,
@ -142,7 +163,7 @@ public:
/// Draws axis lines representing the passed matrix.
/// If scale is NULL axes will be drawn the length they exist within the MatrixF.
/// If colors is NULL the default colors are RED, GREEEN, BLUE ( x, y, z ).
void drawTransform( const GFXStateBlockDesc &desc, const MatrixF &mat, const Point3F *scale = NULL, const ColorI colors[3] = NULL );
void drawTransform( const GFXStateBlockDesc &desc, const MatrixF &mat, const Point3F *scale = NULL, const ColorI colors[3] = NULL );
protected:
@ -174,8 +195,21 @@ protected:
GFXStateBlockRef mBitmapStretchWrapSB;
GFXStateBlockRef mBitmapStretchWrapLinearSB;
GFXStateBlockRef mRectFillSB;
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_

View file

@ -64,7 +64,7 @@ enum GFXTexCallbackCode
GFXResurrect,
};
enum GFXPrimitiveType
enum GFXPrimitiveType
{
GFXPT_FIRST = 0,
GFXPointList = 0,
@ -75,7 +75,7 @@ enum GFXPrimitiveType
GFXPT_COUNT
};
enum GFXBitmapFlip
enum GFXBitmapFlip
{
GFXBitmapFlip_None = 0,
GFXBitmapFlip_X = 1 << 0,
@ -83,7 +83,7 @@ enum GFXBitmapFlip
GFXBitmapFlip_XY = GFXBitmapFlip_X | GFXBitmapFlip_Y
};
enum GFXTextureAddressMode
enum GFXTextureAddressMode
{
GFXAddress_FIRST = 0,
GFXAddressWrap = 0,
@ -94,7 +94,7 @@ enum GFXTextureAddressMode
GFXAddress_COUNT
};
enum GFXTextureFilterType
enum GFXTextureFilterType
{
GFXTextureFilter_FIRST = 0,
GFXTextureFilterNone = 0,
@ -104,7 +104,7 @@ enum GFXTextureFilterType
GFXTextureFilter_COUNT
};
enum GFXFillMode
enum GFXFillMode
{
GFXFill_FIRST = 1,
GFXFillPoint = 1,
@ -113,7 +113,7 @@ enum GFXFillMode
GFXFill_COUNT
};
enum GFXFormat
enum GFXFormat
{
// when adding formats make sure to place
// them in the correct group!
@ -152,7 +152,7 @@ enum GFXFormat
GFXFormatR11G11B10,
GFXFormatD32,
GFXFormatD24X8,
GFXFormatD24S8,
GFXFormatD24S8,
GFXFormatD24FS8,
// Guaranteed RGBA8 (for apis which really dont like bgr)
@ -172,7 +172,7 @@ enum GFXFormat
GFXFormatBC3, //dxt4/5
GFXFormatBC4, //3dc+ / ati1
GFXFormatBC5, //3dc / ati2
// compressed sRGB formats
// compressed sRGB formats
GFXFormatBC1_SRGB,
GFXFormatBC2_SRGB,
GFXFormatBC3_SRGB,
@ -191,7 +191,7 @@ enum GFXFormat
/// Returns the byte size of the pixel for non-compressed formats.
inline U32 GFXFormat_getByteSize( GFXFormat format )
{
AssertFatal( format < GFXFormat_UNKNOWNSIZE,
AssertFatal( format < GFXFormat_UNKNOWNSIZE,
"GFXDevice::formatByteSize - Cannot size a compressed format!" );
if ( format < GFXFormat_16BIT )
@ -205,12 +205,12 @@ inline U32 GFXFormat_getByteSize( GFXFormat format )
else if ( format < GFXFormat_128BIT )
return 8;// 64 bit...
// This should be 128bits... else its a DDS and
// This should be 128bits... else its a DDS and
// the assert should have gone off above.
return 16;
}
enum GFXClearFlags
enum GFXClearFlags
{
GFXClearTarget = 1 << 0,
GFXClearZBuffer = 1 << 1,
@ -218,7 +218,7 @@ enum GFXClearFlags
};
/// The supported blend modes.
enum GFXBlend
enum GFXBlend
{
GFXBlend_FIRST = 0,
GFXBlendZero = 0, /// (0, 0, 0, 0)
@ -238,7 +238,7 @@ enum GFXBlend
/// Constants that name each GFXDevice type. Any new GFXDevice subclass must be
/// added to this enum. A string representing its name must also be added to
/// GFXInit::getAdapterNameFromType().
enum GFXAdapterType
enum GFXAdapterType
{
OpenGL = 0,
Direct3D11,
@ -255,7 +255,7 @@ enum GFXCullMode
GFXCull_COUNT
};
enum GFXCmpFunc
enum GFXCmpFunc
{
GFXCmp_FIRST = 0,
GFXCmpNever = 0,
@ -269,7 +269,7 @@ enum GFXCmpFunc
GFXCmp_COUNT
};
enum GFXStencilOp
enum GFXStencilOp
{
GFXStencilOp_FIRST = 0,
GFXStencilOpKeep = 0,
@ -283,8 +283,8 @@ enum GFXStencilOp
GFXStencilOp_COUNT
};
enum GFXBlendOp
{
enum GFXBlendOp
{
GFXBlendOp_FIRST = 0,
GFXBlendOpAdd = 0,
GFXBlendOpSubtract,
@ -294,7 +294,7 @@ enum GFXBlendOp
GFXBlendOp_COUNT
};
enum GFXMatrixType
enum GFXMatrixType
{
GFXMatrixWorld = 256,
GFXMatrixView = 2,
@ -312,25 +312,39 @@ enum GFXMatrixType
enum GFXShaderConstType
{
GFXSCT_Uknown,
/// GFX"S"hader"C"onstant"T"ype
GFXSCT_ConstBuffer,
// Scalar
GFXSCT_Float,
GFXSCT_Float,
// Vectors
GFXSCT_Float2,
GFXSCT_Float3,
GFXSCT_Float4,
GFXSCT_Float2,
GFXSCT_Float3,
GFXSCT_Float4,
// Matrices
GFXSCT_Float2x2,
GFXSCT_Float2x2,
GFXSCT_Float3x3,
GFXSCT_Float3x4,
GFXSCT_Float4x3,
GFXSCT_Float4x4,
GFXSCT_Float4x4,
// Scalar
GFXSCT_Int,
GFXSCT_Int,
// Vectors
GFXSCT_Int2,
GFXSCT_Int3,
GFXSCT_Int4,
GFXSCT_Int2,
GFXSCT_Int3,
GFXSCT_Int4,
// Scalar
GFXSCT_UInt,
// Vectors
GFXSCT_UInt2,
GFXSCT_UInt3,
GFXSCT_UInt4,
// Scalar
GFXSCT_Bool,
// Vectors
GFXSCT_Bool2,
GFXSCT_Bool3,
GFXSCT_Bool4,
// Samplers
GFXSCT_Sampler,
GFXSCT_SamplerCube,
@ -352,7 +366,7 @@ enum GFXDeclType
/// @see Point2F
GFXDeclType_Float2,
/// A three-component F32.
/// A three-component F32.
/// @see Point3F
GFXDeclType_Float3,

View file

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

View file

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

View file

@ -57,7 +57,7 @@
#include "gfx/gl/tGL/tXGL.h"
#endif
GFXAdapter::CreateDeviceInstanceDelegate GFXGLDevice::mCreateDeviceInstance(GFXGLDevice::createInstance);
GFXAdapter::CreateDeviceInstanceDelegate GFXGLDevice::mCreateDeviceInstance(GFXGLDevice::createInstance);
GFXDevice *GFXGLDevice::createInstance( U32 adapterIndex )
{
@ -76,7 +76,7 @@ void loadGLCore()
if(coreLoaded)
return;
coreLoaded = true;
// Make sure we've got our GL bindings.
GL::gglPerformBinds();
}
@ -87,11 +87,11 @@ void loadGLExtensions(void *context)
if(extensionsLoaded)
return;
extensionsLoaded = true;
GL::gglPerformExtensionBinds(context);
}
void STDCALL glDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
void STDCALL glDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
// JTH [11/24/2016]: This is a temporary fix so that we do not get spammed for redundant fbo changes.
@ -118,24 +118,24 @@ void STDCALL glAmdDebugCallback(GLuint id, GLenum category, GLenum severity, GLs
}
void GFXGLDevice::initGLState()
{
{
// We don't currently need to sync device state with a known good place because we are
// going to set everything in GFXGLStateBlock, but if we change our GFXGLStateBlock strategy, this may
// need to happen.
// Deal with the card profiler here when we know we have a valid context.
mCardProfiler = new GFXGLCardProfiler();
mCardProfiler->init();
mCardProfiler->init();
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&mMaxShaderTextures);
// JTH: Needs removed, ffp
//glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&mMaxFFTextures);
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, (GLint*)&mMaxTRColors);
mMaxTRColors = getMin( mMaxTRColors, (U32)(GFXTextureTarget::MaxRenderSlotId-1) );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// [JTH 5/6/2016] GLSL 1.50 is really SM 4.0
// Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run.
// Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run.
mPixelShaderVersion = 3.0;
// Set capability extensions.
@ -150,7 +150,7 @@ void GFXGLDevice::initGLState()
String vendorStr = (const char*)glGetString( GL_VENDOR );
if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos)
mUseGlMap = false;
// Workaround for all Mac's, has a problem using glMap* with volatile buffers
#ifdef TORQUE_OS_MAC
mUseGlMap = false;
@ -173,7 +173,7 @@ void GFXGLDevice::initGLState()
else if(gglHasExtension(AMD_debug_output))
{
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallbackAMD(glAmdDebugCallback, NULL);
glDebugMessageCallbackAMD(glAmdDebugCallback, NULL);
//glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
GLuint unusedIds = 0;
glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0,&unusedIds, GL_TRUE);
@ -258,16 +258,17 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
mModelViewProjSC[i] = NULL;
mOpenglStateCache = new GFXGLStateCache;
mCurrentConstBuffer = NULL;
}
GFXGLDevice::~GFXGLDevice()
{
mCurrentStateBlock = NULL;
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
mCurrentVB[i] = NULL;
mCurrentPB = NULL;
for(U32 i = 0; i < mVolatileVBs.size(); i++)
mVolatileVBs[i] = NULL;
for(U32 i = 0; i < mVolatilePBs.size(); i++)
@ -291,13 +292,18 @@ GFXGLDevice::~GFXGLDevice()
mTextureManager->kill();
}
// Free device buffers
DeviceBufferMap::Iterator bufferIter = mDeviceBufferMap.begin();
for (; bufferIter != mDeviceBufferMap.end(); ++bufferIter)
glDeleteBuffers(1, &bufferIter->value);
GFXResource* walk = mResourceListHead;
while(walk)
{
walk->zombify();
walk = walk->getNextResource();
}
if( mCardProfiler )
SAFE_DELETE( mCardProfiler );
@ -306,16 +312,33 @@ GFXGLDevice::~GFXGLDevice()
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()
{
mTextureManager->zombify();
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
if(mCurrentVB[i])
mCurrentVB[i]->finish();
if(mCurrentPB)
mCurrentPB->finish();
//mVolatileVBs.clear();
//mVolatilePBs.clear();
GFXResource* walk = mResourceListHead;
@ -334,12 +357,12 @@ void GFXGLDevice::resurrect()
walk->resurrect();
walk = walk->getNextResource();
}
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
for(int i = 0; i < VERTEX_STREAM_COUNT; ++i)
if(mCurrentVB[i])
mCurrentVB[i]->prepare();
if(mCurrentPB)
mCurrentPB->prepare();
mTextureManager->resurrect();
}
@ -366,7 +389,7 @@ GFXPrimitiveBuffer* GFXGLDevice::findVolatilePBO(U32 numIndices, U32 numPrimitiv
for(U32 i = 0; i < mVolatilePBs.size(); i++)
if((mVolatilePBs[i]->mIndexCount >= numIndices) && (mVolatilePBs[i]->getRefCount() == 1))
return mVolatilePBs[i];
// No existing PB, so create one
StrongRefPtr<GFXGLPrimitiveBuffer> buf(new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, GFXBufferTypeVolatile));
buf->registerResourceWithDevice(this);
@ -374,18 +397,18 @@ GFXPrimitiveBuffer* GFXGLDevice::findVolatilePBO(U32 numIndices, U32 numPrimitiv
return buf.getPointer();
}
GFXVertexBuffer *GFXGLDevice::allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
GFXVertexBuffer *GFXGLDevice::allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
GFXBufferType bufferType,
void* data )
void* data )
{
PROFILE_SCOPE(GFXGLDevice_allocVertexBuffer);
if(bufferType == GFXBufferTypeVolatile)
return findVolatileVBO(numVerts, vertexFormat, vertSize);
GFXGLVertexBuffer* buf = new GFXGLVertexBuffer( GFX, numVerts, vertexFormat, vertSize, bufferType );
buf->registerResourceWithDevice(this);
buf->registerResourceWithDevice(this);
if(data)
{
@ -398,10 +421,10 @@ GFXVertexBuffer *GFXGLDevice::allocVertexBuffer( U32 numVerts,
return buf;
}
GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data )
GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data )
{
GFXPrimitiveBuffer* buf;
if(bufferType == GFXBufferTypeVolatile)
{
buf = findVolatilePBO(numIndices, numPrimitives);
@ -411,7 +434,7 @@ GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPr
buf = new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType);
buf->registerResourceWithDevice(this);
}
if(data)
{
void* dest;
@ -430,7 +453,7 @@ void GFXGLDevice::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
{
// Reset the state the old VB required, then set the state the new VB requires.
if( mCurrentVB[stream] )
{
{
mCurrentVB[stream]->finish();
}
@ -460,10 +483,10 @@ void GFXGLDevice::setVertexStreamFrequency( U32 stream, U32 frequency )
}
GFXCubemap* GFXGLDevice::createCubemap()
{
{
GFXGLCubemap* cube = new GFXGLCubemap();
cube->registerResourceWithDevice(this);
return cube;
return cube;
};
GFXCubemapArray *GFXGLDevice::createCubemapArray()
@ -480,7 +503,7 @@ GFXTextureArray* GFXGLDevice::createTextureArray()
return textureArray;
}
void GFXGLDevice::endSceneInternal()
void GFXGLDevice::endSceneInternal()
{
// nothing to do for opengl
mCanCurrentlyRender = false;
@ -556,9 +579,9 @@ void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil
{
// Make sure we have flushed our render target state.
_updateRenderTargets();
bool writeAllColors = true;
bool zwrite = true;
bool zwrite = true;
bool writeAllStencil = true;
const GFXStateBlockDesc *desc = NULL;
if (mCurrentGLStateBlock)
@ -568,7 +591,7 @@ void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil
writeAllColors = desc->colorWriteRed && desc->colorWriteGreen && desc->colorWriteBlue && desc->colorWriteAlpha;
writeAllStencil = desc->stencilWriteMask == 0xFFFFFFFF;
}
glColorMask(true, true, true, true);
glDepthMask(true);
glStencilMask(0xFFFFFFFF);
@ -585,7 +608,7 @@ void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil
if(!writeAllColors)
glColorMask(desc->colorWriteRed, desc->colorWriteGreen, desc->colorWriteBlue, desc->colorWriteAlpha);
if(!zwrite)
glDepthMask(false);
@ -623,20 +646,20 @@ inline GLsizei GFXGLDevice::primCountToIndexCount(GFXPrimitiveType primType, U32
AssertFatal(false, "GFXGLDevice::primCountToIndexCount - unrecognized prim type");
break;
}
return 0;
}
GFXVertexDecl* GFXGLDevice::allocVertexDecl( const GFXVertexFormat *vertexFormat )
GFXVertexDecl* GFXGLDevice::allocVertexDecl( const GFXVertexFormat *vertexFormat )
{
PROFILE_SCOPE(GFXGLDevice_allocVertexDecl);
typedef Map<void*, GFXGLVertexDecl> GFXGLVertexDeclMap;
static GFXGLVertexDeclMap declMap;
static GFXGLVertexDeclMap declMap;
GFXGLVertexDeclMap::Iterator itr = declMap.find( (void*)vertexFormat->getDescription().c_str() ); // description string are interned, safe to use c_str()
if(itr != declMap.end())
return &itr->value;
GFXGLVertexDecl &decl = declMap[(void*)vertexFormat->getDescription().c_str()];
GFXGLVertexDecl &decl = declMap[(void*)vertexFormat->getDescription().c_str()];
decl.init(vertexFormat);
return &decl;
}
@ -652,7 +675,7 @@ inline void GFXGLDevice::preDrawPrimitive()
{
updateStates();
}
if(mCurrentShaderConstBuffer)
setShaderConstBufferInternal(mCurrentShaderConstBuffer);
@ -660,18 +683,18 @@ inline void GFXGLDevice::preDrawPrimitive()
{
AssertFatal(mCurrVertexDecl, "");
const GFXGLVertexDecl* decl = static_cast<const GFXGLVertexDecl*>(mCurrVertexDecl);
for(int i = 0; i < getNumVertexStreams(); ++i)
{
if(mCurrentVB[i])
{
mCurrentVB[i]->prepare(i, mCurrentVB_Divisor[i]); // GL_ARB_vertex_attrib_binding
mCurrentVB[i]->prepare(i, mCurrentVB_Divisor[i]); // GL_ARB_vertex_attrib_binding
decl->prepareBuffer_old( i, mCurrentVB[i]->mBuffer, mCurrentVB_Divisor[i] ); // old vertex buffer/format
}
}
decl->updateActiveVertexAttrib( GFXGL->getOpenglCache()->getCacheVertexAttribActive() );
}
decl->updateActiveVertexAttrib( GFXGL->getOpenglCache()->getCacheVertexAttribActive() );
}
mNeedUpdateVertexAttrib = false;
}
@ -682,26 +705,26 @@ inline void GFXGLDevice::postDrawPrimitive(U32 primitiveCount)
mDeviceStatistics.mPolyCount += primitiveCount;
}
void GFXGLDevice::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
void GFXGLDevice::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
{
preDrawPrimitive();
if(mCurrentVB[0])
vertexStart += mCurrentVB[0]->mBufferVertexOffset;
if(mDrawInstancesCount)
glDrawArraysInstanced(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount);
else
glDrawArrays(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount));
glDrawArrays(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount));
postDrawPrimitive(primitiveCount);
}
void GFXGLDevice::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
void GFXGLDevice::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount )
{
preDrawPrimitive();
@ -732,7 +755,7 @@ void GFXGLDevice::setTextureInternal(U32 textureUnit, const GFXTextureObject*tex
{
mActiveTextureType[textureUnit] = tex->getBinding();
tex->bind(textureUnit);
}
}
else if(mActiveTextureType[textureUnit] != GL_ZERO)
{
glActiveTexture(GL_TEXTURE0 + textureUnit);
@ -805,21 +828,21 @@ void GFXGLDevice::setClipRect( const RectI &inRect )
F32 r = F32(mClip.point.x + mClip.extent.x);
F32 b = F32(mClip.point.y + mClip.extent.y);
F32 t = F32(mClip.point.y);
// Set up projection matrix,
// Set up projection matrix,
//static Point4F pt;
pt.set(2.0f / (r - l), 0.0f, 0.0f, 0.0f);
mProjectionMatrix.setColumn(0, pt);
pt.set(0.0f, 2.0f / (t - b), 0.0f, 0.0f);
mProjectionMatrix.setColumn(1, pt);
pt.set(0.0f, 0.0f, 1.0f, 0.0f);
mProjectionMatrix.setColumn(2, pt);
pt.set((l + r) / (l - r), (t + b) / (b - t), 1.0f, 1.0f);
mProjectionMatrix.setColumn(3, pt);
MatrixF mTempMatrix(true);
setViewMatrix( mTempMatrix );
setWorldMatrix( mTempMatrix );
@ -844,7 +867,7 @@ void GFXGLDevice::setStateBlockInternal(GFXStateBlock* block, bool force)
GFXGLStateBlock* glCurrent = static_cast<GFXGLStateBlock*>(mCurrentStateBlock.getPointer());
if (force)
glCurrent = NULL;
glBlock->activate(glCurrent); // Doesn't use current yet.
mCurrentGLStateBlock = glBlock;
}
@ -863,19 +886,19 @@ GFXFence * GFXGLDevice::createFence()
GFXFence* fence = _createPlatformSpecificFence();
if(!fence)
fence = new GFXGeneralFence( this );
fence->registerResourceWithDevice(this);
return fence;
}
GFXOcclusionQuery* GFXGLDevice::createOcclusionQuery()
{
{
GFXOcclusionQuery *query = new GFXGLOcclusionQuery( this );
query->registerResourceWithDevice(this);
return query;
}
void GFXGLDevice::setupGenericShaders( GenericShaderType type )
void GFXGLDevice::setupGenericShaders( GenericShaderType type )
{
AssertFatal(type != GSTargetRestore, "");
@ -927,7 +950,7 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type )
Sim::getRootGroup()->addObject(shaderData);
}
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix);
setShader( mGenericShader[type] );
@ -959,8 +982,19 @@ void GFXGLDevice::setShader(GFXShader *shader, bool force)
void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
{
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal);
static_cast<GFXGLShaderConstBuffer*>(buffer)->activate();
if (buffer)
{
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
@ -968,7 +1002,7 @@ U32 GFXGLDevice::getNumSamplers() const
return getMin((U32)GFX_TEXTURE_STAGE_COUNT,mPixelShaderVersion > 0.001f ? mMaxShaderTextures : mMaxFFTextures);
}
GFXTextureObject* GFXGLDevice::getDefaultDepthTex() const
GFXTextureObject* GFXGLDevice::getDefaultDepthTex() const
{
if(mWindowRT && mWindowRT->getPointer())
return static_cast<GFXGLWindowTarget*>( mWindowRT->getPointer() )->mBackBufferDepthTex.getPointer();
@ -976,9 +1010,9 @@ GFXTextureObject* GFXGLDevice::getDefaultDepthTex() const
return NULL;
}
U32 GFXGLDevice::getNumRenderTargets() const
{
return mMaxTRColors;
U32 GFXGLDevice::getNumRenderTargets() const
{
return mMaxTRColors;
}
void GFXGLDevice::_updateRenderTargets()
@ -988,9 +1022,9 @@ void GFXGLDevice::_updateRenderTargets()
if ( mRTDeactivate )
{
mRTDeactivate->deactivate();
mRTDeactivate = NULL;
mRTDeactivate = NULL;
}
// NOTE: The render target changes is not really accurate
// as the GFXTextureTarget supports MRT internally. So when
// we activate a GFXTarget it could result in multiple calls
@ -1006,31 +1040,31 @@ void GFXGLDevice::_updateRenderTargets()
else
{
GFXGLWindowTarget *win = dynamic_cast<GFXGLWindowTarget*>( mCurrentRT.getPointer() );
AssertFatal( win != NULL,
AssertFatal( win != NULL,
"GFXGLDevice::_updateRenderTargets() - invalid target subclass passed!" );
win->makeActive();
if( win->mContext != static_cast<GFXGLDevice*>(GFX)->mContext )
{
mRTDirty = false;
GFX->updateStates(true);
}
}
mRTDirty = false;
}
if ( mViewportDirty )
{
glViewport( mViewport.point.x, mViewport.point.y, mViewport.extent.x, mViewport.extent.y );
glViewport( mViewport.point.x, mViewport.point.y, mViewport.extent.x, mViewport.extent.y );
mViewportDirty = false;
}
}
GFXFormat GFXGLDevice::selectSupportedFormat( GFXTextureProfile* profile,
const Vector<GFXFormat>& formats,
bool texture,
GFXFormat GFXGLDevice::selectSupportedFormat( GFXTextureProfile* profile,
const Vector<GFXFormat>& formats,
bool texture,
bool mustblend,
bool mustfilter )
{
@ -1041,10 +1075,10 @@ GFXFormat GFXGLDevice::selectSupportedFormat( GFXTextureProfile* profile,
continue;
if(GFXGLTextureInternalFormat[formats[i]] == GL_ZERO)
continue;
return formats[i];
}
return GFXFormatR8G8B8A8;
}
@ -1055,7 +1089,7 @@ U32 GFXGLDevice::getTotalVideoMemory_GL_EXT()
{
GLint mem[4] = {0};
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, mem); // Retrieve the texture pool
/* With mem[0] i get only the total memory free in the pool in KB
*
* mem[0] - total memory free in the pool
@ -1066,7 +1100,7 @@ U32 GFXGLDevice::getTotalVideoMemory_GL_EXT()
return mem[0] / 1024;
}
//source http://www.opengl.org/registry/specs/NVX/gpu_memory_info.txt
else if( gglHasExtension(NVX_gpu_memory_info) )
{

View file

@ -43,9 +43,11 @@ class GFXGLCubemap;
class GFXGLCubemapArray;
class GFXGLStateCache;
class GFXGLVertexDecl;
class GFXGLShaderConstBuffer;
class GFXGLDevice : public GFXDevice
{
public:
struct GLCapabilities
{
@ -59,6 +61,11 @@ public:
};
GLCapabilities mCapabilities;
// UBO map
typedef Map<String, GLuint> DeviceBufferMap;
// grab device buffer.
GLuint getDeviceBuffer(const GFXShaderConstDesc desc);
void zombify();
void resurrect();
GFXGLDevice(U32 adapterIndex);
@ -105,13 +112,13 @@ public:
/// @{
virtual F32 getPixelShaderVersion() const { return mPixelShaderVersion; }
virtual void setPixelShaderVersion( F32 version ) { mPixelShaderVersion = version; }
virtual void setShader(GFXShader *shader, bool force = false);
/// @attention GL cannot check if the given format supports blending or filtering!
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter);
/// Returns the number of texture samplers that can be used in a shader rendering pass
virtual U32 getNumSamplers() const;
@ -128,11 +135,11 @@ public:
virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount );
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount );
virtual void setClipRect( const RectI &rect );
@ -142,15 +149,15 @@ public:
virtual U32 getMaxDynamicVerts() { return GFX_MAX_DYNAMIC_VERTS; }
virtual U32 getMaxDynamicIndices() { return GFX_MAX_DYNAMIC_INDICES; }
GFXFence *createFence();
GFXOcclusionQuery* createOcclusionQuery();
GFXGLStateBlockRef getCurrentStateBlock() { return mCurrentGLStateBlock; }
virtual void setupGenericShaders( GenericShaderType type = GSColor );
///
bool supportsAnisotropic() const { return mCapabilities.anisotropicFiltering; }
@ -158,16 +165,16 @@ public:
GFXTextureObject* getDefaultDepthTex() const;
/// Returns the number of vertex streams supported by the device.
/// Returns the number of vertex streams supported by the device.
const U32 getNumVertexStreams() const { return mNumVertexStream; }
bool glUseMap() const { return mUseGlMap; }
bool glUseMap() const { return mUseGlMap; }
const char* interpretDebugResult(long result) { return "Not Implemented"; };
protected:
protected:
/// Called by GFXDevice to create a device specific stateblock
virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc);
/// Called by GFXDevice to actually set a stateblock.
virtual void setStateBlockInternal(GFXStateBlock* block, bool force);
virtual void setStateBlockInternal(GFXStateBlock* block, bool force);
/// Called by base GFXDevice to actually set a const buffer
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer);
@ -184,13 +191,13 @@ protected:
/// is created.
virtual void initStates() { }
virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
U32 vertSize,
GFXBufferType bufferType,
void* data = NULL);
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data = NULL );
// NOTE: The GL device doesn't need a vertex declaration at
// this time, but we need to return something to keep the system
// from retrying to allocate one on every call.
@ -199,11 +206,13 @@ protected:
virtual void setVertexDecl( const GFXVertexDecl *decl );
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:
typedef GFXDevice Parent;
friend class GFXGLTextureObject;
friend class GFXGLCubemap;
friend class GFXGLCubemapArray;
@ -215,18 +224,18 @@ private:
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
U32 mAdapterIndex;
StrongRefPtr<GFXGLVertexBuffer> mCurrentVB[VERTEX_STREAM_COUNT];
U32 mCurrentVB_Divisor[VERTEX_STREAM_COUNT];
bool mNeedUpdateVertexAttrib;
StrongRefPtr<GFXGLPrimitiveBuffer> mCurrentPB;
U32 mDrawInstancesCount;
GFXShader* mCurrentShader;
GFXShaderRef mGenericShader[GS_COUNT];
GFXShaderConstBufferRef mGenericShaderBuffer[GS_COUNT];
GFXShaderConstHandle *mModelViewProjSC[GS_COUNT];
/// Since GL does not have separate world and view matrices we need to track them
MatrixF m_mCurrentWorld;
MatrixF m_mCurrentView;
@ -237,34 +246,34 @@ private:
F32 mPixelShaderVersion;
U32 mNumVertexStream;
U32 mMaxShaderTextures;
U32 mMaxFFTextures;
U32 mMaxTRColors;
RectI mClip;
GFXGLStateBlockRef mCurrentGLStateBlock;
GLenum mActiveTextureType[GFX_TEXTURE_STAGE_COUNT];
Vector< StrongRefPtr<GFXGLVertexBuffer> > mVolatileVBs; ///< Pool of existing volatile VBs so we can reuse previously created ones
Vector< StrongRefPtr<GFXGLPrimitiveBuffer> > mVolatilePBs; ///< Pool of existing volatile PBs so we can reuse previously created ones
GLsizei primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount);
void preDrawPrimitive();
void postDrawPrimitive(U32 primitiveCount);
void postDrawPrimitive(U32 primitiveCount);
GFXVertexBuffer* findVolatileVBO(U32 numVerts, const GFXVertexFormat *vertexFormat, U32 vertSize); ///< Returns an existing volatile VB which has >= numVerts and the same vert flags/size, or creates a new VB if necessary
GFXPrimitiveBuffer* findVolatilePBO(U32 numIndices, U32 numPrimitives); ///< Returns an existing volatile PB which has >= numIndices, or creates a new PB if necessary
void vsyncCallback(); ///< Vsync callback
void initGLState(); ///< Guaranteed to be called after all extensions have been loaded, use to init card profiler, shader version, max samplers, etc.
GFXFence* _createPlatformSpecificFence(); ///< If our platform (e.g. OS X) supports a fence extenstion (e.g. GL_APPLE_fence) this will create one, otherwise returns NULL
void setPB(GFXGLPrimitiveBuffer* pb); ///< Sets mCurrentPB
GFXGLStateCache *mOpenglStateCache;

File diff suppressed because it is too large Load diff

View file

@ -29,15 +29,143 @@
#include "core/util/tSignal.h"
#include "core/util/tDictionary.h"
class GFXGLShaderConstHandle;
class FileStream;
class GFXGLShaderConstBuffer;
class GFXGLDevice;
class GFXGLShader;
struct BufferRange
{
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:
// DX side needs the description map as the same uniform can exist across stages. for gl it is program wide.
GFXGLShaderConstHandle(GFXGLShader* shader);
GFXGLShaderConstHandle(GFXGLShader* shader,
const GFXShaderConstDesc& desc);
void reinit(const GFXShaderConstDesc& desc);
virtual ~GFXGLShaderConstHandle();
const GFXShaderConstDesc getDesc();
const String& getName() const { return mDesc.name; }
GFXShaderConstType getType() const { return mDesc.constType; }
U32 getArraySize() const { return mDesc.arraySize; }
U32 getSize() const { return mDesc.size; }
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; }
// 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;
}
GFXShaderConstDesc mDesc;
GFXGLShader* mShader;
bool mUBOUniform;
bool mInstancingConstant;
};
class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
{
public:
// -1 is the global buffer.
typedef Map<S32, ConstantBuffer> BufferMap;
GFXGLShaderConstBuffer(GFXGLShader* shader);
~GFXGLShaderConstBuffer();
/// Called by GFXGLDevice to activate this buffer.
void activate(GFXGLShaderConstBuffer* prevShaderBuffer);
void addBuffer(const GFXShaderConstDesc desc);
/// Called when the shader this buffer references is reloaded.
void onShaderReload(GFXGLShader* shader);
// GFXShaderConstBuffer
virtual GFXShader* getShader();
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv);
virtual void set(GFXShaderConstHandle* handle, const S32 f);
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
// GFXResource
virtual const String describeSelf() const;
virtual void zombify() {}
virtual void resurrect() {}
private:
friend class GFXGLShader;
WeakRefPtr<GFXGLShader> mShader;
BufferMap mBufferMap;
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
};
class GFXGLShader : public GFXShader
{
typedef Map<String, GFXGLShaderConstHandle*> HandleMap;
friend class GFXGLShaderConstBuffer;
friend class GFXGLShaderConstHandle;
public:
typedef Map<String, GFXGLShaderConstHandle*> HandleMap;
typedef Map<String, GFXShaderConstDesc> BufferMap;
GFXGLShader(GFXGLDevice* device);
virtual ~GFXGLShader();
@ -50,111 +178,60 @@ public:
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
/// Returns the alignment value for constType
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
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();
friend class GFXGLShaderConstBuffer;
friend class GFXGLShaderConstHandle;
virtual bool _init();
bool initShader( const Torque::Path &file,
bool isVertex,
const Vector<GFXShaderMacro> &macros );
bool initShader(const Torque::Path& file,
GFXShaderStage stage,
const Vector<GFXShaderMacro>& macros);
void clearShaders();
void initConstantDescs();
void initHandles();
void setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer);
static char* _handleIncludes( const Torque::Path &path, FileStream *s );
void setConstantsFromBuffer(U8* buffer);
static bool _loadShaderFromStream( GLuint shader,
const Torque::Path& path,
FileStream* s,
const Vector<GFXShaderMacro>& macros );
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;
/// @}
Vector<GFXShaderConstDesc> mConstants;
U32 mConstBufferSize;
U8* mConstBuffer;
U8* mGlobalConstBuffer;
Vector<GFXShaderConstDesc> mShaderConsts;
HandleMap mHandles;
BufferMap mBuffers;
GFXGLDevice* mDevice;
Vector<GFXGLShaderConstHandle*> mValidHandles;
GFXShaderConstType convertConstType(GLenum constType);
};
class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
{
public:
GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants);
~GFXGLShaderConstBuffer();
/// Called by GFXGLDevice to activate this buffer.
void activate();
/// Called when the shader this buffer references is reloaded.
void onShaderReload( GFXGLShader *shader );
// GFXShaderConstBuffer
virtual GFXShader* getShader() { return mShader; }
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv);
virtual void set(GFXShaderConstHandle* handle, const S32 f);
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
// GFXResource
virtual const String describeSelf() const;
virtual void zombify() {}
virtual void resurrect() {}
private:
friend class GFXGLShader;
U8* mBuffer;
WeakRefPtr<GFXGLShader> mShader;
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
};
#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 "gfx/sim/gfxStateBlockData.h"
#include "core/util/safeDelete.h"
#include "gfx/genericConstBuffer.h"
#include "console/simFieldDictionary.h"
#include "console/propertyParsing.h"
#include "gfx/util/screenspace.h"

View file

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

View file

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

View file

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

View file

@ -1,19 +1,19 @@
// Original code is:
// Copyright (c) 2005 Intel Corporation
// Copyright (c) 2005 Intel Corporation
// All Rights Reserved
//
// CPUCount.cpp : Detects three forms of hardware multi-threading support across IA-32 platform
// The three forms of HW multithreading are: Multi-processor, Multi-core, and
// The three forms of HW multithreading are: Multi-processor, Multi-core, and
// HyperThreading Technology.
// This application enumerates all the logical processors enabled by OS and BIOS,
// determine the HW topology of these enabled logical processors in the system
// determine the HW topology of these enabled logical processors in the system
// using information provided by CPUID instruction.
// A multi-processing system can support any combination of the three forms of HW
// multi-threading support. The relevant topology can be identified using a
// three level decomposition of the "initial APIC ID" into
// Package_id, core_id, and SMT_id. Such decomposition provides a three-level map of
// multi-threading support. The relevant topology can be identified using a
// three level decomposition of the "initial APIC ID" into
// Package_id, core_id, and SMT_id. Such decomposition provides a three-level map of
// the topology of hardware resources and
// allow multi-threaded software to manage shared hardware resources in
// allow multi-threaded software to manage shared hardware resources in
// the platform to reduce resource contention
// Multicore detection algorithm for processor and cache topology requires
@ -60,25 +60,25 @@ namespace CPUInfo {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
DWORD returnLength = 0;
// get buffer length
DWORD rc = GetLogicalProcessorInformation( buffer, &returnLength );
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc( returnLength );
rc = GetLogicalProcessorInformation( buffer, &returnLength );
rc = GetLogicalProcessorInformation( buffer, &returnLength );
// if we fail, assume single threaded
if( FALSE == rc )
{
{
free( buffer );
Con::errorf("Unable to determine CPU Count, assuming 1 core");
TotAvailCore = 1;
TotAvailLogical = 1;
return CONFIG_SingleCoreAndHTNotCapable;
}
}
#pragma push
#pragma warning (disable: 6011)
#pragma warning( push )
#pragma warning( disable: 6011 )
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
DWORD byteOffset = 0;
@ -95,7 +95,7 @@ namespace CPUInfo {
}
free( buffer );
#pragma pop
#pragma warning( pop )
EConfig StatusFlag = CONFIG_SingleCoreAndHTNotCapable;

View file

@ -5,7 +5,7 @@
/// allows it to return the appropriate geometry.
enum PolyListContext
{
/// A hint that the polyist is intended
/// A hint that the polyist is intended
/// for collision testing.
PLC_Collision,
@ -24,7 +24,7 @@ enum PolyListContext
/// A hint that the polyist will be used
/// to export geometry and would like to have
/// texture coords and materials.
/// texture coords and materials.
PLC_Export
};
@ -71,7 +71,7 @@ struct SceneBinRange
inline bool isGlobal() const
{
return minCoord[0] == 0 &&
minCoord[0] == 0 &&
minCoord[1] == 0 &&
maxCoord[0] == 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])
return;
MultiLine* meta = new MultiLine;
MultiLine* newMeta = new MultiLine;
// Now the wsPosition and wsView.
Var* worldToTangent = getInWorldToTangent(componentList);
Var* wsNormal = getInWorldNormal(componentList);
Var* wsPosition = getInWsPosition(componentList);
Var* wsView = getWsView(wsPosition, meta);
Var* wsView = getWsView(wsPosition, newMeta);
//Reflection Probe WIP
U32 MAX_FORWARD_PROBES = 4;
@ -153,32 +153,32 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
Var* showAttenVar = new Var("showAttenVar", "int");
char buf[64];
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");
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");
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");
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");
computeForwardProbes += String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t");
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,
irradianceCubemapAR, specularCubemapAR,
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;
}
}

View file

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

View file

@ -149,4 +149,42 @@ singleton ShaderData( CubemapSaveShader )
samplerNames[0] = "$cubemapTex";
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";
};
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 )
{
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)
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_SOURCES3 "forest/editor/*.cpp" "forest/editor/*.h")