1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include "scalinglayer.hpp"
#include <MyGUI_RenderManager.h>
#include <algorithm>
namespace osgMyGUI
{
/// @brief the ProxyRenderTarget allows to adjust the pixel scale and offset for a "source" render target.
class ProxyRenderTarget : public MyGUI::IRenderTarget
{
public:
/// @param target The target to render to.
/// @param viewSize The size of the underlying layer node to render.
/// @param hoffset The horizontal rendering offset, specified as an offset from the left screen edge in range
/// 0-1.
/// @param voffset The vertical rendering offset, specified as an offset from the top screen edge in range 0-1.
ProxyRenderTarget(MyGUI::IRenderTarget* target, MyGUI::IntSize viewSize, float hoffset, float voffset)
: mTarget(target)
, mViewSize(viewSize)
, mHOffset(hoffset)
, mVOffset(voffset)
{
}
void begin() override { mTarget->begin(); }
void end() override { mTarget->end(); }
void doRender(MyGUI::IVertexBuffer* _buffer, MyGUI::ITexture* _texture, size_t _count) override
{
mTarget->doRender(_buffer, _texture, _count);
}
const MyGUI::RenderTargetInfo& getInfo() const override
{
mInfo = mTarget->getInfo();
mInfo.hOffset = mHOffset;
mInfo.vOffset = mVOffset;
mInfo.pixScaleX = 1.f / mViewSize.width;
mInfo.pixScaleY = 1.f / mViewSize.height;
return mInfo;
}
private:
MyGUI::IRenderTarget* mTarget;
MyGUI::IntSize mViewSize;
float mHOffset, mVOffset;
mutable MyGUI::RenderTargetInfo mInfo;
};
MyGUI::ILayerItem* ScalingLayer::getLayerItemByPoint(int _left, int _top) const
{
screenToLayerCoords(_left, _top);
return OverlappedLayer::getLayerItemByPoint(_left, _top);
}
void ScalingLayer::screenToLayerCoords(int& _left, int& _top) const
{
float scale = getScaleFactor(mViewSize);
if (scale <= 0.f)
return;
MyGUI::IntSize globalViewSize = MyGUI::RenderManager::getInstance().getViewSize();
_left -= globalViewSize.width / 2;
_top -= globalViewSize.height / 2;
_left = static_cast<int>(_left / scale);
_top = static_cast<int>(_top / scale);
_left += mViewSize.width / 2;
_top += mViewSize.height / 2;
}
float ScalingLayer::getScaleFactor(const MyGUI::IntSize& _layerViewSize)
{
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float w = static_cast<float>(viewSize.width);
float h = static_cast<float>(viewSize.height);
float heightScale = (h / _layerViewSize.height);
float widthScale = (w / _layerViewSize.width);
return std::min(widthScale, heightScale);
}
MyGUI::IntPoint ScalingLayer::getPosition(int _left, int _top) const
{
screenToLayerCoords(_left, _top);
return MyGUI::IntPoint(_left, _top);
}
void ScalingLayer::renderToTarget(MyGUI::IRenderTarget* _target, bool _update)
{
MyGUI::IntSize globalViewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntSize viewSize = globalViewSize;
float scale = getScaleFactor(mViewSize);
viewSize.width = static_cast<int>(viewSize.width / scale);
viewSize.height = static_cast<int>(viewSize.height / scale);
float hoffset = (globalViewSize.width - mViewSize.width * getScaleFactor(mViewSize)) / 2.f
/ static_cast<float>(globalViewSize.width);
float voffset = (globalViewSize.height - mViewSize.height * getScaleFactor(mViewSize)) / 2.f
/ static_cast<float>(globalViewSize.height);
ProxyRenderTarget proxy(_target, viewSize, hoffset, voffset);
MyGUI::OverlappedLayer::renderToTarget(&proxy, _update);
}
void ScalingLayer::resizeView(const MyGUI::IntSize& _viewSize)
{
// do nothing
}
void ScalingLayer::deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version)
{
MyGUI::OverlappedLayer::deserialization(_node, _version);
MyGUI::xml::ElementEnumerator info = _node->getElementEnumerator();
while (info.next())
{
if (info->getName() == "Property")
{
auto key = info->findAttribute("key");
auto value = info->findAttribute("value");
if (key == "Size")
{
mViewSize = MyGUI::IntSize::parse(value);
}
}
}
}
}
|