fix github issues 4/6/8 & move sample to use new nuget build
* fix: Component: Microsoft.Wpf.Interop.DirectX.dll should have TargetFrameworkVersionAttribute=4.5 (https://github.com/Microsoft/WPFDXInterop/issues/8 ) * fix: Sample improvement: D3DVisualization.cpp - RenderTarget should not be recreated each Render() call (https://github.com/Microsoft/WPFDXInterop/issues/4 ) Have SurfaceQueueInteropHelper notify d3d renderer when a surface was recreated (due to a resize) to make it easier for them to understand when to recreate rendertarget, etc... That mostly involves plumbing through a bool in the Render event handler signature. Removed SetRenderSize in the d3d rendering component of sample...as that turned out to be unnecessary. Explained it in mainwindow.xaml.cs change. Believe that this fix also solves this issue: Sample/Component Bug: After several resizes, rendering sometimes stops (https://github.com/Microsoft/WPFDXInterop/issues/6 )
This commit is contained in:
Родитель
5e32e60cca
Коммит
ceae359eda
|
@ -64,14 +64,14 @@ extern void __cdecl Cleanup()
|
|||
/// <summary>
|
||||
/// Render for global class instance
|
||||
/// </summary>
|
||||
extern HRESULT __cdecl Render(void * pResource)
|
||||
extern HRESULT __cdecl Render(void * pResource, bool isNewSurface)
|
||||
{
|
||||
if ( NULL == pApplication )
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return pApplication->Render(pResource);
|
||||
return pApplication->Render(pResource, isNewSurface);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -120,20 +120,6 @@ extern HRESULT _cdecl SetCameraPhi(float phi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the size of the this visualization
|
||||
/// </summary>
|
||||
extern HRESULT _cdecl SetRenderSize(int pixelWidth, int pixelHeight)
|
||||
{
|
||||
if (NULL == pApplication)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pApplication->SetRenderSize(pixelWidth, pixelHeight);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
|
@ -391,19 +377,11 @@ void CCube::SetUpViewport()
|
|||
m_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, m_Width / (FLOAT)m_Height, 0.01f, 100.0f);
|
||||
}
|
||||
|
||||
HRESULT CCube::SetRenderSize(int pixelWidth, int pixelHeight)
|
||||
{
|
||||
m_Width = pixelWidth;
|
||||
m_Height = pixelHeight;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders a frame
|
||||
/// Initializes RenderTarget
|
||||
/// </summary>
|
||||
/// <returns>S_OK for success, or failure code</returns>
|
||||
HRESULT CCube::Render(void * pResource)
|
||||
HRESULT CCube::InitRenderTarget(void * pResource)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
|
@ -426,19 +404,19 @@ HRESULT CCube::Render(void * pResource)
|
|||
pDXGIResource->Release();
|
||||
|
||||
IUnknown * tempResource11;
|
||||
hr = m_pd3dDevice->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), (void**)(&tempResource11));
|
||||
hr = m_pd3dDevice->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), (void**)(&tempResource11));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID3D11Texture2D * pOutputResource;
|
||||
hr = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&pOutputResource));
|
||||
hr = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&pOutputResource));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
tempResource11->Release();
|
||||
tempResource11->Release();
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtDesc;
|
||||
rtDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
@ -458,11 +436,39 @@ HRESULT CCube::Render(void * pResource)
|
|||
m_Width = outputResourceDesc.Width;
|
||||
m_Height = outputResourceDesc.Height;
|
||||
|
||||
SetUpViewport();
|
||||
SetUpViewport();
|
||||
}
|
||||
|
||||
m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
|
||||
|
||||
if ( NULL != pOutputResource )
|
||||
{
|
||||
pOutputResource->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders a frame
|
||||
/// </summary>
|
||||
/// <returns>S_OK for success, or failure code</returns>
|
||||
HRESULT CCube::Render(void * pResource, bool isNewSurface)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// If we've gotten a new Surface, need to initialize the renderTarget.
|
||||
// One of the times that this happens is on a resize.
|
||||
if ( isNewSurface )
|
||||
{
|
||||
m_pImmediateContext->OMSetRenderTargets(0, NULL, NULL);
|
||||
hr = InitRenderTarget(pResource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
// Update our time
|
||||
static float t = 0.0f;
|
||||
if (m_driverType == D3D_DRIVER_TYPE_REFERENCE)
|
||||
|
@ -487,7 +493,6 @@ HRESULT CCube::Render(void * pResource)
|
|||
static float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, ClearColor);
|
||||
|
||||
|
||||
// Update the view matrix
|
||||
m_camera.Update();
|
||||
|
||||
|
@ -499,19 +504,12 @@ HRESULT CCube::Render(void * pResource)
|
|||
cb.mProjection = XMMatrixTranspose(viewProjection);
|
||||
m_pImmediateContext->UpdateSubresource(m_pConstantBuffer, 0, NULL, &cb, 0, 0);
|
||||
|
||||
//
|
||||
// Renders a triangle
|
||||
//
|
||||
m_pImmediateContext->VSSetShader(m_pVertexShader, NULL, 0);
|
||||
m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer);
|
||||
m_pImmediateContext->PSSetShader(m_pPixelShader, NULL, 0);
|
||||
m_pImmediateContext->DrawIndexed(36, 0, 0); // 36 vertices needed for 12 triangles in a triangle list
|
||||
|
||||
if ( NULL != pOutputResource )
|
||||
{
|
||||
pOutputResource->Release();
|
||||
}
|
||||
|
||||
if ( NULL != m_pImmediateContext )
|
||||
{
|
||||
m_pImmediateContext->Flush();
|
||||
|
|
|
@ -32,7 +32,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) HRESULT __cdecl Render(void * pResource);
|
||||
__declspec(dllexport) HRESULT __cdecl Render(void * pResource, bool isNewSurface);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@ -47,10 +47,6 @@ extern "C" {
|
|||
__declspec(dllexport) HRESULT __cdecl SetCameraPhi(float phi);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) HRESULT __cdecl SetRenderSize(int pixelWidth, int pixelHeight);
|
||||
}
|
||||
|
||||
class CCube
|
||||
{
|
||||
|
||||
|
@ -75,7 +71,7 @@ public:
|
|||
/// Renders a frame
|
||||
/// </summary>
|
||||
/// <returns>S_OK for success, or failure code</returns>
|
||||
HRESULT Render(void * pResource);
|
||||
HRESULT Render(void * pResource, bool isNewSurface);
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -84,9 +80,6 @@ public:
|
|||
/// <returns>Pointer to the camera</returns>
|
||||
CCamera* GetCamera();
|
||||
|
||||
// Method for host to communicate size for rendering this D3D visualization.
|
||||
HRESULT SetRenderSize(int pixelWidth, int pixelHeight);
|
||||
|
||||
// Special function definitions to ensure alignment between c# and c++
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
|
@ -100,7 +93,9 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
HRESULT InitRenderTarget(void * pResource);
|
||||
void SetUpViewport();
|
||||
|
||||
// 3d camera
|
||||
CCamera m_camera;
|
||||
|
||||
|
|
|
@ -58,9 +58,9 @@
|
|||
NativeMethods.InvokeWithDllProtection(NativeMethods.Cleanup);
|
||||
}
|
||||
|
||||
private static int Render(IntPtr resourcePointer)
|
||||
private static int Render(IntPtr resourcePointer, bool isNewSurface)
|
||||
{
|
||||
return NativeMethods.InvokeWithDllProtection(() => NativeMethods.Render(resourcePointer));
|
||||
return NativeMethods.InvokeWithDllProtection(() => NativeMethods.Render(resourcePointer, isNewSurface));
|
||||
}
|
||||
|
||||
private static int SetCameraRadius(float radius)
|
||||
|
@ -119,10 +119,10 @@
|
|||
int surfWidth = (int)(host.ActualWidth < 0 ? 0 : Math.Ceiling(host.ActualWidth * dpiScale));
|
||||
int surfHeight = (int)(host.ActualHeight < 0 ? 0 : Math.Ceiling(host.ActualHeight * dpiScale));
|
||||
|
||||
// notify the D3D11Image and the DxRendering component of the pixel size desired for the DirectX rendering.
|
||||
// Notify the D3D11Image of the pixel size desired for the DirectX rendering.
|
||||
// The D3DRendering component will determine the size of the new surface it is given, at that point.
|
||||
InteropImage.SetPixelSize(surfWidth, surfHeight);
|
||||
NativeMethods.SetRenderSize(surfWidth, surfHeight);
|
||||
|
||||
|
||||
// Stop rendering if the D3DImage isn't visible - currently just if width or height is 0
|
||||
// TODO: more optimizations possible (scrolled off screen, etc...)
|
||||
bool isVisible = (surfWidth != 0 && surfHeight != 0);
|
||||
|
@ -261,9 +261,9 @@
|
|||
}
|
||||
#endregion Helpers
|
||||
|
||||
private void DoRender(IntPtr surface)
|
||||
private void DoRender(IntPtr surface, bool isNewSurface)
|
||||
{
|
||||
Render(surface);
|
||||
Render(surface, isNewSurface);
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
|
@ -299,7 +299,7 @@
|
|||
public static extern void Cleanup();
|
||||
|
||||
[DllImport("D3DVisualization.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int Render(IntPtr resourcePointer);
|
||||
public static extern int Render(IntPtr resourcePointer, bool isNewSurface);
|
||||
|
||||
[DllImport("D3DVisualization.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetCameraRadius(float radius);
|
||||
|
@ -310,9 +310,6 @@
|
|||
[DllImport("D3DVisualization.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetCameraPhi(float phi);
|
||||
|
||||
[DllImport("D3DVisualization.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetRenderSize(int pixelWidth, int pixelHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Method used to invoke an Action that will catch DllNotFoundExceptions and display a warning dialog.
|
||||
/// </summary>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Wpf.Interop.DirectX">
|
||||
<HintPath>..\packages\Microsoft.Wpf.Interop.DirectX-x64.0.9.0-beta-22855\lib\net45\Microsoft.Wpf.Interop.DirectX.dll</HintPath>
|
||||
<HintPath>..\packages\Microsoft.Wpf.Interop.DirectX-x64.0.9.0-beta-22856\lib\net45\Microsoft.Wpf.Interop.DirectX.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Wpf.Interop.DirectX-x64" version="0.9.0-beta-22855" targetFramework="net45" />
|
||||
<package id="Microsoft.Wpf.Interop.DirectX-x64" version="0.9.0-beta-22856" targetFramework="net45" />
|
||||
</packages>
|
|
@ -8,7 +8,7 @@ namespace Microsoft {
|
|||
static D3D11Image::D3D11Image()
|
||||
{
|
||||
OnRenderProperty = DependencyProperty::Register("OnRender",
|
||||
Action<IntPtr>::typeid,
|
||||
Action<IntPtr, bool>::typeid,
|
||||
D3D11Image::typeid,
|
||||
gcnew UIPropertyMetadata(nullptr, gcnew PropertyChangedCallback(&RenderChanged)));
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace Microsoft {
|
|||
{
|
||||
if (image->Helper != nullptr)
|
||||
{
|
||||
image->Helper->RenderD2D = static_cast<Action<IntPtr>^>(args.NewValue);
|
||||
image->Helper->RenderD2D = static_cast<Action<IntPtr, bool>^>(args.NewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,14 +40,14 @@ namespace Microsoft {
|
|||
|
||||
/// The OnRender action delegate will fire and pass the surface to the application that the DirectX rendering component should
|
||||
/// render into.
|
||||
property Action<IntPtr>^ OnRender
|
||||
property Action<IntPtr, bool>^ OnRender
|
||||
{
|
||||
Action<IntPtr>^ get()
|
||||
Action<IntPtr, bool>^ get()
|
||||
{
|
||||
return static_cast<Action<IntPtr>^>(GetValue(OnRenderProperty));
|
||||
return static_cast<Action<IntPtr, bool>^>(GetValue(OnRenderProperty));
|
||||
}
|
||||
|
||||
void set(Action<IntPtr>^ value)
|
||||
void set(Action<IntPtr, bool>^ value)
|
||||
{
|
||||
SetValue(OnRenderProperty, value);
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ namespace Microsoft {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void SurfaceQueueInteropHelper::RenderToDXGI(IntPtr pdxgiSurface)
|
||||
void SurfaceQueueInteropHelper::RenderToDXGI(IntPtr pdxgiSurface, bool isNewSurface)
|
||||
{
|
||||
if (nullptr != m_renderD2D)
|
||||
{
|
||||
m_renderD2D(pdxgiSurface);
|
||||
m_renderD2D(pdxgiSurface, isNewSurface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,6 +297,8 @@ namespace Microsoft {
|
|||
UINT size = sizeof(int);
|
||||
|
||||
bool fNeedUnlock = false;
|
||||
|
||||
bool isNewSurface = !m_areSurfacesInitialized;
|
||||
|
||||
if (m_shouldSkipRender || (nullptr == m_d3dImage) || !Initialize())
|
||||
{
|
||||
|
@ -321,7 +323,7 @@ namespace Microsoft {
|
|||
// Render D3D10 content
|
||||
try
|
||||
{
|
||||
RenderToDXGI((IntPtr)(void*)pDXGISurface);
|
||||
RenderToDXGI((IntPtr)(void*)pDXGISurface, isNewSurface);
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
|
@ -342,7 +344,12 @@ namespace Microsoft {
|
|||
// Get the top level surface from the texture
|
||||
IFC(pTexture9->GetSurfaceLevel(0, &pSurface9));
|
||||
|
||||
m_d3dImage->SetBackBuffer(System::Windows::Interop::D3DResourceType::IDirect3DSurface9, (IntPtr)(void*)pSurface9, true /* enableSoftwareFallback */);
|
||||
m_d3dImage->SetBackBuffer(System::Windows::Interop::D3DResourceType::IDirect3DSurface9,
|
||||
(IntPtr)(void*)pSurface9,
|
||||
true // enableSoftwareFallback
|
||||
// Supports fallback to software rendering for Remote Desktop, etc...
|
||||
// Was added in WPF 4.5
|
||||
);
|
||||
|
||||
// Produce Surface
|
||||
m_ABProducer->Enqueue(pTexture9, &count, sizeof(int), SURFACE_QUEUE_FLAG_DO_NOT_WAIT);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Microsoft {
|
|||
public ref class SurfaceQueueInteropHelper : IDisposable
|
||||
{
|
||||
private:
|
||||
Action<IntPtr>^ m_renderD2D;
|
||||
Action<IntPtr, bool>^ m_renderD2D;
|
||||
D3DImage^ m_d3dImage;
|
||||
DependencyPropertyChangedEventHandler^ m_frontBufferAvailableChanged;
|
||||
UINT m_pixelWidth, m_pixelHeight;
|
||||
|
@ -48,7 +48,7 @@ namespace Microsoft {
|
|||
|
||||
HRESULT InitD3D10();
|
||||
|
||||
void RenderToDXGI(IntPtr pdxgiSurface);
|
||||
void RenderToDXGI(IntPtr pdxgiSurface, bool isNewSurface);
|
||||
|
||||
void CleanupD3D10();
|
||||
|
||||
|
@ -73,9 +73,9 @@ namespace Microsoft {
|
|||
public:
|
||||
|
||||
/// The action delegate called when a render is required.
|
||||
property Action<IntPtr>^ SurfaceQueueInteropHelper::RenderD2D
|
||||
property Action<IntPtr, bool>^ SurfaceQueueInteropHelper::RenderD2D
|
||||
{
|
||||
void set(Action<IntPtr>^ value) { m_renderD2D = value; }
|
||||
void set(Action<IntPtr, bool>^ value) { m_renderD2D = value; }
|
||||
}
|
||||
|
||||
/// Gets or sets the associated D3DImage object that is working in conjunction with this helper.
|
||||
|
|
Загрузка…
Ссылка в новой задаче