BCB Components rotating around DirectX

Welcome to BCB-Tools.com Latest News

Development Tools Demo Applications Step-By-Step Tutorials Component Reference

Register Here Available Downloads

Frequently Asked Questions Links to other sites Information about the BCB-Tools.com website


    TUTORIAL - INSIDE THE TDx_LIBRARY
    Go to the Welcome Page
        INSIDE THE TDX_LIBRARY

    Read some step-by-step TDx_Library Tutorials...

    This tutorial is best viewed maximized, in 1024 x 768 screen resolution or better.




    OVERVIEW OF USING THE TDX_LIBRARY
    Top     Next

    The TDx_Library "wraps" DirectX on a 1:1 basis.

    For those not familiar with "wrappers", the idea is that all available DirectX functionality is
    translated and modified where necessary from Microsoft's "hungarian notation" style of programming
    to the much easier Visual Component Library (VCL) style of programming used in Borland C++ Builder.

    They say a picture is worth a thousand words, so here is an attempt :-



    In essence, the TDx_Library builds onto existing DirectX functionality while
    adding extra functionality around the DirectX core designed to help you create results quicker.






    INSIDE THE TDX_LIBRARY
    Top     Next     Prev



    Understanding the DirectX to TDx_Library relationship is easy:

    Above you can see some of the TDx_Draw_Library components highlighted on the Component Palette.

    The components on this palette represent all the different sections of DirectDraw wrapped into BCB components,
    each component translating all available features in a particular section of DirectDraw to it's VCL equivalent,
    with the end-result component wrapping and incorporating all DirectDraw functionality on a 1:1 basis.

    eg:
    • TDDBltFX wraps the DDBLTFX structure
    • TDDCaps wraps the DDCAPS structure
    • TDDColorKey wraps the DDCOLORKEY structure

    • ...
    • TDx_Draw wraps the IDirectDraw7 interface
    • TDx_DrawClipper wraps the IDirectDrawClipper interface
    • TDx_DrawColorControl wraps the IDirectDrawColorControl interface

    • ...
    • and so on, one component for each DirectDraw structure or interface.

    By dragging and dropping these components, setting up properties, adding some vcl code, you are indeed programming with DirectDraw, or DirectSound, or DirectInput or DirectPlay or Direct3DI.




    These components are really 3 distinct types, all derived from the standard BCB TComponent:
    • Wrappers
    • Multi Wrappers
    • Interface Wrappers

    Each of these 3 component types is designed to wrap a particular feature of DirectX.
    • Wrappers wrap a single DirectX structure
    • Multi Wrappers wrap and manage a dynamic array of DirectX structures
    • Interface Wrappers wrap an individual DirectX COM interface

    More information on each of the individual wrapper types is located below.






    WRAPPERS
    Top     Next     Prev

    A "Wrapper" component type takes a standard DirectX Structure Definition, and translates it to work in BCB.
    For example, below is the DDCOLORCONTROL structure definition defined within DirectDraw:
      struct DDCOLORCONTROL
      {
      DWORD dwSize;
      DWORD dwFlags;
      LONG lBrightness;
      LONG lContrast;
      LONG lHue;
      LONG lSaturation;
      LONG lSharpness;
      LONG lGamma;
      LONG lColorEnable;
      DWORD dwReserved1;
      };


    In "TDx_Library" terms, this becomes a standard vcl-style component:
      class TDDColorControl : public TComponent
      {
      // properties:

      __property dword Size;
      __property dword Flags;
      __property long Brightness;
      __property long Contrast;
      __property long Hue;
      __property long Saturation;
      __property long Sharpness;
      __property long Gamma;
      __property long ColorEnable;

      __property HRESULT ErrorValue;
      __property DDCOLORCONTROL* Internal_DDCOLORCONTROL_Ptr;
      __property AnsiString Flags_Strings;

      // methods:

      void __fastcall Clear();
      void __fastcall Internal_DDCOLORCONTROL_Update();

      // events:

      __property TDx_Error OnError();

      // internals:

      DDCOLORCONTROL fDDCOLORCONTROL;
      };


    a standard vcl-style component can be setup at design time:



    and can also be setup a runtime using vcl-style code:



    with automatic error detection:







    additional components are similar, but different:

        

        



    See these bits?
      // properties:

      __property HRESULT ErrorValue;
      __property DDCOLORCONTROL* Internal_DDCOLORCONTROL_Ptr;
      __property AnsiString Flags_Strings;

      // methods:

      void __fastcall Clear();
      void __fastcall Internal_DDCOLORCONTROL_Update();

      // events:

      __property TDx_Error OnError();

      // internals:

      DDCOLORCONTROL fDDCOLORCONTROL;


    This is what they are used for:

      __property HRESULT ErrorValue;

      This property contains the last DirectX or TDx_Library error code that was automatically detected by
      the wrapper component. This is usually an "out-of-range" error.


      __property DDCOLORCONTROL* Internal_DDCOLORCONTROL_Ptr;

      This property allows direct access to the internal DirectX structure, as is sometimes required.
      (Advanced Tip) when you copy data into a wrapper's internal structure using this property, and the
      VCL part of this component has already been linked to other component, you can auto-cascade your
      data into all linked TDx_Library components by calling the Internal_DDCOLORCONTROL_Update() method.


      __property AnsiString Flags_Strings;

      Whenever a component property has flags, a corresponding '_Strings' property is available for instant
      text retrieval of the currently set flags. For example, DDCaps1 (above) has Caps2, Caps, FXAlphaCaps, NLVBCaps2, etc.
      It also has text variants called 'Caps2_Strings', 'Caps_Strings', 'FXAlphaCaps_Strings', 'NLVBCaps2_Strings', etc.


      void __fastcall Clear();

      This method clears the internal structure's content, and if required, it resets dwSize to sizeof(DDCOLORCONTROL), or other structure.


      void __fastcall Internal_DDCOLORCONTROL_Update();

      This method is mostly used internally by the TDx_Library to maintain data integrity throughout different components that are linked together.
      For example, you can link a TDDSurfaceDesc::Caps property to a TDDSCaps component, and a
      TDDSurfaceDesc::PixelFormat property to a TDDPixelFormat component, then
      when the TDDSurfaceDesc's internal DDSURFACEDESC structure is modified, a call to the
      TDDSurfaceDesc::Internal_DDSURFACEDESC_Update() will automatically update the linked components
      internal data structures.


      __property TDx_Error OnError();

      This event is automatically called by the error detection code for each method,
      and can usually be setup as a one-stop-shop for all error handling code.


      DDCOLORCONTROL fDDCOLORCONTROL

      This is the internal storage of the DirectX DDCOLORCONTROL structure.
      (Advanced Tip) All the properties have FGet() & FSet() methods, which are used to auto-translate from DirectX to BCB,
      some have auto error-detection, and where possible, the DirectX structure elements are manipulated directly. For more complex
      translations, some DirectX structure elements are manipulated in tandem with BCB "shadow" elements.









    MULTI WRAPPERS
    Top     Next     Prev

    A "MultiWrapper" component is basically the same as a "Wrapper Component", except that it translates
    and automatically manages an array of structures internally instead of a single DirectX structure.

    These components are implemented where an array of structures is required to be passed to DirectX,
    and also when it is more convenient to store an array of data structures within the same component, ie. to save resources.

    Note that MultiWrapper components are used at runtime due to their dynamic nature.



    As a MultiWrapper example, below is the DDVIDEOPORTCONNECT structure definition defined within DirectDraw:
      struct DDVIDEOPORTCONNECT
      {
      DWORD dwSize;
      DWORD dwPortWidth;
      GUID guidTypeID;
      DWORD dwFlags;
      ULONG_PTR dwReserved1;
      };


    In the TDx_Library, this becomes a multiwrapper TComponent:
      class TDDVideoPortConnect : public TComponent
      {
      // properties:

      __property dword Size[ dword pArrayIndex ];
      __property dword PortWidth[ dword pArrayIndex ];
      __property GUID TypeID[ dword pArrayIndex ];
      __property dword Flags[ dword pArrayIndex ];

      __property dword SizeAll;
      __property dword ArraySize;
      __property HRESULT ErrorValue;
      __property DDVIDEOPORTCONNECT* Internal_DDCOLORKEY_Ptr[ dword pArrayIndex ];
      __property AnsiString Flags_Strings[ dword pArrayIndex ];

      // methods:

      void __fastcall Clear( dword pArrayIndex );
      void __fastcall ClearAll();
      void __fastcall Internal_DDVIDEOPORTCONNECT_Update();

      // events:

      __property TDx_Error OnError();

      // internals:

      DDVIDEOPORTCONNECT* fDDVIDEOPORTCONNECT;
      };


    See the 'pArrayIndex' parameter everywhere?

    A MultiWrapper maintains a dynamic array of structures, in this case an array of DDVIDEOPORTCONNECT structures.
    The 'pArrayIndex' parameter is used to access the data inside a particular structure.

    As an example :-
      void __fastcall TForm1::Button1Click( TObject* Sender )
      {
      // get number of video port connections
      dword port_id = 0;
      dword num_connections = 0;
      Dx_DrawVideoPortContainer1->GetVideoPortConnectInfo( port_id, &num_connections, NULL );

      // tell the TDDVideoPortConnect MultiWrapper to reallocate storage to handle 'num_connections' DDVIDEOPORTCONNECT structures.
      DDVideoPortConnect1->ArraySize = num_connections;

      // retrieve video port connection information
      Dx_DrawVideoPortContainer1->GetVideoPortConnectInfo( port_id, &num_connections, DDVideoPortConnect1 );

      // display results
      for (int i=0;i    ShowMessage( "#" + IntToStr(i) + ": " + DDVideoPortConnect1->Flags_Strings[i] );
      }








    INTERFACE WRAPPERS
    Top     Next     Prev

    An "Interface Wrapper" component wraps an entire DirectX COM (Component Object Model) interface, such as
    IDirectDraw7, IDirectDrawSurface7, IDirectSound, etc.

    All functions normally associated with the COM interface have been translated to work inside the wrapper
    as standard BCB-style component methods, with BCB-style parameters, automatic parameter checking,
    automatic error checking and redirection to the component's OnError() event, and so on.

    Basically, instead of having a COM interface with functions, you now have a BCB component with simplified VCL methods.

    Parameters that "must be" a given value, are no longer required to be passed to the method,
    and parameters that are not actually used do not need to be passed to the method.

    Methods return true if successful or false on failure: the automatic error handling removes the
    requirement to check each method return result for errors. If you want to check the error value
    immediately after calling a function, simply check the components 'ErrorValue' property.




    As an example, take a look at IDirectDraw7::EnumDisplayModes(), in it's COM format :-
      HRESULT EnumDisplayModes( DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback );
    Compare it to TDx_Draw::EnumDisplayModes(), the TDx_Library equivalent :-
      bool __fastcall TDx_Draw::EnumDisplayModes( dword Flags, TDDSurfaceDesc* SurfaceDesc, void* Context );
    Note the missing "Callback"? You don't have to implement callbacks.
    The TDx_Draw::EnumDisplayModes() method automatically calls the TDx_Draw::OnEnumDisplayModes() callback event instead!

    Note also the direct translation of parameters from DirectX conventions to VCL conventions.




    Another example, TDx_DrawSurface::Blt() :-
      HRESULT Blt( LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx );
    Becomes :-
      virtual bool __fastcall Blt( TRect* pDestRect, TDx_DrawSurface* pSrcSurface, TRect* pSrcRect, dword pFlags, TDDBltFX* pBltFx );
    This time, note the translation of the LPRECT to TRect?
    Same everywhere. Whatever can be translated has been translated.



    Each Interface Wrapper automatically creates and destroys it's own interface, saving much tedious programming.
    eg:
      void __fastcall TForm1::FormCreate( TObject* Sender )
      {
      if (Dx_Draw1->Create( NULL ))
          ShowMessage( "DirectDraw7 interface created successfully" );
      else
          ShowMessage( "Could not create DirectDraw7 interface" );
      }

      void __fastcall TForm1::FormDestroy( TObject* Sender )
      {
      if (Dx_Draw1->Created)
          if (Dx_Draw1->Destroy())
              ShowMessage( "DirectDraw7 interface destroyed successfully" );
          else
              ShowMessage( "Could not destroy DirectDraw7 interface" );
      }



    Upon successful creation of the COM interface, an interface wrapper calls it's OnCreate() event.
    Midway through destruction, just prior to destroying the COM interface, an interface wrapper calls it's OnDestroy() event.
    eg:
      void __fastcall TForm1::FormCreate( TObject* Sender )
      {
      Dx_Draw1->Create( NULL );
      }

      void __fastcall TForm1::FormDestroy( TObject* Sender )
      {
      if (Dx_Draw1->Created) Dx_Draw1->Destroy();
      }

      void __fastcall TForm1::Dx_Draw1Create( TObject* Sender )
      {
      ShowMessage( "DirectDraw7 interface created successfully" );
      }

      void __fastcall TForm1::Dx_Draw1Destroy( TObject* Sender )
      {
      ShowMessage( "DirectDraw7 interface is being destroyed" );
      }



    The OnCreate() and OnDestroy() events are fantastic for automatically cascading related data elements.
    eg:
      void __fastcall TForm1::FormCreate( TObject* Sender )
      {
      Dx_Draw1->Create( NULL );
      }

      void __fastcall TForm1::FormDestroy( TObject* Sender )
      {
      if (Dx_Draw1->Created) Dx_Draw1->Destroy();
      }

      void __fastcall TForm1::Dx_Draw1Create( TObject* Sender )
      {
      ShowMessage( "DirectDraw7 interface created successfully" );
      Dx_DrawSurface1->Create( DDSurfaceDesc1, Dx_Draw1 );
      }

      void __fastcall TForm1::Dx_Draw1Destroy( TObject* Sender )
      {
      ShowMessage( "DirectDraw7 interface is being destroyed" );
      if (Dx_DrawSurface1->Created) Dx_DrawSurface1->Destroy();
      }

      void __fastcall TForm1::Dx_DrawSurface1Create( TObject* Sender )
      {
      ShowMessage( "DirectDrawSurface interface created successfully" );
      Dx_DrawSurface1->GetCaps( DDSCaps1 );
      }

      void __fastcall TForm1::Dx_DrawSurface1Destroy( TObject* Sender )
      {
      ShowMessage( "DirectDrawSurface interface is being destroyed" );
      DDSCaps1->Clear();
      }



    Automatic error handling is easy:
      void __fastcall TForm1::Dx_Draw1Error( TObject* Sender, AnsiString Function, AnsiString Error, AnsiString ErrorMessage )
      {
      ShowMessage("An error occurred in the Dx_Draw1 component:\n\
          The Function: "+Function+"\nThe Error: "+Error+"\nThe Error Message: "+ErrorMessage );
      }


    DirectX Callbacks can be painful to implement within BCB.
    Within the TDx_Library, all callbacks are translated automatically and become easy-to-use BCB events.
    For example, the TDx_Draw::EnumDisplayModes() method automatically calls the TDx_Draw::OnEnumDisplayModes() event,
    the TDx_Draw::DDEnumerate() method automatically calls the TDx_Draw::OnDDEnumerate() event, etc.

    Below are examples of callback event's :-
      void __fastcall TForm1::Dx_Draw1DDEnumerate(TObject *Sender, GUID *Guid, AnsiString DriverDescription,
              AnsiString DriverName, void *Context, HMONITOR HMonitor, bool &Finished)
      {
      ShowMessage( "Found a DirectX Device:\n\
          Driver Name:"+DriverName+"\nDriver Description: "+DriverDescription );
      }

      void __fastcall TForm1::Dx_Draw1EnumDisplayModes(TObject *Sender, TDDSurfaceDesc *SurfaceDesc, void *Context,
              bool &Finished)
      {
      ShowMessage( "Found a Display Mode: "+
              IntToStr( (int)SurfaceDesc->Width) + "x" +
              IntToStr( (int)SurfaceDesc->Height) + "x" +
              IntToStr( (int)SurfaceDesc->PixelFormat->RGBBitCount) );
      }








    COMPONENT LIST
    Top     Next     Prev

    This is a list of the different component types for currently released libraries :-
    For detailed information on each component, try the component reference.

    TDx_Draw_Library
      TDDBltFX - Wrapper
      TDDCaps - Wrapper
      TDDColorControl - Wrapper
      TDDColorKey - Wrapper
      TDDDeviceIndentifier - Wrapper
      TDDGammaRamp - Wrapper
      TDDOverlayFX - Wrapper
      TDDPixelFormat - MultiWrapper
      TDDSCaps - Wrapper
      TDDSurfaceDesc - Wrapper
      TDDVideoPortBandwidth - Wrapper
      TDDVideoPortCaps - Wrapper
      TDDVideoPortConnect - MultiWrapper
      TDDVideoPortDesc - Wrapper
      TDDVideoPortInfo - Wrapper
      TDDVideoPortStatus - Wrapper
      TDx_Draw - Interface
      TDx_DrawClipper - Interface
      TDx_DrawColorControl - Interface
      TDx_DrawGammaControl - Interface
      TDx_DrawPalette - Interface
      TDx_DrawSurface - Interface
      TDx_DrawVideoPort - Interface
      TDx_DrawVideoPortContainer - Interface
    TDx_Sound_Library
      TDS3DBuffer - Wrapper
      TDS3DListener - Wrapper
      TDSBCaps - Wrapper
      TDSBPositionNotify - MultiWrapper
      TDSBufferDesc - Wrapper
      TDSCBCaps - Wrapper
      TDSCBufferDesc - Wrapper
      TDSCCaps - Wrapper
      TDSCaps - Wrapper
      TDx_Sound - Interface
      TDx_Sound3DBuffer - Interface
      TDx_Sound3DListener - Interface
      TDx_SoundBuffer - Interface
      TDx_SoundCapture - Interface
      TDx_SoundCaptureBuffer - Interface
      TDx_SoundKsPropertySet - Interface
      TDx_SoundNotify - Interface -> Hidden Thread not in DirectX
    TDx_Input_Library
      TDICondition - MultiWrapper
      TDIConstantForce - Wrapper
      TDICustomForce - Wrapper
      TDIDataFormat - Wrapper
      TDIDevCaps - Wrapper
      TDIDeviceInstance - Wrapper
      TDIDeviceObjectData - MultiWrapper
      TDIDeviceObjectInstance - Wrapper
      TDIEffectEscape - Wrapper
      TDIEffect - Wrapper
      TDIEffectInfo - Wrapper
      TDIEnvelope - Wrapper
      TDIFileEffect - MultiWrapper
      TDIJoyState - Wrapper
      TDIJoyState2 - Wrapper
      TDIKeyboardState - Wrapper -> not in DirectX
      TDIMouseState - Wrapper
      TDIMouseState2 - Wrapper
      TDIObjectDataFormat - MultiWrapper
      TDIPeriodic - Wrapper
      TDIPropDWORD - Wrapper
      TDIPropGuidAndPath - Wrapper
      TDIPropHeader - Wrapper
      TDIPropRange - Wrapper
      TDIPropString - Wrapper
      TDIRampForce - Wrapper
      TDx_Input - Interface
      TDx_InputDevice - Interface -> Hidden Thread not in DirectX
      TDx_InputEffect - Interface
    TDx_Play_Library
      TDPAccountDesc - Wrapper
      TDApplicationDesc - Wrapper
      TDPCaps - Wrapper
      TDPChat - Wrapper
      TDPComPortAddress - Wrapper
      TDPCompoundAddressElement - MultiWrapper
      TDPCredentials - Wrapper
      TDPLAppInfo - Wrapper
      TDPLConnection - Wrapper
      TDPName - Wrapper
      TDPSecurityDesc - Wrapper
      TDPSessionDesc - Wrapper
      TDx_Play - Interface -> Hidden Thread not in DirectX
      TDx_PlayLobby - Interface -> Hidden Thread not in DirectX
    TDx_3DI_Library
      TD3DClipStatus - Wrapper
      TD3DColorValue - Wrapper
      TD3DDP_PtrStride - MultiWrapper
      TD3DDevInfo_TextureManager - Wrapper
      TD3DDevInfo_Texturing - Wrapper
      TD3DDeviceDesc - Wrapper
      TD3DDrawPrimitiveStridedData - MultiWrapper
      TD3DLVertex - MultiWrapper
      TD3DLight - Wrapper
      TD3DLightingCaps - Wrapper
      TD3DLinePattern - Wrapper
      TD3DMaterial - Wrapper
      TD3DMatrix - Wrapper
      TD3DPrimCaps - Wrapper
      TD3DRect - MultiWrapper
      TD3DTLVertex - MultiWrapper
      TD3DVector - MultiWrapper
      TD3DVertex - MultiWrapper
      TD3DVertexBufferDesc - Wrapper
      TD3DViewport - Wrapper
      TDx_3D - Interface
      TDx_3DDevice - Interface
      TDx_3DVertexBuffer - Interface






    MORE INFORMATION
    Top     Next     Prev

    For more information, choose from the following links :-




























Top

Welcome |  Latest News |  Tools |  Demos |  Tutorials |  Reference |  Register |  Downloads
FAQ |  Links |  Site Information

This page is Copyright © 2007++ Darren John Dwyer, Australia. All Rights Reserved.
Borland C++ Builder, CBuilder, etc are Trademarks of Borland Corporation.
DirectX, DirectDraw, Windows, etc are Trademarks of Microsoft Corporation.