CDXBaseNTo1 is a base class that you can use to implement transforms that take multiple images or meshes as inputs and produce a single image or mesh output. If you choose not to use this base class, you can create a transform by directly implementing the IDXTransform interface, the IObjectWithSite Component Object Model (COM) interface, and, if you are using an image transform, the IDXSurfacePick interface. However, you will find it easier to use this base class because it performs parameter validation, preprocesses data, and implements the full IDXTransform interface. This simplifies development by only requiring implementation of the code specific to the transform.
The base class is a Microsoft® Active Template Library (ATL) object, which is based on the multi-threaded version of the CComObjectRootEx class. It implements IDXTransform, the IDXBaseObject interface, IObjectWithSite, the IObjectSafety ATL interface, and for image-to-image transforms, the IDXSurfacePick interface. CDXBaseNTo1 contains several data members that can be accessed directly. Other members can only be accessed through helper functions.
For more information about the IObjectWithSite and IObjectSafety interfaces, see the Platform SDK documentation.
This article contains the following sections.
When you use the CDXBaseNTo1 base class, you inherit data members that are important for basic transform functions. For more information, see the CDXBaseNTo1 Data Members reference.
You will probably need to change some of the base class defaults in the constructor of your derived class or, if you prefer, you can override the ATL CComObjectRootEx::FinalConstruct method and initialize the object there. The base class sets all default settings for one required input and one output image-to-image transform.
The m_dwOptionsFlags member is used to determine restrictions on inputs and outputs. If the transform takes mesh inputs, set the DXBOF_INPUTS_MESHBUILDERS flag. If the transform produces a mesh, set the DXBOF_OUTPUT_MESHBUILDER flag.
For image-to-image transforms that have multiple inputs, you can set DXBOF_SAME_SIZE_INPUTS, which will force the base class to make all input surfaces have the same width and height. In this case, the common size uses the largest width and height from all input surfaces, with undefined regions in the inputs padded with zero alpha samples. If this flag is set in combination with DXBOF_CENTER_INPUTS, images that are smaller than the common size will be placed in the center of the bounds, otherwise they will originate at (0,0).
Next, you must decide on the appropriate values for m_dwMiscFlags. The default setting for this data member is BLEND_SUPPORTED | DITHER_SUPPORTED | BOUNDS_SUPPORTED | PLACEMENT_SUPPORTED | BLEND_WITH_OUTPUT | DITHER_OUTPUT. This is the appropriate default setting for image-to-image transforms. If the image transform can support the Quality property, you should simply set m_dwMiscFlags |= DXTMF_QUALITY_SUPPORTED. If your transform produces a mesh and does not support Quality, set m_dwMiscFlags = 0, otherwise only set the QUALITY_SUPPORTED flag.
Set the m_ulMaxInputs member to the appropriate value. The default is 1.
Set the m_ulNumInRequired member to the appropriate value. The default is 1.
If the transform is an image-to-image transform, you can change m_ulMaxImageBands. If the transform cannot break operations into multiple bands, but you still want to use the WorkProc method of execution, set this member to 1. If you want to call the Execute method directly, set this member to 0, and your class's OnExecute method will be called. Otherwise, you would normally leave this at its default value, which is 4. For more information, see the Execution section.
When your transform's IDXTransform::Setup method is called, the base class validates the number and type of inputs and outputs, and, if everything looks correct, it calls your derived function, as shown in the following:
HRESULT OnSetup(DWORD dwSetupFlags);
The flags are undefined at this time and will always be zero. At this point, you can perform the initialization you need. You are not required to override the CDXBaseNTo1::OnSetup method. Typical operations that are performed during a call to CDXBaseNTo1::OnSetup are: copying input meshes to the output or determining the native pixel formats of inputs and outputs.
When the transform is cleared (or "un-setup") by a call to Setup with NULL input and output parameters, you can be notified to release the transform's resources by overriding CDXBaseNTo1::OnReleaseObjects, as shown in the following:
void OnReleaseObjects();
If the transform is an image-to-image transform, and you have not set m_ulMaxImageBands to zero, you should override the CDXBaseNTo1::WorkProc virtual function, as shown in the following:
HRESULT WorkProc(const CDXTWorkInfoNTo1 & WorkInfo, BOOL* pbContinueProcessing);
The CDXTWorkInfoNTo1 object contains a DoBnds data member, which specifies the logical portion of the output space to produce, and an OutputBnds data member, which specifies where the output should be placed on the output surface. Use the OutputBnds when locking the output surface to make sure you only request a write lock on the appropriate portion of the output surface to allow multiple bands to execute on separate processors.
If you are implementing a mesh transform, or you have set m_ulMaxImageBands to zero, you should override the CDXBaseNTo1::OnExecute virtual function, as shown in the following:
virtual HRESULT OnExecute( const GUID* pRequestID, const DXBNDS *pPortionBnds, const DXVEC * pPlacement )
When the CDXBaseNTo1::OnExecute method is called, the base class will have already performed appropriate parameter validation. For example, it makes sure that only supported parameters are provided (mesh transforms can ignore all of the parameters) and that the transform is appropriately set up prior to calling OnExecute. This makes implementation of Execute easier than overriding the IDXTransform::Execute method.
All transforms must support the IDXTransform::MapBoundsIn2Out method. Generally, you can accomplish this by simply overriding the appropriate version of the CDXBaseNTo1::DetermineBnds virtual function. For transforms that produce a mesh, override the DetermineBnds that operates on a CDXCBnds. For image-to-image transforms, override the DetermineBnds that operates on a CDXDBnds. If your transform performs a one-to-one mapping of input to output space, you don't need to implement DetermineBnds because the base class implements this by default.
If you are using an image transform, the bounds structure contains the union of all input bounds. You should modify the bounds to the resulting output bounds.
If you have a three-dimensional (3-D) transform that takes image inputs, the input bounds will be a normalized { {-1,1}, {-1,1}, {-1,1} } bounds, which you can modify and that will be returned as the output bounds.
If you have a 3-D transform that takes mesh inputs, the bounds will be a union of all of the input mesh bounds.
Transforms also must support the IDXTransform::MapBoundsOut2In method if the transform's input and output bounds differ. For example, this is the case for an image scaling transform. This method is important because it enables the base class to perform several operations generically, such as picking. If you implement surface picking in your transform, you need to override the IDXTransform::MapBoundsOut2In method.
Image transforms must implement picking by overriding the CDXBaseNTo1::OnSurfacePick method, which lets the derived class fully implement picking or by overriding the CDXBaseNTo1::OnGetSurfacePickOrder method, which requires the derived class to return stacking order and weights so the base class can determine which input was hit. If the transform does not have any inputs, the derived class should hit test against the output space returning DXT_S_HITOUTPUT for a successful hit.
The CDXBaseNTo1::InputSurface helper function returns an IDXSurface interface for the specified input. Similarly, the CDXBaseNTo1::OutputSurface function returns an IDXSurface interface for the output.
The CDXBaseNTo1::DoOver helper function returns TRUE if one or more inputs has transparent or translucent pixels and if the DXTMF_BLEND_WITH_OUTPUT flag is set in the m_dwMiscFlags. This is correct for most image transforms. However, if your transform creates transparent or translucent pixels, you should not use this helper function to determine whether to blend the transform output over the output surface. You should instead check that DXTMF_BLEND_WITH_OUTPUT flag is set in m_dwMiscFlags.
The CDXBaseNTo1::DoDither helper function returns TRUE under two possible circumstances: If there are no inputs and the DXTMF_DITHER_OUTPUT is set, the return value is TRUE. Also, if one or more of the inputs has a greater number of bits per pixel than the output surface and if DXTMF_DITHER_OUTPUT flag is set, the function returns TRUE.
For information on other helper functions, see the CDXBaseNTo1 Helper Function reference.
Top of Page
© 2000 Microsoft and/or its suppliers. All rights reserved. Terms of Use.