私の目標: C#/Xaml で記述された Windows Phone ランタイム コンポーネントから C++ で記述された Direct3DComponent に文字列を渡すこと。
私の理解: これは D3DInterop を使用して達成されます。
具体的には、D3D with Xaml アプリケーション テンプレートを使用して、DrawingSurfaceGrid が読み込まれたときに作成される Direct3DBackground オブジェクトに値を渡そうとしています。
テンプレートの作成者は、整数などの単純なデータ型のみをコピーすることでこれを実現しましたが、マーシャリング文字列の例は示されていません。最終的な解決策は、単純な変数の割り当てよりも複雑になるという結論に達しました。最初の呼び出しで最初に十分な大きさのバッファーを割り当て、次に 2 番目の呼び出しで実際にバイトをコピーするなどです。
以下は、最初に D3DComponent にデータを渡すプロジェクトのマネージ部分であり、その後にデータを受け取るクラス Direct3DBackground クラス宣言があります。
private void DrawingSurfaceBackground_Loaded(object sender, RoutedEventArgs e)
{
if (m_d3dBackground == null)
{
m_d3dBackground = new Direct3DBackground();
// Set window bounds in dips
m_d3dBackground.WindowBounds = new Windows.Foundation.Size(
(float)Application.Current.Host.Content.ActualWidth,
(float)Application.Current.Host.Content.ActualHeight
);
// Set native resolution in pixels
m_d3dBackground.NativeResolution = new Windows.Foundation.Size(
(float)Math.Floor(Application.Current.Host.Content.ActualWidth * Application.Current.Host.Content.ScaleFactor / 100.0f + 0.5f),
(float)Math.Floor(Application.Current.Host.Content.ActualHeight * Application.Current.Host.Content.ScaleFactor / 100.0f + 0.5f)
);
// Set render resolution to the full native resolution
m_d3dBackground.RenderResolution = m_d3dBackground.NativeResolution;
// Get the location of the model from the query string
string ModelLocation;
if (this.NavigationContext.QueryString.ContainsKey("ModelLocation"))
{
ModelLocation = this.NavigationContext.QueryString["ModelLocation"];
}
// then somehow pass the value of ModelLocation to m_d3dBackground
/// ???
// Hook-up native component to DrawingSurfaceBackgroundGrid
DrawingSurfaceBackground.SetBackgroundContentProvider(m_d3dBackground.CreateContentProvider());
DrawingSurfaceBackground.SetBackgroundManipulationHandler(m_d3dBackground);
}
}
そして、このデータを受け取る C++ クラス:
public ref class Direct3DBackground sealed : public Windows::Phone::Input::Interop::IDrawingSurfaceManipulationHandler
{
public:
Direct3DBackground();
Windows::Phone::Graphics::Interop::IDrawingSurfaceBackgroundContentProvider^ CreateContentProvider();
// IDrawingSurfaceManipulationHandler
virtual void SetManipulationHost(Windows::Phone::Input::Interop::DrawingSurfaceManipulationHost^ manipulationHost);
event RequestAdditionalFrameHandler^ RequestAdditionalFrame;
property Windows::Foundation::Size WindowBounds;
property Windows::Foundation::Size NativeResolution;
property Windows::Foundation::Size RenderResolution;
// property System::String ModelLocationUri; // The solution is more complex than this
protected:
// Event Handlers
void OnPointerPressed(Windows::Phone::Input::Interop::DrawingSurfaceManipulationHost^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerReleased(Windows::Phone::Input::Interop::DrawingSurfaceManipulationHost^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerMoved(Windows::Phone::Input::Interop::DrawingSurfaceManipulationHost^ sender, Windows::UI::Core::PointerEventArgs^ args);
internal:
HRESULT Connect(_In_ IDrawingSurfaceRuntimeHostNative* host, _In_ ID3D11Device1* device);
void Disconnect();
HRESULT PrepareResources(_In_ const LARGE_INTEGER* presentTargetTime, _Inout_ DrawingSurfaceSizeF* desiredRenderTargetSize);
HRESULT Draw(_In_ ID3D11Device1* device, _In_ ID3D11DeviceContext1* context, _In_ ID3D11RenderTargetView* renderTargetView);
private:
CubeRenderer^ m_renderer;
BasicTimer^ m_timer;
};