Jump to content
gioma

D2D1Missing - Direct2D 1.1 ID2D1DeviceContext : How to use it?

Recommended Posts

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

Thanks but It doesn't work on Delphi , it needs many corrections 😞

Share this post


Link to post

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

  • Like 1
  • Thanks 1

Share this post


Link to post
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
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
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
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
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.

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×