mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-28 16:49:43 +00:00
Merge pull request #1223 from marauder2k9-torque/ShaderConstBuffer-CleanupRefactor
GFX Shader Refactor
This commit is contained in:
commit
b624ec230a
45 changed files with 5021 additions and 2996 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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 ¢er, 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();
|
||||
|
|
|
|||
|
|
@ -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 ¢er, 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_
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
|
|
@ -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> ¯os )
|
||||
{
|
||||
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> ¯os,
|
||||
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" )
|
||||
|
|
|
|||
|
|
@ -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> ¯os );
|
||||
#endif
|
||||
|
||||
///
|
||||
bool init( const Torque::Path &vertFile,
|
||||
const Torque::Path &pixFile,
|
||||
F32 pixVersion,
|
||||
bool init( F32 pixVersion,
|
||||
const Vector<GFXShaderMacro> ¯os,
|
||||
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(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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> ¯os );
|
||||
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_
|
||||
|
|
|
|||
1003
Engine/source/gui/shaderEditor/guiShaderEditor.cpp
Normal file
1003
Engine/source/gui/shaderEditor/guiShaderEditor.cpp
Normal file
File diff suppressed because it is too large
Load diff
147
Engine/source/gui/shaderEditor/guiShaderEditor.h
Normal file
147
Engine/source/gui/shaderEditor/guiShaderEditor.h
Normal 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_
|
||||
203
Engine/source/gui/shaderEditor/guiShaderNode.cpp
Normal file
203
Engine/source/gui/shaderEditor/guiShaderNode.cpp
Normal 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)
|
||||
{
|
||||
}
|
||||
159
Engine/source/gui/shaderEditor/guiShaderNode.h
Normal file
159
Engine/source/gui/shaderEditor/guiShaderNode.h
Normal 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_
|
||||
51
Engine/source/gui/shaderEditor/nodes/materialOutputNode.cpp
Normal file
51
Engine/source/gui/shaderEditor/nodes/materialOutputNode.cpp
Normal 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";
|
||||
}
|
||||
39
Engine/source/gui/shaderEditor/nodes/materialOutputNode.h
Normal file
39
Engine/source/gui/shaderEditor/nodes/materialOutputNode.h
Normal 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.");
|
||||
};
|
||||
49
Engine/source/gui/shaderEditor/nodes/mathNode.cpp
Normal file
49
Engine/source/gui/shaderEditor/nodes/mathNode.cpp
Normal 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";
|
||||
}
|
||||
39
Engine/source/gui/shaderEditor/nodes/mathNode.h
Normal file
39
Engine/source/gui/shaderEditor/nodes/mathNode.h
Normal 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.");
|
||||
};
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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> ¯os )
|
|||
|
||||
// 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> ¯os )
|
|||
{
|
||||
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> ¯os )
|
|||
|
||||
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> ¯os )
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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> ¯os,
|
||||
String *outString );
|
||||
void _stringizeMacros(const Vector<GFXShaderMacro>& macros,
|
||||
String* outString);
|
||||
|
||||
/// Creates a new shader returning NULL on error.
|
||||
GFXShader* _createShader( const Vector<GFXShaderMacro> ¯os );
|
||||
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> ¯os = 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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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> ¯os, 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> ¯os, 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> ¯os, 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
<GUIAsset
|
||||
canSave="true"
|
||||
canSaveDynamicFields="true"
|
||||
AssetName="ShaderEditorGui, EditorGuiGroup"
|
||||
scriptFile="@assetFile=shaderEditorGui.ed.gui"
|
||||
GUIFile="@assetFile=shaderEditorGui.ed.gui"
|
||||
VersionId="1"/>
|
||||
|
|
@ -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 ---
|
||||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue