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