//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #include "RenderAPI/BsViewport.h" #include "RTTI/BsViewportRTTI.h" #include "Error/BsException.h" #include "RenderAPI/BsRenderTarget.h" #include "Math/BsMath.h" #include "RenderAPI/BsRenderAPI.h" #include "Allocators/BsFrameAlloc.h" namespace bs { const Color ViewportBase::DEFAULT_CLEAR_COLOR = Color(0.0f, 0.3685f, 0.7969f); ViewportBase::ViewportBase(float x, float y, float width, float height) : mNormArea(x, y, width, height), mRequiresColorClear(true), mRequiresDepthClear(true) , mRequiresStencilClear(false), mClearColor(DEFAULT_CLEAR_COLOR), mDepthClearValue(1.0f), mStencilClearValue(0) { } void ViewportBase::setArea(float x, float y, float width, float height) { mNormArea.x = x; mNormArea.y = y; mNormArea.width = width; mNormArea.height = height; _markCoreDirty(); } Rect2I ViewportBase::getArea() const { float width = (float)getTargetWidth(); float height = (float)getTargetHeight(); Rect2I area; area.x = (int)(mNormArea.x * width); area.y = (int)(mNormArea.y * height); area.width = (int)(mNormArea.width * width); area.height = (int)(mNormArea.height * height); return area; } void ViewportBase::setRequiresClear(bool colorClear, bool depthClear, bool stencilClear) { mRequiresColorClear = colorClear; mRequiresDepthClear = depthClear; mRequiresStencilClear = stencilClear; _markCoreDirty(); } void ViewportBase::setClearValues(const Color& clearColor, float clearDepth, UINT16 clearStencil) { mClearColor = clearColor; mDepthClearValue = clearDepth; mStencilClearValue = clearStencil; _markCoreDirty(); } INT32 ViewportBase::getX() const { return (INT32)(mNormArea.x * getTargetWidth()); } INT32 ViewportBase::getY() const { return (INT32)(mNormArea.y * getTargetHeight()); } INT32 ViewportBase::getWidth() const { return (INT32)(mNormArea.width * getTargetWidth()); } INT32 ViewportBase::getHeight() const { return (INT32)(mNormArea.height * getTargetHeight()); } Viewport::Viewport() :ViewportBase() { } Viewport::Viewport(const SPtr& target, float x, float y, float width, float height) :ViewportBase(x, y, width, height), mTarget(target) { } void Viewport::setTarget(const SPtr& target) { mTarget = target; markDependenciesDirty(); _markCoreDirty(); } SPtr Viewport::getCore() const { return std::static_pointer_cast(mCoreSpecific); } void Viewport::_markCoreDirty() { markCoreDirty(); } UINT32 Viewport::getTargetWidth() const { if(mTarget != nullptr) return mTarget->getProperties().getWidth(); return 0; } UINT32 Viewport::getTargetHeight() const { if(mTarget != nullptr) return mTarget->getProperties().getHeight(); return 0; } SPtr Viewport::createCore() const { SPtr targetCore; if (mTarget != nullptr) targetCore = mTarget->getCore(); ct::Viewport* viewport = new (bs_alloc()) ct::Viewport(targetCore, mNormArea.x, mNormArea.y, mNormArea.width, mNormArea.height); SPtr viewportPtr = bs_shared_ptr(viewport); viewportPtr->_setThisPtr(viewportPtr); return viewportPtr; } CoreSyncData Viewport::syncToCore(FrameAlloc* allocator) { UINT32 size = 0; size += rttiGetElemSize(mNormArea); size += rttiGetElemSize(mRequiresColorClear); size += rttiGetElemSize(mRequiresDepthClear); size += rttiGetElemSize(mRequiresStencilClear); size += rttiGetElemSize(mClearColor); size += rttiGetElemSize(mDepthClearValue); size += rttiGetElemSize(mStencilClearValue); size += sizeof(SPtr); UINT8* buffer = allocator->alloc(size); char* dataPtr = (char*)buffer; dataPtr = rttiWriteElem(mNormArea, dataPtr); dataPtr = rttiWriteElem(mRequiresColorClear, dataPtr); dataPtr = rttiWriteElem(mRequiresDepthClear, dataPtr); dataPtr = rttiWriteElem(mRequiresStencilClear, dataPtr); dataPtr = rttiWriteElem(mClearColor, dataPtr); dataPtr = rttiWriteElem(mDepthClearValue, dataPtr); dataPtr = rttiWriteElem(mStencilClearValue, dataPtr); SPtr* rtPtr = new (dataPtr) SPtr(); if (mTarget != nullptr) *rtPtr = mTarget->getCore(); else *rtPtr = nullptr; return CoreSyncData(buffer, size); } void Viewport::getCoreDependencies(Vector& dependencies) { if (mTarget != nullptr) dependencies.push_back(mTarget.get()); } SPtr Viewport::create(const SPtr& target, float x, float y, float width, float height) { Viewport* viewport = new (bs_alloc()) Viewport(target, x, y, width, height); SPtr viewportPtr = bs_core_ptr(viewport); viewportPtr->_setThisPtr(viewportPtr); viewportPtr->initialize(); return viewportPtr; } SPtr Viewport::createEmpty() { Viewport* viewport = new (bs_alloc()) Viewport(); SPtr viewportPtr = bs_core_ptr(viewport); viewportPtr->_setThisPtr(viewportPtr); return viewportPtr; } RTTITypeBase* Viewport::getRTTIStatic() { return ViewportRTTI::instance(); } RTTITypeBase* Viewport::getRTTI() const { return Viewport::getRTTIStatic(); } namespace ct { Viewport::Viewport(const SPtr& target, float x, float y, float width, float height) :ViewportBase(x, y, width, height), mTarget(target) { } SPtr Viewport::create(const SPtr& target, float x, float y, float width, float height) { Viewport* viewport = new (bs_alloc()) Viewport(target, x, y, width, height); SPtr viewportPtr = bs_shared_ptr(viewport); viewportPtr->_setThisPtr(viewportPtr); viewportPtr->initialize(); return viewportPtr; } UINT32 Viewport::getTargetWidth() const { if (mTarget != nullptr) return mTarget->getProperties().getWidth(); return 0; } UINT32 Viewport::getTargetHeight() const { if (mTarget != nullptr) return mTarget->getProperties().getHeight(); return 0; } void Viewport::syncToCore(const CoreSyncData& data) { char* dataPtr = (char*)data.getBuffer(); dataPtr = rttiReadElem(mNormArea, dataPtr); dataPtr = rttiReadElem(mRequiresColorClear, dataPtr); dataPtr = rttiReadElem(mRequiresDepthClear, dataPtr); dataPtr = rttiReadElem(mRequiresStencilClear, dataPtr); dataPtr = rttiReadElem(mClearColor, dataPtr); dataPtr = rttiReadElem(mDepthClearValue, dataPtr); dataPtr = rttiReadElem(mStencilClearValue, dataPtr); SPtr* rtPtr = (SPtr*)dataPtr; mTarget = *rtPtr; rtPtr->~SPtr(); } } }