About Transforms and DXSurfaces

Microsoft DirectX Transform objects apply space and time effects to Microsoft DirectDraw objects. Microsoft DirectX Transform objects read data from a source, modify it, and write it to a destination object. In certain cases the source and destination data objects can be the same if the transform is capable of executing in place. Microsoft DirectX Transform exposes a number of Component Object Model (COM) interfaces and data types that enable you to create your own unique effects and plug them into the existing architecture.

Applying Transforms To DXSurfaces

The most common use of a transform interface is to apply an effect to a DXSurface object that contains a bitmap image. Transforms can include transitions, convolutions, warps, spatial transforms, and color lookup table operations, such as brightening, contrasting, and gamma correcting. Transforms are created and initialized by using the IDXTransformFactory::CreateTransform method and are executed with the IDXTransform::Execute method.

DXSurface objects are the core image data objects for transforms. A DXSurface wraps a DirectDrawSurface through aggregation and provides additional functionality, such as color lookup and seamless conversion among different pixel formats. DXSurfaces can also be procedural surfaces that dynamically calculate the necessary pixel values when the surface is accessed instead of simply being an array of discrete values like a DirectDrawSurface object. Any surface that is not a DXSurface, such as a DirectDrawSurface, that is passed to a transform is wrapped in a DXSurface when the IDXTransform::Setup method is called. This provides a standard object for all transforms to interface with and a consistent model for reading and writing pixels.

All transforms on DXSurfaces must support data access through either the IDXARGBReadPtr or IDXARGBReadWritePtr interface, or both. These interfaces provide simplified access to the underlying samples in both of the following pixel formats: ARGB32 or alpha-premultiplied PMARGB32. Transforms gain access to these interfaces through the IDXSurface::LockSurface method and use them to call the IDXARGBReadPtr::Unpack or IDXARGBReadWritePtr::PackAndMove methods, which read and write the surface's pixels. Conversion to a common pixel format from an input surface and into an output surface simplifies the transform by making it pixel-format independent; therefore, the transform is spared the details of converting between the numerous pixel formats that are commonly used. It also allows the format of the source and the destination to differ without writing special-case transform code. If a transform recognizes both the input and output native data formats, it can go directly to the data, avoiding any intermediate conversion of the pixels. However, the pixel abstraction APIs provided are highly efficient, so writing special-case native pixel routines should be unnecessary.

Transforms describe regions of an image with the DXBNDS union structure. This structure describes an (x, y, z, t) volume in 64-bit, 32-bit, continuous, and discrete values, depending on the specific structure type. The CDXBnds template helper class can take bounds of any type and appropriately convert where necessary. Transforms should always work using bounds in their native coordinate type.

The following diagram details the process of using the IDXTransform::Execute method. This diagram assumes the transform has been created and set up correctly prior to the execution of the transform. For details on initialization and setup, see Using Transforms in C++.

The previous diagram illustrates the following steps that occur when the IDXTransform::Execute method is used.

  1. Surfaces are associated with specific Microsoft DirectX Transform objects in the IDXTransform::Setup method before the call to IDXTransform::Execute. The transform obtains the IDXSurface interface from the input DXSurfaces associated with it at this time.
  2. The transform uses IDXSurface::LockSurface with the DXLOCKF_READ flag set to create a read pointer object and return an IDXARGBReadPtr interface. This object can be used to access the DXSurface's samples.
  3. The IDXARGBReadPtr::Unpack method is used to read the pixel samples and convert them into an ARGB32 pixel format. You can optionally use the IDXARGBReadPtr::UnpackPremult method to convert samples to the alpha-premultiplied PMARGB32 format.
  4. The transform performs operations on the samples.
  5. The transform obtains the IDXSurface interface from the output DXSurface associated with it.
  6. The transform uses IDXSurface::LockSurface with the DXLOCKF_READWRITE flag set to create a read/write pointer object and to return an IDXARGBReadWritePtr interface. This object can be used to access the DXSurface's pixel samples.
  7. The IDXARGBReadWritePtr::PackAndMove method is used to convert ARGB32 samples into the underlying native pixel format and to write them to the output DXSurface. You can optionally use the IDXARGBReadWritePtr::PackPremultAndMove method to convert the PMARGB32 samples into the underlying pixel format and to write the samples to the output DXSurface.