मैं WPF 4.5 अनलेश अध्याय 1 9 पर आधारित प्रश्न का उत्तर देने का प्रयास करूंगा। यदि आप इसे देखना चाहते हैं, तो आप उपधारा में सभी जानकारी पा सकते हैं "WPF सामग्री के साथ मिक्सिंग डायरेक्टएक्स सामग्री "।
आपका सी ++ DLL होना चाहिए 3 उजागर तरीकों(), सफाई() प्रारंभ करें और रेंडर()।
xmlns:interop="clr-namespace:System.Windows.Interop;assembly=PresentationCore"
<Button.Background>
<ImageBrush>
<ImageBrush.ImageSource>
<interop:D3DImage x:Name="d3dImage" />
</ImageBrush.ImageSource>
</ImageBrush>
</Button.Background>
मैं निर्धारित किया है:
extern "C" __declspec(dllexport) IDirect3DSurface9* WINAPI Initialize(HWND hwnd, int width, int height)
{
// Initialize Direct3D
if(SUCCEEDED(InitD3D(hwnd)))
{
// Create the scene geometry
if(SUCCEEDED(InitGeometry()))
{
if (FAILED(g_pd3dDevice->CreateRenderTarget(width, height,
D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0,
true, // lockable (true for compatibility with Windows XP. False is preferred for Windows Vista or later)
&g_pd3dSurface, NULL)))
{
MessageBox(NULL, L"NULL!", L"Missing File", 0);
return NULL;
}
g_pd3dDevice->SetRenderTarget(0, g_pd3dSurface);
}
}
return g_pd3dSurface;
}
HRESULT InitD3D(HWND hWnd)
{
// For Windows Vista or later, this would be better if it used Direct3DCreate9Ex:
if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
// Set up the structure used to create the D3DDevice. Since we are now
// using more complex geometry, we will create a device with a zbuffer.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// Create the D3DDevice
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice)))
{
return E_FAIL;
}
// Turn on the zbuffer
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
// Turn on ambient lighting
g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xffffffff);
return S_OK;
}
XAML कोड पर चलते हैं: दिलचस्प तरीकों Initialize() और InitD3D() है, जो Initialize() द्वारा कहा जाता है एक छवि ब्रश का उपयोग करके, यहां एक बटन की पृष्ठभूमि के रूप में। मेरा मानना है कि इसे पृष्ठभूमि के रूप में जोड़ना डायरेक्टएक्स सामग्री को प्रदर्शित करने का एक अच्छा तरीका है। हालांकि, आप जिस तरह से चाहें छवि का उपयोग कर सकते हैं।
प्रारंभ करने के लिए प्रतिपादन वर्तमान विंडो के लिए एक संभाल के अधिग्रहण और इसके साथ DLL की विधि Initialize() फोन:
private void initialize()
{
IntPtr surface = DLL.Initialize(new WindowInteropHelper(this).Handle,
(int)button.ActualWidth, (int)button.ActualHeight);
if (surface != IntPtr.Zero)
{
d3dImage.Lock();
d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface);
d3dImage.Unlock();
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
}
CompositionTarget.Rendering घटना निकाल दिया जाता है बस से पहले यूआई प्रदान की गई है। तुम वहाँ में अपने DirectX सामग्री प्रस्तुत करना चाहिए:
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
d3dImage.Lock();
DLL.Render();
// Invalidate the whole area:
d3dImage.AddDirtyRect(new Int32Rect(0, 0, d3dImage.PixelWidth, d3dImage.PixelHeight));
d3dImage.Unlock();
}
}
वह मूल रूप से यह था, मुझे आशा है कि यह मदद करता है। अब बस कुछ ही महत्वपूर्ण sidenotes:
- हमेशा की तरह, अपनी छवि को ताला कि WPF फ्रेम आंशिक रूप से
- न कॉल डायरेक्ट 3 डी उपकरण पर मौजूद ड्रॉ से बचने के लिए। डब्ल्यूपीएफ आपके द्वारा बैकबफर प्रस्तुत करता है, जिस सतह पर आप d3dImage.SetBackBuffer() पर जाते हैं।
घटना IsFrontBufferAvailableChanged क्योंकि कभी-कभी frontbuffer अनुपलब्ध (उदाहरण के लिए, जब उपयोगकर्ता लॉक स्क्रीन में प्रवेश करती है) नहीं बन सकता संभाला जाना चाहिए। आपको बफर उपलब्धता के आधार पर संसाधनों को मुक्त या अधिग्रहित करना चाहिए।
private void d3dImage_IsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (d3dImage.IsFrontBufferAvailable)
{
initialize();
}
else
{
// Cleanup:
CompositionTarget.Rendering -= CompositionTarget_Rendering;
DLL.Cleanup();
}
}
मैं कैसे एक WPF आवेदन में Direct2D की मेजबानी करने का एक उदाहरण के लिए खोज करेंगे। अच्छा सवाल। –
क्या आपके पास डीएलएल तक पहुंच है? क्या आप अपना कोड बदल सकते हैं? मेरा मानना है कि CreateWindow() को कॉल करने में समस्या – Domysee
डब्ल्यूपीएफ डब्ल्यूआईसी के बहुत करीब है, इसलिए मैं इसके बजाय d2d1.CreateWicBitmapRenderTarget का उपयोग अपने IWicBitmap के साथ करूँगा। इस IWicBitmap का उपयोग WPF के अमूर्त बिटमैप स्रोत से प्राप्त कक्षा में किया जा सकता है (जैसे इंटरऑप बिटमैप की तरह, लेकिन स्वयं की कक्षा के साथ क्योंकि डब्ल्यूपीएफ अपने डब्ल्यूआईसी बिटमैप्स का पर्दाफाश नहीं करता है ...)। यह बिटमैप स्रोत अब पैनल का बच्चा हो सकता है। यदि आपके पास काम करने के लिए नमूना ऐप है, तो हम इसे और विकसित कर सकते हैं। –