File: scalinglayer.cpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (137 lines) | stat: -rw-r--r-- 4,687 bytes parent folder | download
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);
                }
            }
        }
    }

}