gioma 19 Posted May 6, 2022 I have an application that uses a TDirect2DCanvas to render an image stream. However, I noticed that the iterpolation used is only Linear (Direct2D 1.0), but if I wanted to use those introduced with Direct2D 1.1 (bicubic, etc.) i would have to add unit Winapi.D2DMissing. Now the problem is that the TDirect2DCanvas does not use ID2D1DeviceContext (added in Winapi.D2DMissing) as the rendering target but ID2D1RenderTarget. I can't figure out how to use the new Direct2D 1.1 features. Anyone has any ideas? Share this post Link to post
Vandrovnik 215 Posted May 6, 2022 (edited) I have found and used this, instead of the outdated (maybe it is not in D11.1?) version in Delphi: https://github.com/CMCHTPC/DelphiDX12 But I do not use TDirect2DCanvas. Edited May 6, 2022 by Vandrovnik Share this post Link to post
gioma 19 Posted May 6, 2022 Thanks but It doesn't work on Delphi , it needs many corrections 😞 Share this post Link to post
TiGü 21 Posted May 6, 2022 You can check if your normal ID2D1RenderTarget/ID2D1HwndRenderTarget/ID2D1DCRenderTarget from the TDirect2DCanvas supports the newer Direct2D 1.1 ID2D1DeviceContext. Something like this: // Self.Handle is the HWND of your Form... FVCLCanvas := TDirect2DCanvas.Create(Self.Handle); var DeviceContext: ID2D1DeviceContext; if Supports(FVCLCanvas.RenderTarget, ID2D1DeviceContext, DeviceContext) then begin var YourPointer: Pointer; var DontForgetThePitch := 1024; var AllImportantBitmapProperties: D2D1_BITMAP_PROPERTIES1; var D2D1Bitmap: ID2D1Bitmap1; DeviceContext.CreateBitmap(SizeU(1024,1024), YourPointer, DontForgetThePitch, @AllImportantBitmapProperties, D2D1Bitmap); DeviceContext.DrawImage(D2D1Bitmap, nil, nil, D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC); end; I assume you will find out the details on your own (Fill the Pointer to your Data, Pitch, Bitmap props). Or you build the entire Direct 2D 1.1 - 1.3 thing by yourself and forget the crappy TDirect2DCanvas. Microsoft had a lot of DirectX samples and all of them have a abstract class called "DirectXBase" (e.g. https://github.com/microsoft/VCSamples/blob/master/VC2012Samples/Windows 8 samples/C%2B%2B/Windows 8 app samples/Direct2D interpolation modes sample (Windows 8)/C%2B%2B/DirectXBase.cpp). You can use the attachment pascal unit as a starting point. I recommend the header translations from MfPack (https://github.com/FactoryXCode/MfPack) for this. DirectXBase.pas 1 1 Share this post Link to post
Vandrovnik 215 Posted May 6, 2022 1 hour ago, gioma said: Thanks but It doesn't work on Delphi , it needs many corrections 😞 I do use it in Delphi application... Share this post Link to post
gioma 19 Posted May 6, 2022 16 minutes ago, Vandrovnik said: I do use it in Delphi application... I use Delphi Alexandria and when compiling the example projects there are many errors due to missing {$IFDEF FPC} and if I set FPC between the conditional defines there are commands that don't exist in Delphi. I use Delphi Alexandria and when compiling the example projects there are many errors due to missing {$IFDEF FPC} and if I set FPC between the conditional defines there are commands that don't exist in Delphi. Share this post Link to post
gioma 19 Posted May 6, 2022 1 hour ago, TiGü said: You can check if your normal ID2D1RenderTarget/ID2D1HwndRenderTarget/ID2D1DCRenderTarget from the TDirect2DCanvas supports the newer Direct2D 1.1 ID2D1DeviceContext. Something like this: // Self.Handle is the HWND of your Form... FVCLCanvas := TDirect2DCanvas.Create(Self.Handle); var DeviceContext: ID2D1DeviceContext; if Supports(FVCLCanvas.RenderTarget, ID2D1DeviceContext, DeviceContext) then begin var YourPointer: Pointer; var DontForgetThePitch := 1024; var AllImportantBitmapProperties: D2D1_BITMAP_PROPERTIES1; var D2D1Bitmap: ID2D1Bitmap1; DeviceContext.CreateBitmap(SizeU(1024,1024), YourPointer, DontForgetThePitch, @AllImportantBitmapProperties, D2D1Bitmap); DeviceContext.DrawImage(D2D1Bitmap, nil, nil, D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC); end; I assume you will find out the details on your own (Fill the Pointer to your Data, Pitch, Bitmap props). Or you build the entire Direct 2D 1.1 - 1.3 thing by yourself and forget the crappy TDirect2DCanvas. Microsoft had a lot of DirectX samples and all of them have a abstract class called "DirectXBase" (e.g. https://github.com/microsoft/VCSamples/blob/master/VC2012Samples/Windows 8 samples/C%2B%2B/Windows 8 app samples/Direct2D interpolation modes sample (Windows 8)/C%2B%2B/DirectXBase.cpp). You can use the attachment pascal unit as a starting point. I recommend the header translations from MfPack (https://github.com/FactoryXCode/MfPack) for this. DirectXBase.pas So I could start from the Vcl.Direct2D unit to create a unit that uses DirectD2 1.1..mm.. it could be an indea. For now I have done this and it seems to work, but I don't know if I use Direct2D 1.1 at 100% _scale := width / _HostDesktopWidth; IMGpitch:=_HostDesktopWidth*4; if (DesktopFrame=nil) or ( _DesktopFrameRect.right <> _HostDesktopWidth ) or ( _DesktopFrameRect.bottom <> _HostDesktopHeight ) then begin _DesktopFrameRect.left:=0; _DesktopFrameRect.right:=_HostDesktopWidth; _DesktopFrameRect.top:=0; _DesktopFrameRect.bottom:=_HostDesktopHeight; BitmapProp.DpiX := 0; BitmapProp.DpiY := 0; BitmapProp.pixelFormat.Format := DXGI_FORMAT_B8G8R8A8_UNORM; BitmapProp.pixelFormat.AlphaMode := D2D1_ALPHA_MODE_IGNORE; _FD2DCanvas.RenderTarget.CreateBitmap(D2D1SizeU(_HostDesktopWidth, _HostDesktopHeight), _IMGBuffer, IMGpitch, BitmapProp, DesktopFrame); WriteLog('[Paint] CreateBitmap '+intToStr(_HostDesktopWidth)+'x'+intToStr(_HostDesktopHeight) ); end else begin _DesktopFrameRect.left:=0; _DesktopFrameRect.right:=_HostDesktopWidth; _DesktopFrameRect.top:=0; _DesktopFrameRect.bottom:=_HostDesktopHeight; DesktopFrame.CopyFromMemory(_DesktopFrameRect,_IMGBuffer,IMGpitch); end; if _firstRender then begin _ConnectionStartedAt:=GetTickCount; ComputeTransform; _firstRender:=false; end; _FD2DCanvas.RenderTarget.SetTransform(_FTransform); LRect.left:=0; LRect.right:=_HostDesktopWidth; LRect.top:=0; LRect.bottom:=_HostDesktopHeight; (_FD2DCanvas.RenderTarget as ID2D1DeviceContext ).DrawBitmap(DesktopFrame,LRect,1, _InterpolationMode); Share this post Link to post
TiGü 21 Posted May 9, 2022 On 5/6/2022 at 6:05 PM, gioma said: For now I have done this and it seems to work, but I don't know if I use Direct2D 1.1 at 100% Does it work? Do you see a difference between the various interpolation modes? Share this post Link to post
gioma 19 Posted May 9, 2022 5 hours ago, TiGü said: Does it work? Do you see a difference between the various interpolation modes? it seems incredible but it seems to work, there is a difference between the various interpolations. 1 Share this post Link to post