1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "pch.h"
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "Direct3DInterop.h"
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "Direct3DContentProvider.h"
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <windows.storage.streams.h>
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <wrl.h>
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <robuffer.h>
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <opencv2\imgproc\types_c.h>
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Windows::Storage::Streams;
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Microsoft::WRL;
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Windows::Foundation;
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Windows::UI::Core;
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Microsoft::WRL;
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Windows::Phone::Graphics::Interop;
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace Windows::Phone::Input::Interop;
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslernamespace PhoneXamlDirect3DApp1Comp
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::ApplyGrayFilter(const cv::Mat& image)
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Mat intermediateMat;
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::cvtColor(image, intermediateMat, CV_RGBA2GRAY);
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::cvtColor(intermediateMat, image, CV_GRAY2BGRA);
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::ApplyCannyFilter(const cv::Mat& image)
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Mat intermediateMat;
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::Canny(image, intermediateMat, 80, 90);
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::cvtColor(intermediateMat, image, CV_GRAY2BGRA);
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::ApplySepiaFilter(const cv::Mat& image)
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        const float SepiaKernelData[16] =
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* B */0.131f, 0.534f, 0.272f, 0.f,
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* G */0.168f, 0.686f, 0.349f, 0.f,
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* R */0.189f, 0.769f, 0.393f, 0.f,
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* A */0.000f, 0.000f, 0.000f, 1.f
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        };
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        const cv::Mat SepiaKernel(4, 4, CV_32FC1, (void*)SepiaKernelData);
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cv::transform(image, image, SepiaKernel);
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Direct3DInterop::Direct3DInterop() :
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_timer(ref new BasicTimer())
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    IDrawingSurfaceContentProvider^ Direct3DInterop::CreateContentProvider()
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ComPtr<Direct3DContentProvider> provider = Make<Direct3DContentProvider>(this);
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return reinterpret_cast<IDrawingSurfaceContentProvider^>(provider.Detach());
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // IDrawingSurfaceManipulationHandler
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::SetManipulationHost(DrawingSurfaceManipulationHost^ manipulationHost)
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        manipulationHost->PointerPressed +=
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerPressed);
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        manipulationHost->PointerMoved +=
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerMoved);
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        manipulationHost->PointerReleased +=
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ref new TypedEventHandler<DrawingSurfaceManipulationHost^, PointerEventArgs^>(this, &Direct3DInterop::OnPointerReleased);
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::RenderResolution::set(Windows::Foundation::Size renderResolution)
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (renderResolution.Width  != m_renderResolution.Width ||
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            renderResolution.Height != m_renderResolution.Height)
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_renderResolution = renderResolution;
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (m_renderer)
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                m_renderer->UpdateForRenderResolutionChange(m_renderResolution.Width, m_renderResolution.Height);
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                RecreateSynchronizedTexture();
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // Event Handlers
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::OnPointerPressed(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Insert your code here.
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::OnPointerMoved(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Insert your code here.
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::OnPointerReleased(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Insert your code here.
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // Interface With Direct3DContentProvider
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    HRESULT Direct3DInterop::Connect(_In_ IDrawingSurfaceRuntimeHostNative* host)
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer = ref new CubeRenderer();
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer->Initialize();
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer->UpdateForWindowSizeChange(WindowBounds.Width, WindowBounds.Height);
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer->UpdateForRenderResolutionChange(m_renderResolution.Width, m_renderResolution.Height);
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Restart timer after renderer has finished initializing.
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_timer->Reset();
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return S_OK;
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::Disconnect()
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer = nullptr;
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    HRESULT Direct3DInterop::PrepareResources(_In_ const LARGE_INTEGER* presentTargetTime, _Out_ BOOL* contentDirty)
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *contentDirty = true;
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return S_OK;
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    HRESULT Direct3DInterop::GetTexture(_In_ const DrawingSurfaceSizeF* size, _Out_ IDrawingSurfaceSynchronizedTextureNative** synchronizedTexture, _Out_ DrawingSurfaceRectF* textureSubRectangle)
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_timer->Update();
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer->Update(m_timer->Total, m_timer->Delta);
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_renderer->Render();
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RequestAdditionalFrame();
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return S_OK;
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ID3D11Texture2D* Direct3DInterop::GetTexture()
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return m_renderer->GetTexture();
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void Direct3DInterop::CreateTexture(const Platform::Array<int>^  buffer,int width,int height, OCVFilterType filter)
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (m_renderer)
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cv::Mat Lena = cv::Mat(height, width, CV_8UC4);
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            memcpy(Lena.data, buffer->Data, 4 * height*width);
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            switch (filter)
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case OCVFilterType::ePreview:
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case OCVFilterType::eGray:
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    ApplyGrayFilter(Lena);
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case OCVFilterType::eCanny:
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    ApplyCannyFilter(Lena);
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case OCVFilterType::eSepia:
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    ApplySepiaFilter(Lena);
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_renderer->CreateTextureFromByte(Lena.data, width, height);
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    byte* GetPointerToPixelData( Windows::Storage::Streams::IBuffer ^ pixelBuffer)
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Query the IBufferByteAccess interface.
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ComPtr<IBufferByteAccess> bufferByteAccess;
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        reinterpret_cast<IInspectable*>( pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Retrieve the buffer data.
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        byte* pixels = nullptr;
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        bufferByteAccess->Buffer(&pixels);
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return pixels;
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
187