本ガイドでは次の作業について説明します。
Texture Share SDK をソースからビルドする。
C++ SDK と DirectX11 および DirectX12 アプリケーションを統合する。
Unreal Engine プラグインとブループリントを使用する。
Unreal プロジェクトのレンダリングされたビューポートを外部のアプリケーションに送信する。
Unreal セッション中に外部アプリケーションからテクスチャを送受信する。
ステップ 1 - SDK を導入する
Texture Share SDK を使用するには、エンジンのソース コードをダウンロードしてエンジンをソースからビルドする必要があります。エンジン ソース コードのダウンロードについては、「Unreal Engine のインストール方法」を参照してください。
Visual Studio でエンジンをビルドしても、デフォルトでは Texture Share SDK プロジェクトはビルドされません。
Texture Share SDK をビルドするには次の手順に従います。
Visual Studio で「
UE4.sln
」ファイルを開きます。ソリューション エクスプローラー パネルで [Programs (プログラム)] > [TextureShare] に移動します。「TextureShareSDK」プロジェクトを右クリックしてビルドします。
プロジェクトのビルドが完了すると、「Engine\Binaries\Win64\TextureShareSDK」フォルダに「
.lib
」と「.dll
」ファイルが生成されます。
C++ SDK の統合
Texture Share API を使用することで、テクスチャ共有プロセスをより細かく制御することができます。
Texture Share を使用するには、まず共有を行うものの間にセッションを確立する必要があります。確立前に読み取り/書き込みを行うことはできません。一連の手順を通じて、プロジェクト用にカスタマイズ可能な、さまざまな同期状態を制御することができます。
Texture Share API を使用する C++ アプリケーションは次の構造に準拠しています。
テクスチャ共有オブジェクトの名前を指定することで、クライアント アプリケーションがテクスチャ共有オブジェクトを作成する。
テクスチャが、複数のテクスチャを保持可能なテクスチャ共有オブジェクトとともに登録されており、テクスチャ セッションが開始される。
各フレームでデータの書き込みと他のアプリケーションへの送信が可能、または読み取りが可能。データ バッファは読み取り/書き込み操作の前にロックされ、その後にロック解除される必要があります。
セッションが終了するまで、手順 3 が各フレームごとに繰り返される。
次のセクションでは、「Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D12」にある DirectX12 サンプル プロジェクト「TextureShareD3D12Client.vcxproj
」で Texture Share API がどのように使用されているかを紹介します。
この例では DirectX12 を使用していますが、プロセスは DirectX11 でも同じです。多少の修正が必要ですが、「ThirdParty」フォルダにある DirectX11 サンプル プロジェクトを使ってプロセスを確認できます。
ファイルのインクルード
ヘッダ ファイル「
TextureShareD3D12Client.h
」および「TextureShareDLL.h
」をインクルードします。pragma コメント を使って静的ライブラリ ファイルをリンクします。Visual Studio で Release (リリース) コンフィギュレーションを使ってビルドする場合は「
TextureShareSDK.lib
」を、 Debug (デバッグ) コンフィギュレーションを使ってビルドする場合は「TextureShareSDK-Win64-Debug.lib
」を使用します。#include "TextureShareD3D12Client.h" #include "TextureShareDLL.h" #ifdef _DEBUG #pragma comment( lib, "TextureShareSDK-Win64-Debug.lib" ) #else #pragma comment( lib, "TextureShareSDK.lib" ) #endif
初期化
次の手順では、C++ で初期化すべきものと Texture Share セッションの開始方法について説明します。
レンダリング パイプラインとアセットを DirectX API とともにロードします。
DirectX デバイス を作成します。
GraphicsCommandList を作成します。
例については
D3D12HelloTexture::LoadPipeline()
とD3D12HelloTexture::LoadAssets()
を参照してください。Texture Share 項目を作成します。
共有の名前を設定します。名前は最大 128 文字です。
ETextureShareProcess::Client
を使ってアプリケーションをクライアントとして設定します。Texture Share セッションの同期ポリシーを定義します。詳細については「Sync Policies (同期ポリシー)」を参照してください。この例ではすべての同期ポリシーが None (なし) に設定されているため、同期イベントはノンブロッキングになります。
使用するグラフィック API を指定します。現時点では DirectX11 と DirectX12 のみがサポートされています。
FTextureShareSyncPolicy DefaultSyncPolicy; DefaultSyncPolicy.ConnectionSync = ETextureShareSyncConnect::None; DefaultSyncPolicy.FrameSync = ETextureShareSyncFrame::None; DefaultSyncPolicy.TextureSync = ETextureShareSyncSurface::None; FTextureShareInterface::CreateTextureShare(ShareName.c_str(), ETextureShareProcess::Client, DefaultSyncPolicy, ETextureShareDevice::D3D12);
テクスチャを Texture Share 項目と登録します。
セッションの共有名を設定します。
テクスチャの名前を設定します。
テクスチャの解像度を設定します。
テクスチャの形式と値を定義します。
テクスチャを読み取り可能または書き込み可能に設定します。
ETextureShareFormat ShareFormat = ETextureShareFormat::Undefined; uint32 ShareFormatValue = 0; // Use client texture format: if (InFormat != DXGI_FORMAT_UNKNOWN) { ShareFormat = ETextureShareFormat::Format_DXGI; ShareFormatValue = InFormat; } FTextureShareInterface::RegisterTexture(ShareName.c_str(), TextureName.c_str(), Width, Height, ShareFormat, ShareFormatValue, TextureOp);
Texture Share セッション範囲の開始点を定義します。
FTextureShareInterface::BeginSession(ShareName.c_str());
レンダリング スレッド
次は、レンダリング スレッド内で共有メモリにアクセスする手順です。この手順では、読み取りと書き込みの両操作を使用する方法について説明します。
Texture Share セッションでフレームの範囲の開始点を定義します。
FTextureShareInterface::BeginFrame_RenderThread(ShareName.c_str());
レンダリング スレッド内のテクスチャを読み取ります。
テクスチャにロックをかけます。
テクスチャ メモリにアクセスします。
テクスチャのロックを解除します。
if (FTextureShareInterface::IsValid(ShareName.c_str())) { ID3D12Resource* SharedResource; if (FTextureShareInterface::LockTextureD3D12_RenderThread(pD3D12Device, ShareName.c_str(), TextureName.c_str(), SharedResource)) { if (!FTextureShareD3D12Helper::IsTexturesEqual(SharedResource, *InOutSRVTexture)) { // Shared texture size changed on server side. Remove temp texture, and re-create new tempTexture ReleaseTextureAndSRV(InOutSRVTexture); } if (!*InOutSRVTexture) { // Create Temp texture&srv FTextureShareD3D12Helper::CreateSRVTexture(pD3D12Device, pD3D12HeapSRV, SharedResource, InOutSRVTexture, SRVIndex); } // Copy from shared to temp: if (*InOutSRVTexture) { FTextureShareD3D12Helper::CopyResource(pCmdList, SharedResource, *InOutSRVTexture); } // Unlock shared resource FTextureShareInterface::UnlockTexture_RenderThread(ShareName.c_str(), TextureName.c_str()); } else { // Release unused texture (disconnect purpose) ReleaseTextureAndSRV(InOutSRVTexture); } }
レンダリング スレッド内のテクスチャに書き込みます。
セッションが有効であるかどうかを確認します。
テクスチャにロックをかけます。
メモリにアクセスします。
テクスチャのロックを解除します。
if (FTextureShareInterface::IsValid(ShareName.c_str())) { ID3D12Resource* SharedResource; if (FTextureShareInterface::LockTextureD3D12_RenderThread(pD3D12Device, ShareName.c_str(), TextureName.c_str(), SharedResource)) { FTextureShareD3D12Helper::CopyResource(pCmdList, InTexture, SharedResource); FTextureShareInterface::UnlockTexture_RenderThread(ShareName.c_str(), TextureName.c_str()); } }
投影やカメラ マトリックスなど、補助バッファ内の情報にアクセスするためのフレーム データを取得します。
FTextureShareSDKAdditionalData* OutFrameData; FTextureShareInterface::GetRemoteAdditionalData(ShareName.c_str(), *OutFrameData);
Texture Share セッションでフレームの範囲の終了点を定義します。
FTextureShareInterface::EndFrame_RenderThread(ShareName.c_str());
表示するフレームを提供します。
クリーンアップ
次の手順では、アプリケーションの終了時に Texture Share セッションを終了する方法について説明します。
Texture Share セッションの範囲の終了点を定義します。
FTextureShareInterface::EndSession(ShareName.c_str());
Texture Share 項目を削除してメモリを解放します。
FTextureShareInterface::ReleaseTextureShare(ShareName.c_str());
ステップ 2 - Unreal で使用する
次は、Texture Share プラグインを使用して Unreal Engine 内で Texture Share ブループリントにアクセスする手順です。
エディタのメイン メニューから [Edit (編集)] > [Plugins (プラグイン)] を選択して プライグイン エディタ を開きます。
プラグイン エディタ内で [Misc (その他)] セクションにある Texture Share プラグインを見つけます。
3.[Enabled (有効)] チェックボックスをオンにしてエディタを再起動します。
コンテンツ ブラウザ パネルの右下にある [View Options (表示オプション)] ドロップダウンをクリックして開きます。[Show Engine Content (エンジンのコンテンツを表示)] と [Show Plugin Content (プライグイン コンテンツを表示)] チェックボックスをオンにします。
コンテンツ ブラウザ 上部のフォルダ アイコンをクリックして、コンテンツのパスを選択します。リストから [TextureShare Content (TextureShare コンテンツ)] を選択します。
「Blueprints」フォルダには、シーンに直接追加可能な 2 つのブループリント オブジェクトが含まれています。
BP_TextureShare_Scene: Unreal シーン全体のレンダリングされたフレームを共有するブループリント。
BP_TextureShare_Postprocess: 特定の Texture オブジェクトを送受信するブループリント。
「Materials」フォルダには、 BP_TextureShare_Postprocess ブループリントで使用可能なテクスチャとマテリアルが含まれています。
RTT_TextureShare_Backbuffer: Texture Render Target 2D アセット。
M_TextureShare_RTTBackbuffer: RTT_TextureShare_Backbuffer テクスチャをサンプリングして エミッシブ カラー として使用するマテリアル。
本クイック スタートの以降の手順では、それぞれのブループリントの使用方法と、これらを他の DirectX アプリケーションに接続する方法について説明します。
ステップ 3 - Unreal シーンをテクスチャとして DirectX アプリケーションに送信する
次の手順に従って Unreal シーンを外部の DirectX アプリケーションにストリーミングします。
「Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D11 」に移動して、Visual Studio で「
TextureShareD3D11Client.vcxproj
」サンプル プロジェクトを開きます。Visual Studio で、 [Solution Configuration (ソリューション構成)] を [Release (リリース)] に設定します。
3.Visual Studio でプロジェクトをビルドします。
「Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D11\Binaries\TextureShareD3D11Client-Win64-Release 」フォルダに移動して
TextureShareD3D11Client.exe
アプリケーションを起動します。Unreal Engine で Unreal プロジェクトを開き、ブループリント BP_TextureShare_Scene オブジェクトをシーンに追加します。
BP_TextureShare_Scene オブジェクトを選択し、その [Details (詳細)] パネルを開きます。
[Share Name (共有名)] パラメータが、サンプル プロジェクトの ShareName 変数と同じ名前 (vp_1 ) に設定されていることを確認します。
Unreal で [Play (プレイ)] をクリックします。Unreal シーンからレンダリングされたフレームがテクスチャとしてクライアント アプリケーションにストリーミングされ、回転するキューブに適用されます。
ステップ 4 - テクスチャを外部の DirectX アプリケーションに送信する
前の手順では、Unreal シーンをテクスチャとして別のプロセスで共有する方法について説明しました。プロジェクト内のテクスチャ オブジェクトは外部のアプリケーションにも送信することができます。
次は、Unreal プロジェクト内のあらゆるテクスチャ オブジェクトをサンプル DirectX アプリケーションに共有する手順です。
「Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12」フォルダに移動して、Visual Studio で「
TextureShareD3D12Client.vcxproj
」サンプル プロジェクトを開きます。[Solution Configuration] を [Release] に設定します。
3.プロジェクトをビルドします。
「Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release」フォルダに移動して、プロジェクトでビルドした実行可能ファイル「
TextureShareD3D12Client.exe
」を実行します。Unreal Engine で Unreal プロジェクトを開き、ブループリント BP_TextureShare_Postprocess オブジェクトをシーンに追加します。
シーンに追加した BP_TextureShare_Postprocess オブジェクトを選択し、その [Details] パネルを開きます。
[Postprocess (ポストプロセス)] セクションを展開します。
[Postprocess] セクションの [Send (送信)] セクションを展開します。ここには 2 つの [Send] 配列要素があります。それぞれの ID は、サンプル プロジェクトの「
D3D12HelloTexture.cpp
」ファイルで定義されているテクスチャ名に対応したものである必要があります。// Define share and texture names std::wstring ShareName1 = L"vp_1"; std::wstring ReceiveTextureNames[] = { L"SceneDepth" , L"BackBuffer" };
最初の [Send] 要素の [Id] を SceneDepth に設定します。
2 番目の [Send] 要素の [Id] を BackBuffer に設定します。
Unreal Editor の [Play] をクリックします。
両方の [Send] 要素の Texture パラメータを、それぞれのテクスチャ オブジェクトで更新します。エンジンによってこれらのテクスチャがクライアント アプリケーションにストリーミングされ、レンダリングされた三角ポリゴンに適用されます。
ステップ 5 - DirectX アプリケーションからテクスチャを受信して Unreal で表示する
前の手順では、テクスチャを外部の DirectX アプリケーションに送信する方法について説明しました。このセクションでは、別のアプリケーションからテクスチャを受信する方法について説明します。
次は、サンプル DirectX アプリケーションからテクスチャを受信する手順です。
「Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12」フォルダに移動して、Visual Studio で「
TextureShareD3D12Client.vcxproj
」サンプル プロジェクトを開きます。[Solution Configuration] を [Release] に設定します。
3.プロジェクトをビルドします。
「Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release」フォルダに移動して、プロジェクトでビルドした実行可能ファイル「
TextureShareD3D12Client.exe
」を実行します。Unreal Engine で Unreal プロジェクトを開き、ブループリント BP_TextureShare_Postprocess オブジェクトをシーンに追加します。
シーンに追加した BP_TextureShare_Postprocess オブジェクトを選択し、その [Details] パネルを開きます。
[Details] パネルの [Default (デフォルト)] セクションにある [Postprocess] セクションを展開します。
[Postprocess] の [Receive (受信)] セクションを展開します。ここには [Receive] 配列要素が 1 つあります。この要素の [Id] は、サンプル プロジェクトの「
D3D12HelloTexture.cpp
」ファイルで定義されているテクスチャ名に対応したものである必要があります。// Define share and texture names std::wstring ShareName1 = L"vp_1"; std::wstring SendBackbufferTextureName = L"InBackbuffer";
[Receive] 要素の RTT パラメータを、 TextureShare プラグインで提供される RTT_TextureShare_Backbuffer テクスチャに設定します。
これで、TextureShare を使って別のアプリケーションからテクスチャを受信できるよう Unreal プロジェクトを設定できました。
次の例では Unreal Engine セッションが開始しています。Unreal が TextureShareD3D12Client アプリケーションにテクスチャを送信し、このアプリケーションからバックバッファを受信しています。リアルタイムで受信したものを示すために、シーン内の壁に掛かっている絵画には RTT_TextureShare_Backbuffer テクスチャからサンプリングされたマテリアルが使用されています。