zoukankan      html  css  js  c++  java
  • Direct2D 变换

    可以通过矩阵变换来给几何图形作平移(Translation)、旋转(Rotate)、扭曲(Skew)和大小变换(Scale):

    View Code
    #include "stdafx.h"
    
    struct SampleWindow
        : DesktopWindow<SampleWindow>
    {
        ComPtr<ID2D1RectangleGeometry> m_geometry;
        ComPtr<ID2D1SolidColorBrush> m_brush;
    
        void CreateDeviceIndependentResources()
        {
            HR(m_factory->CreateRectangleGeometry(
                RectF(0.0f, 0.0f, 200.0f, 100.0f), m_geometry.GetAddressOf()));
        }
        
        void CreateDeviceResources()
        {
            HR(m_target->CreateSolidColorBrush(
                COLOR_WHITE, m_brush.GetAddressOf()));
        }
    
        void DrawGeometry(const Matrix3x2F& matrix, const D2D1_COLOR_F& color)
        {
            m_brush->SetColor(color);
            m_target->SetTransform(matrix);
            m_target->FillGeometry(m_geometry.Get(), m_brush.Get());
        }
    
        void Draw()
        {
            m_target->Clear(COLOR_BLUE);
    
            m_brush->SetOpacity(0.75f);
    
            // 如果不用Identity,重绘的时候就会消失
            auto t = Matrix3x2F::Identity();
            DrawGeometry(t, COLOR_WHITE);
    
            t = Matrix3x2F::Translation(100.0f, 50.0f) * t;
            DrawGeometry(t, COLOR_YELLOW);
    
            t = Matrix3x2F::Scale(1.0f, 2.0f) * Matrix3x2F::Translation(100.0f, 50.0f) * t;
            DrawGeometry(t, COLOR_RED);
    
            t = Matrix3x2F::Skew(-45.0f, 0.0f) * Matrix3x2F::Translation(300.0f, 150.0f);
            DrawGeometry(t, COLOR_BLACK);
    
            t = Matrix3x2F::Rotation(45.0f) * Matrix3x2F::Translation(300.0f, 150.0f);
            DrawGeometry(t, COLOR_WHITE);
        }
    };
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
        SampleWindow window;
        return window.Run();
    }

    在给带边框的几何图形作形变时,会导致边框也产生变化,如果这不是想要的情况,可以:
    1、给几何图形单独定义边框
    2、使用形变几何图形(ID2D1TransformedGeometry),来维护边框不变:

    View Code
    #include "stdafx.h"
    
    struct SampleWindow
        : DesktopWindow<SampleWindow>
    {
        ComPtr<ID2D1RectangleGeometry> m_geometry;
        ComPtr<ID2D1SolidColorBrush> m_brush;
        ComPtr<ID2D1StrokeStyle1> m_style;
        D2D1_POINT_2F m_offset;
        D2D1_POINT_2F m_anchor;
    
        void CreateDeviceIndependentResources()
        {
            auto rect = RectF(0.0f, 0.0f, 100.0f, 100.0f);
    
            ASSERT(!m_geometry);
            HR(m_factory->CreateRectangleGeometry(rect, m_geometry.GetAddressOf()));
    
            m_offset = Point2F(1.0f, 1.0f);
            m_anchor = Point2F();
    
            D2D1_STROKE_STYLE_PROPERTIES1 props = {};
            props.miterLimit = 10.0f;
            props.transformType = D2D1_STROKE_TRANSFORM_TYPE_FIXED;
    
            ASSERT(!m_style);
            HR(m_factory->CreateStrokeStyle(props, nullptr, 0, m_style.GetAddressOf()));
        }
        
        void CreateDeviceResources()
        {
            HR(m_target->CreateSolidColorBrush(
                COLOR_WHITE, m_brush.GetAddressOf()));
        }
    
        void Draw()
        {
            m_target->Clear(COLOR_BLUE);
    
            auto t = Matrix3x2F::Translation(50.0f, 50.0f);
            auto scale = Matrix3x2F::Scale(
                max(1.0f, m_offset.x), 
                max(1.0f, m_offset.y));
    
            m_target->SetTransform(scale * t);
            m_target->DrawGeometry(m_geometry.Get(), m_brush.Get(), 5.0f, m_style.Get());
    
            // 也可以使用以下方法来避免边缘发生形变
            /*ComPtr<ID2D1TransformedGeometry> geometry;
            HR(m_factory->CreateTransformedGeometry(m_geometry.Get(), scale * t, geometry.GetAddressOf()));
            m_target->DrawGeometry(geometry.Get(), m_brush.Get(), 5.0f);*/
        }
    
        LRESULT MouseLeftButtonDownHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
        {
            SetCapture();
            m_anchor.x = LOWORD(lparam);
            m_anchor.y = HIWORD(lparam);
            return 0;
        }
    
        LRESULT MouseLeftButtonUpHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
        {
            ReleaseCapture();
            return 0;
        }
    
        LRESULT MouseMoveHandler(UINT, WPARAM wparam, LPARAM lparam, BOOL&)
        {
            auto x = (FLOAT)LOWORD(lparam);
            auto y = (FLOAT)HIWORD(lparam);
    
            if (wparam & MK_LBUTTON)
            {
                m_offset.x = 1 + (x - m_anchor.x) / 100.0f;
                m_offset.y = 1 + (y - m_anchor.y) / 100.0f;
                Invalidate();
            }
            return 0;
        }
    };
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
        SampleWindow window;
        return window.Run();
    }

    此外,还可以通过给画笔(ID2D1Brush)设置矩阵变换(Matrix3x2F)来显示不同的图形:

    View Code
    #include "stdafx.h"
    
    struct SampleWindow
        : DesktopWindow<SampleWindow>
    {
        ComPtr<ID2D1LinearGradientBrush> m_brush;
    
        void CreateDeviceIndependentResources()
        {
        }
        
        void CreateDeviceResources()
        {
            D2D1_GRADIENT_STOP stops[] = 
            {
                { 0.0f, COLOR_WHITE }, 
                { 1.0f, COLOR_BLUE }
            };
    
            ComPtr<ID2D1GradientStopCollection> collection;
            HR(m_target->CreateGradientStopCollection(stops, _countof(stops), collection.GetAddressOf()));
            D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = {};
            HR(m_target->CreateLinearGradientBrush(props, collection.Get(), m_brush.GetAddressOf()));
        }
    
        void Draw()
        {
            auto size = m_target->GetSize();
            m_brush->SetEndPoint(Point2F(size.width, size.height));
            m_target->FillRectangle(RectF(0.0f, 0.0f, size.width, size.height), m_brush.Get());
        }
    
        LRESULT MouseMoveHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
        {
            if (m_target)
            {
                auto size = m_target->GetSize();
                auto t = Matrix3x2F::Translation(LOWORD(lparam) - size.width, HIWORD(lparam) - size.height);
                m_brush->SetTransform(t);
                Invalidate();
            }
            return 0;
        }
    };
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
        SampleWindow window;
        return window.Run();
    }


     

  • 相关阅读:
    小技巧与阅读感悟
    Android常见漏洞介绍(1):Intent Scheme URL 攻击
    利用Mallet工具自动挖掘文本Topic
    Xie Tao的几个小建议PPT:关于读Paper,如何与他人交流,赶Deadline
    Python解析DNS数据包
    iOS 横竖屏适配 笔记
    多工程联编,cocopods的使用
    Call to unavailable function 'system': not available on iOS
    xxx referenced from: xxx in xxx.o
    YYModel学习总结YYClassInfo(1)
  • 原文地址:https://www.cnblogs.com/sdflysha/p/3036815.html
Copyright © 2011-2022 走看看