1#include "pch.h"
2#include "Direct3DInterop.h"
3#include "Direct3DContentProvider.h"
4#include <windows.storage.streams.h>
5#include <wrl.h>
6#include <robuffer.h>
7#include <opencv2\imgproc\types_c.h>
8
9using namespace Windows::Storage::Streams;
10using namespace Microsoft::WRL;
11using namespace Windows::Foundation;
12using namespace Windows::UI::Core;
13using namespace Microsoft::WRL;
14using namespace Windows::Phone::Graphics::Interop;
15using namespace Windows::Phone::Input::Interop;
16
17namespace PhoneXamlDirect3DApp1Comp
18{
19    void Direct3DInterop::ApplyGrayFilter(const cv::Mat& image)
20    {
21        cv::Mat intermediateMat;
22        cv::cvtColor(image, intermediateMat, CV_RGBA2GRAY);
23        cv::cvtColor(intermediateMat, image, CV_GRAY2BGRA);
24    }
25
26    void Direct3DInterop::ApplyCannyFilter(const cv::Mat& image)
27    {
28        cv::Mat intermediateMat;
29        cv::Canny(image, intermediateMat, 80, 90);
30        cv::cvtColor(intermediateMat, image, CV_GRAY2BGRA);
31    }
32
33    void Direct3DInterop::ApplySepiaFilter(const cv::Mat& image)
34    {
35        const float SepiaKernelData[16] =
36        {
37            /* B */0.131f, 0.534f, 0.272f, 0.f,
38            /* G */0.168f, 0.686f, 0.349f, 0.f,
39            /* R */0.189f, 0.769f, 0.393f, 0.f,
40            /* A */0.000f, 0.000f, 0.000f, 1.f
41        };
42
43        const cv::Mat SepiaKernel(4, 4, CV_32FC1, (void*)SepiaKernelData);
44        cv::transform(image, image, SepiaKernel);
45    }
46
47    Direct3DInterop::Direct3DInterop() :
48        m_timer(ref new BasicTimer())
49    {
50    }
51
52    IDrawingSurfaceContentProvider^ Direct3DInterop::CreateContentProvider()
53    {
54        ComPtr<Direct3DContentProvider> provider = Make<Direct3DContentProvider>(this);
55        return reinterpret_cast<IDrawingSurfaceContentProvider^>(provider.Detach());
56    }
57
58    // IDrawingSurfaceManipulationHandler
59    void Direct3DInterop::SetManipulationHost(DrawingSurfaceManipulationHost^ manipulationHost)
60    {
61        manipulationHost->PointerPressed +=
62            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerPressed);
63
64        manipulationHost->PointerMoved +=
65            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerMoved);
66
67        manipulationHost->PointerReleased +=
68            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerReleased);
69    }
70
71    void Direct3DInterop::RenderResolution::set(Windows::Foundation::Size renderResolution)
72    {
73        if (renderResolution.Width  != m_renderResolution.Width ||
74            renderResolution.Height != m_renderResolution.Height)
75        {
76            m_renderResolution = renderResolution;
77
78            if (m_renderer)
79            {
80                m_renderer->UpdateForRenderResolutionChange(m_renderResolution.Width, m_renderResolution.Height);
81                RecreateSynchronizedTexture();
82            }
83        }
84    }
85
86    // Event Handlers
87
88    void Direct3DInterop::OnPointerPressed(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
89    {
90        // Insert your code here.
91    }
92
93    void Direct3DInterop::OnPointerMoved(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
94    {
95        // Insert your code here.
96    }
97
98    void Direct3DInterop::OnPointerReleased(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
99    {
100        // Insert your code here.
101    }
102
103    // Interface With Direct3DContentProvider
104    HRESULT Direct3DInterop::Connect(_In_ IDrawingSurfaceRuntimeHostNative* host)
105    {
106        m_renderer = ref new CubeRenderer();
107        m_renderer->Initialize();
108        m_renderer->UpdateForWindowSizeChange(WindowBounds.Width, WindowBounds.Height);
109        m_renderer->UpdateForRenderResolutionChange(m_renderResolution.Width, m_renderResolution.Height);
110
111        // Restart timer after renderer has finished initializing.
112        m_timer->Reset();
113
114        return S_OK;
115    }
116
117    void Direct3DInterop::Disconnect()
118    {
119        m_renderer = nullptr;
120    }
121
122    HRESULT Direct3DInterop::PrepareResources(_In_ const LARGE_INTEGER* presentTargetTime, _Out_ BOOL* contentDirty)
123    {
124        *contentDirty = true;
125
126        return S_OK;
127    }
128
129    HRESULT Direct3DInterop::GetTexture(_In_ const DrawingSurfaceSizeF* size, _Out_ IDrawingSurfaceSynchronizedTextureNative** synchronizedTexture, _Out_ DrawingSurfaceRectF* textureSubRectangle)
130    {
131        m_timer->Update();
132        m_renderer->Update(m_timer->Total, m_timer->Delta);
133        m_renderer->Render();
134
135        RequestAdditionalFrame();
136
137        return S_OK;
138    }
139
140    ID3D11Texture2D* Direct3DInterop::GetTexture()
141    {
142        return m_renderer->GetTexture();
143    }
144
145    void Direct3DInterop::CreateTexture(const Platform::Array<int>^  buffer,int width,int height, OCVFilterType filter)
146    {
147        if (m_renderer)
148        {
149            cv::Mat Lena = cv::Mat(height, width, CV_8UC4);
150            memcpy(Lena.data, buffer->Data, 4 * height*width);
151
152            switch (filter)
153            {
154                case OCVFilterType::ePreview:
155                    break;
156
157                case OCVFilterType::eGray:
158                    ApplyGrayFilter(Lena);
159                    break;
160
161                case OCVFilterType::eCanny:
162                    ApplyCannyFilter(Lena);
163                    break;
164
165                case OCVFilterType::eSepia:
166                    ApplySepiaFilter(Lena);
167                    break;
168            }
169
170            m_renderer->CreateTextureFromByte(Lena.data, width, height);
171        }
172    }
173
174    byte* GetPointerToPixelData( Windows::Storage::Streams::IBuffer ^ pixelBuffer)
175    {
176        // Query the IBufferByteAccess interface.
177        ComPtr<IBufferByteAccess> bufferByteAccess;
178        reinterpret_cast<IInspectable*>( pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
179
180        // Retrieve the buffer data.
181        byte* pixels = nullptr;
182        bufferByteAccess->Buffer(&pixels);
183        return pixels;
184    }
185
186}
187