- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Examples

# hlslShader.h

    #ifndef _hlslShader_h_
    #define _hlslShader_h_
    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+

    #include <maya/MPxCommand.h>
    #include <maya/MPxHardwareShader.h>
    #include <maya/MTypeId.h>
    #include <maya/MStringArray.h>
    #include <maya/MVaryingParameter.h>
    #include <maya/MUniformParameter.h>
    #include <maya/MUniformParameterList.h>
    #include <maya/MRenderProfile.h>

    #include <maya/MHwrCallback.h>

    #include <d3d9.h>
    #include <d3dx9.h>

    /*
    //
    // A varying parameter
    //
    class hlslVaryingParameter
    {
    public:
        MVaryingParameter   fMayaParameter;
    };

    //
    // A pass
    //
    class hlslPass
    {
    public:
        inline              hlslPass( 0) : fNumParameters( 0), fParameters( NULL) {}
        inline              ~hlslPass() { if( fParameters) delete fParameters; }
        inline int          numParameters() const { return fNumParameters; }
        inline void         numParameters( int numParms) { if( fParameters) delete fParameters; fNumParameters = numParms; fParameters = numParms ? new hlslVaryingParameter[ numParms] : NULL; }
        inline hlslVaryingParameter& parameter( int p) const { return fParameters[ p]; }

    protected:
        hlslVaryingParameter* fParameters;
        int                 fNumParameters;
    };
    */

    class hlslShader;

    // Callback structure to handle device changes
    //
    class hlslDeviceManager : public MHwrCallback
    {
    public:
        typedef enum
        {
            kInvalid,
            kReset,
            kValid
        } hlslDeviceState;
        inline hlslDeviceManager( hlslShader& shader) : fShader( shader), fState( kValid) { addCallback( this); }
        ~hlslDeviceManager() { removeCallback( this); }
        virtual void deviceNew();
        virtual void deviceLost();
        virtual void deviceReset();
        virtual void deviceDeleted();
        inline hlslDeviceState  deviceState() { return fState; }
        void resetShader();

    private:
        // Hide this bad boy to let the compiler know it shouldn't be able to generate an assignment operator
        void operator=( const hlslDeviceManager&) {};

    protected:
        hlslDeviceState fState;
        hlslShader& fShader;
    };

    // Our shader node itself!
    //
    class hlslShader : public MPxHardwareShader
    {
    public:

        friend class hlslDeviceManager;

        // PxNode housekeeping: create, copy setup
                            hlslShader();
        virtual void        postConstructor();
        virtual             ~hlslShader();
        static  void*       creator();
        static  MStatus     initialize();
        static  void        initializeNodeAttrs();

        // Internal attribute housekeeping
        virtual void        copyInternalData( MPxNode* pSrc );
        virtual bool        getInternalValueInContext( const MPlug&,
                                                  MDataHandle&,
                                                  MDGContext&);
        virtual bool        setInternalValueInContext( const MPlug&,
                                                  const MDataHandle&,
                                                  MDGContext&);

        // Override geometry rendering
        virtual MStatus     render( MGeometryList& iterator);

        // Indicate pass transparency options
        virtual unsigned int    transparencyOptions();

        // Query the renderers supported by this shader
        //
        virtual const MRenderProfile& profile();

        // Override this method to draw a image for swatch rendering.
        virtual MStatus renderSwatchImage( MImage & image );

        // Override these method to support texture display in the UV texture editor.
        //
        virtual MStatus getAvailableImages( const MPxHardwareShader::ShaderContext &context,
                                            const MString &uvSetName,
                                            MStringArray &imageNames );
        virtual MStatus renderImage( const MPxHardwareShader::ShaderContext &context,
                                    const MString &imageName,
                                    floatRegion region,
                                    const MPxHardwareShader::RenderParameters& parameters,
                                    int &imageWidth,
                                    int &imageHeight );

        // UVLink utility
        //
        MStatus uvLinks( const MString& varyingParamName, MStringArray& uniformTextureNames );

    public:

        // Release all our device handles
        void                release();

        // The typeid is a unique 32bit indentifier that describes this node.
        // It is used to save and retrieve nodes of this type from the binary
        // file format.  If it is not unique, it will cause file IO problems.
        //
        static  MTypeId sId;

        // Our rendering profile
        //
        static MRenderProfile sProfile;

        // There needs to be a MObject handle declared for each attribute that
        // the node will have.  These handles are needed for getting and setting
        // the values later.
        //
        // Input shader attribute
        //
        static  MObject sShader;
        static  MObject sTechnique;
        static  MObject sTechniques;
        static  MObject sDescription;
        static  MObject sDiagnostics;

    protected:

        // Change the shader or technique we're using
        MStatus         setShader( const MString& shader);
        MStatus         setTechnique( const MString& technique);
        bool            passHasTranparency( D3DXHANDLE passHandle );

        // Resource management
        hlslDeviceManager   fDeviceManager;
        void            releaseVertexDeclaration();

        // Values of internal attributes
        MString         fShader;
        MString         fTechnique;
        MStringArray    fTechniques;

        // The current daignostics/description strings
        MString         fDescription;
        MString         fDiagnostics;

        // D3D resources
        LPD3DXEFFECT    fD3DEffect;
        D3DXHANDLE      fD3DTechnique;
        D3DXEFFECT_DESC fD3DEffectDesc;
        D3DXTECHNIQUE_DESC fD3DTechniqueDesc;

        // The current set of parameters
        MVaryingParameter fVertexStructure;
        IDirect3DVertexDeclaration9** fD3DVertexDeclaration;
        MUniformParameterList fUniformParameters;
        bool                  fTechniqueHasBlending;

        // Utilities for converting D3D -> Maya
        void            setupUniform( D3DXHANDLE d3dParameter, const MString& prefix);
        bool            GetAnnotation( D3DXHANDLE parameter, const char* name, LPCSTR& value);
        bool            GetBOOLAnnotation( D3DXHANDLE parameter, const char* name, BOOL& value);
        bool            GetAnnotation( D3DXHANDLE parameter, const char* name, float& value);
        bool            GetAnnotation( D3DXHANDLE parameter, const char* name, int& value);
        MUniformParameter::DataSemantic ConvertSemantic( D3DXHANDLE parameter, D3DXPARAMETER_DESC& description);
        MUniformParameter::DataType     ConvertType( D3DXHANDLE parameter, D3DXPARAMETER_DESC& description);
        MUniformParameter::DataSemantic ConvertSpace( D3DXHANDLE parameter, D3DXPARAMETER_DESC& description, MUniformParameter::DataSemantic defaultSpace);

        void            updateUIVisibilityFromAnnotation( D3DXHANDLE d3dParameter, MUniformParameter& uniform);
        void            updateRangeFromAnnotation( D3DXHANDLE d3dParameter, MUniformParameter& uniform);

        // Ummm ... don't ask
        inline hlslShader& me() { return *this; }

        // Housekeeping
        int             fErrorCount;
        void            reportInternalError( const char* function, size_t errcode );
    };

    class hlslShaderCmd : MPxCommand
    {
    public:
                            hlslShaderCmd();
        virtual             ~hlslShaderCmd();

        MStatus             doIt( const MArgList& );
        bool                isUndoable() { return false; }

        static MSyntax      newSyntax();
        static void*        creator();
    };

    #endif /* _hlslShader_h_ */