| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- #include "CmDeferredRenderSystem.h"
- #include "CmDeferredGpuCommands.h"
- #include "CmRenderSystemManager.h"
- #include "CmException.h"
- namespace CamelotEngine
- {
- DeferredRenderSystem::DeferredRenderSystem(CM_THREAD_ID_TYPE threadId)
- :mMyThreadId(threadId), mReadyRenderCommandBuffer(nullptr)
- {
- mActiveRenderCommandBuffer = new vector<DeferredGpuCommand*>::type();
- }
- DeferredRenderSystem::~DeferredRenderSystem()
- {
- CM_LOCK_MUTEX(mCommandBufferMutex)
- if(mReadyRenderCommandBuffer != nullptr)
- {
- for(auto iter = mReadyRenderCommandBuffer->begin(); iter != mReadyRenderCommandBuffer->end(); ++iter)
- delete *iter;
- delete mReadyRenderCommandBuffer;
- mReadyRenderCommandBuffer = nullptr;
- }
- if(mActiveRenderCommandBuffer != nullptr)
- {
- for(auto iter = mActiveRenderCommandBuffer->begin(); iter != mActiveRenderCommandBuffer->end(); ++iter)
- delete *iter;
- delete mActiveRenderCommandBuffer;
- mActiveRenderCommandBuffer = nullptr;
- }
- }
- void DeferredRenderSystem::render(const RenderOperation& op)
- {
- throwIfInvalidThread();
- RenderOperation opCopy = op;
- DfrdRenderGpuCommand* newCommand = new DfrdRenderGpuCommand(opCopy);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::bindGpuProgram(GpuProgramRef prg)
- {
- throwIfInvalidThread();
- DfrdBindGpuProgramCommand* newCommand = new DfrdBindGpuProgramCommand(prg);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::unbindGpuProgram(GpuProgramType gptype)
- {
- throwIfInvalidThread();
- DfrdUnbindGpuProgramCommand* newCommand = new DfrdUnbindGpuProgramCommand(gptype);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params)
- {
- throwIfInvalidThread();
- // We need to copy the constant buffers in order to prevent the user from modifying the parameters before rendering is done.
- // Because of the way how GpuProgramParameters copy constructor works, only constants are copied and rest of the data is shared.
- // Shared data is data that is only modified on shader change, and that should only occur on render thread, so it won't interfere
- // with rendering.
- GpuProgramParametersSharedPtr paramCopy = GpuProgramParametersSharedPtr(new GpuProgramParameters(*params));
- DfrdBindGpuParamsCommand* newCommand = new DfrdBindGpuParamsCommand(gptype, paramCopy);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::setInvertVertexWinding(bool invert)
- {
- throwIfInvalidThread();
- DfrdInvVertWindingCommand* newCommand = new DfrdInvVertWindingCommand(invert);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right, size_t bottom)
- {
- throwIfInvalidThread();
- DfrdScissorTestCommand* newCommand = new DfrdScissorTestCommand(enabled, left, top, right, bottom);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setStencilBufferParams(CompareFunction func, UINT32 refValue, UINT32 mask,
- StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation)
- {
- throwIfInvalidThread();
- DfrdStencilBufferParamsCommand* newCommand = new DfrdStencilBufferParamsCommand(func, refValue, mask, stencilFailOp, depthFailOp, passOp, twoSidedOperation);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::setVertexDeclaration(VertexDeclarationPtr decl)
- {
- throwIfInvalidThread();
- DfrdVertexDeclCommand* newCommand = new DfrdVertexDeclCommand();
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
- {
- throwIfInvalidThread();
- DfrdVertBufferBindCommand* newCommand = new DfrdVertBufferBindCommand();
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setPolygonMode(PolygonMode mode)
- {
- throwIfInvalidThread();
- DfrdPolygonModeCommand* newCommand = new DfrdPolygonModeCommand(mode);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setStencilCheckEnabled(bool enabled)
- {
- throwIfInvalidThread();
- DfrdStencilCheckCommand* newCommand = new DfrdStencilCheckCommand(enabled);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setWaitForVerticalBlank(bool enabled)
- {
- throwIfInvalidThread();
- DfrdWaitForVerticalBlankCommand* newCommand = new DfrdWaitForVerticalBlankCommand(enabled);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureUnitSettings(size_t texUnit, const TexturePtr& texture, const SamplerState& samplerState)
- {
- throwIfInvalidThread();
- DfrdTextureUnitSettingsCommand* newCommand = new DfrdTextureUnitSettingsCommand(texUnit, texture, samplerState);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setPointParameters(float size, bool attenuationEnabled,
- float constant, float linear, float quadratic, float minSize, float maxSize)
- {
- throwIfInvalidThread();
- DfrdPointParamsCommand* newCommand = new DfrdPointParamsCommand(size, attenuationEnabled, constant, linear, quadratic, minSize, maxSize);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTexture(size_t unit, bool enabled, const TexturePtr &texPtr)
- {
- throwIfInvalidThread();
- DfrdTextureCommand* newCommand = new DfrdTextureCommand(unit, enabled, texPtr);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setVertexTexture(size_t unit, const TexturePtr& tex)
- {
- throwIfInvalidThread();
- DfrdVertexTextureCommand* newCommand = new DfrdVertexTextureCommand(unit, tex);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureFiltering(size_t unit, FilterOptions minFilter,
- FilterOptions magFilter, FilterOptions mipFilter)
- {
- throwIfInvalidThread();
- setTextureFiltering(unit, FT_MIN, minFilter);
- setTextureFiltering(unit, FT_MAG, magFilter);
- setTextureFiltering(unit, FT_MIP, mipFilter);
- }
-
- void DeferredRenderSystem::setTextureFiltering(size_t unit, FilterType ftype, FilterOptions filter)
- {
- throwIfInvalidThread();
- DfrdTextureFilteringCommand* newCommand = new DfrdTextureFilteringCommand(unit, ftype, filter);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureAnisotropy(size_t unit, unsigned int maxAnisotropy)
- {
- throwIfInvalidThread();
- DfrdTextureAnisotropyCommand* newCommand = new DfrdTextureAnisotropyCommand(unit, maxAnisotropy);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureAddressingMode(size_t unit, const SamplerState::UVWAddressingMode& uvw)
- {
- throwIfInvalidThread();
- DfrdTextureAddrModeCommand* newCommand = new DfrdTextureAddrModeCommand(unit, uvw);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureBorderColor(size_t unit, const Color& color)
- {
- throwIfInvalidThread();
- DfrdTextureBorderColorCommand* newCommand = new DfrdTextureBorderColorCommand(unit, color);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setTextureMipmapBias(size_t unit, float bias)
- {
- throwIfInvalidThread();
- DfrdTextureMipBiasCommand* newCommand = new DfrdTextureMipBiasCommand(unit, bias);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op)
- {
- throwIfInvalidThread();
- DfrdSceneBlendingCommand* newCommand = new DfrdSceneBlendingCommand(sourceFactor, destFactor, op);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha,
- SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp)
- {
- throwIfInvalidThread();
- DfrdSeparateSceneBlendingCommand* newCommand = new DfrdSeparateSceneBlendingCommand(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha, op, alphaOp);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage)
- {
- throwIfInvalidThread();
- DfrdAlphaRejectParamsCommand* newCommand = new DfrdAlphaRejectParamsCommand(func, value, alphaToCoverage);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setViewport(const Viewport& vp)
- {
- throwIfInvalidThread();
- DfrdViewportCommand* newCommand = new DfrdViewportCommand(vp);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setCullingMode(CullingMode mode)
- {
- throwIfInvalidThread();
- DfrdCullingCommand* newCommand = new DfrdCullingCommand(mode);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
- {
- throwIfInvalidThread();
- DfrdDepthBufferParamsCommand* newCommand = new DfrdDepthBufferParamsCommand(depthTest, depthWrite, depthFunction);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setDepthBufferCheckEnabled(bool enabled)
- {
- throwIfInvalidThread();
- DfrdDepthBufferCheckCommand* newCommand = new DfrdDepthBufferCheckCommand(enabled);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setDepthBufferWriteEnabled(bool enabled)
- {
- throwIfInvalidThread();
- DfrdDepthBufferWriteCommand* newCommand = new DfrdDepthBufferWriteCommand(enabled);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setDepthBufferFunction(CompareFunction func)
- {
- throwIfInvalidThread();
- DfrdDepthBufferFuncCommand* newCommand = new DfrdDepthBufferFuncCommand(func);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::setDepthBias(float constantBias, float slopeScaleBias)
- {
- throwIfInvalidThread();
- DfrdDepthBiasCommand* newCommand = new DfrdDepthBiasCommand(constantBias, slopeScaleBias);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
- {
- throwIfInvalidThread();
- DfrdColorBufferWriteCommand* newCommand = new DfrdColorBufferWriteCommand(red, green, blue, alpha);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::disableTextureUnit(size_t texUnit)
- {
- throwIfInvalidThread();
- DfrdDisableTextureUnitCommand* newCommand = new DfrdDisableTextureUnitCommand(texUnit);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
-
- void DeferredRenderSystem::disableTextureUnitsFrom(size_t texUnit)
- {
- throwIfInvalidThread();
- DfrdDisableTextureUnitsFromCommand* newCommand = new DfrdDisableTextureUnitsFromCommand(texUnit);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::beginFrame(void)
- {
- throwIfInvalidThread();
- DfrdBeginFrameCommand* newCommand = new DfrdBeginFrameCommand();
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::endFrame(void)
- {
- throwIfInvalidThread();
- DfrdEndFrameCommand* newCommand = new DfrdEndFrameCommand();
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::clearFrameBuffer(unsigned int buffers,
- const Color& color, float depth, unsigned short stencil)
- {
- throwIfInvalidThread();
- DfrdClearFrameBufferCommand* newCommand = new DfrdClearFrameBufferCommand(buffers, color, depth, stencil);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::swapAllRenderTargetBuffers(bool waitForVsync)
- {
- throwIfInvalidThread();
- DfrdSwapAllRenderTargetBuffersCommand* newCommand = new DfrdSwapAllRenderTargetBuffersCommand(waitForVsync);
- mActiveRenderCommandBuffer->push_back(newCommand);
- }
- void DeferredRenderSystem::submitToGpu()
- {
- {
- CM_LOCK_MUTEX(mCommandBufferMutex)
- if(mReadyRenderCommandBuffer != nullptr)
- {
- for(auto iter = mReadyRenderCommandBuffer->begin(); iter != mReadyRenderCommandBuffer->end(); ++iter)
- delete *iter;
- delete mReadyRenderCommandBuffer;
- mReadyRenderCommandBuffer = nullptr;
- }
- mReadyRenderCommandBuffer = mActiveRenderCommandBuffer;
- mActiveRenderCommandBuffer = new vector<DeferredGpuCommand*>::type();
- }
- }
- void DeferredRenderSystem::playbackCommands()
- {
- RenderSystem* rs = RenderSystemManager::getActive();
- if(rs->getRenderThreadId() != CM_THREAD_CURRENT_ID)
- CM_EXCEPT(InternalErrorException, "This method should only be called from the render thread.");
- vector<DeferredGpuCommand*>::type* currentCommands = nullptr;
- {
- CM_LOCK_MUTEX(mCommandBufferMutex)
- currentCommands = mReadyRenderCommandBuffer;
- mReadyRenderCommandBuffer = nullptr;
- }
- if(currentCommands == nullptr)
- return;
- for(auto iter = currentCommands->begin(); iter != currentCommands->end(); ++iter)
- {
- (*iter)->submitCommand(rs);
- delete *iter;
- }
- delete currentCommands;
- }
- bool DeferredRenderSystem::hasReadyCommands()
- {
- CM_LOCK_MUTEX(mCommandBufferMutex)
- if(mReadyRenderCommandBuffer != nullptr && mReadyRenderCommandBuffer->size() > 0)
- return true;
- return false;
- }
- void DeferredRenderSystem::throwIfInvalidThread()
- {
- #if CM_THREAD_SUPPORT != 0
- if(CM_THREAD_CURRENT_ID != mMyThreadId)
- {
- CM_EXCEPT(InternalErrorException, "Deferred render system method called on an invalid thread.");
- }
- #endif
- }
- }
|