hwRenderPostEffect.cpp

//-
// ==========================================================================
// 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.
// ==========================================================================
//+

//
// DESCRIPTION: 
//              This is an example of adding processing
//              effects to the hardware renderer.
//

#ifdef WIN32
#pragma warning( disable : 4786 )               // Disable STL warnings.
#endif

#include <maya/MIOStream.h> 
#include <maya/MString.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>


#include <maya/MDrawProcedureBase.h>
#include <maya/MHardwareRenderer.h>

#include <stdio.h>

#if defined(OSMac_MachO_)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif

class hwRenderEffect : public MDrawProcedureBase
{
public:
                    hwRenderEffect();
    virtual         ~hwRenderEffect();

        virtual bool execute();

        static void deleteEffect( hwRenderEffect * ePtr);       
        static MDrawProcedureBase *createEffect( const MString &name, 
                                                        hwRenderEffect *ePtr,
                                                        MHardwareRenderer::CallLocation location);


        MHardwareRenderer::CallLocation mLocation;
};


hwRenderEffect::hwRenderEffect()
{
}

hwRenderEffect::~hwRenderEffect()
{
        // No-op
}

void
hwRenderEffect::deleteEffect( hwRenderEffect * ePtr) 
{
        if (ePtr)
        {
                MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer();
                if (pRenderer)
                {
                        const MString & backEndStr = pRenderer->backEndString();
                        MHardwareRenderer::DrawProcedureStatusCode result = 
                                pRenderer->removeDrawProcedure( backEndStr, ePtr, ePtr->mLocation );
                        cout<<"Call hwRenderEffect::deleteEffect("<<ePtr->fName.asChar()
                                <<") loc("<<ePtr->mLocation
                                <<") = "<<result<<endl;
                }
                delete ePtr;
                ePtr = 0;
        }
}

/*static*/
MDrawProcedureBase *
hwRenderEffect::createEffect( const MString &name, 
                                                        hwRenderEffect *ePtr,
                                                        MHardwareRenderer::CallLocation location)
{
        MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer();
        if (pRenderer)
        {
                if (!ePtr)
                {
                        ePtr = new hwRenderEffect();
                        ePtr->setEnabled( true );
                        ePtr->setName( name );  
                        ePtr->mLocation = location;

                        const MString & backEndStr = pRenderer->backEndString();
                        MHardwareRenderer::DrawProcedureStatusCode result = 
                                pRenderer->addDrawProcedure( backEndStr, ePtr, location );
                        cout<<"Call hwRenderEffect::createEffect("<<ePtr->name().asChar()
                                <<") loc("<<ePtr->mLocation
                                <<") = "<<result<<endl;
                }
        }
        return (MDrawProcedureBase *)ePtr;
}

/* virtual */
bool
hwRenderEffect::execute()
{
        MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer();
        if (!pRenderer)
                return false;

        const MString & backEndStr = pRenderer->backEndString();
        unsigned int width = 0, height = 0;

        MStatus stat = 
                pRenderer->getBufferSize( backEndStr, width, height );
        if (width <= 0 || height <= 0)
                return false;

        unsigned int exposureNum;
        unsigned int totalExposureCount;
        pRenderer->getCurrentExposureNumber( backEndStr, exposureNum );
        pRenderer->getTotalExposureCount( backEndStr, totalExposureCount );

        // Perform some post-rendering. Invert the image.
        bool xxxx = true;
        if ( xxxx && mLocation == MHardwareRenderer::kPostRendering )
        {
                cout<<"Call EXP["<<exposureNum<<"/"<<totalExposureCount
                        <<"] hwRenderEffect::execute("<<width<<", "<<height
                        <<") -- "<<fName.asChar()<<endl;

                MHardwareRenderer::BufferPixelFormat colFmt;
                stat = pRenderer->getColorBufferPixelFormat( backEndStr, colFmt );
                void *pixels = 0;
                unsigned int data_type = GL_UNSIGNED_BYTE; 
                unsigned int format = GL_RGBA;

                unsigned int totalSize = width*height*4;

                if (totalSize == 0)
                        return false;

                if (colFmt == MHardwareRenderer::kRGBA_Fix8)
                {
                        data_type = GL_UNSIGNED_BYTE; 
                        format = GL_RGBA;
                        pixels = new unsigned char[totalSize];
                }
#ifdef _SUPPORT_16_FLOAT_
                else if (MHardwareRenderer::kRGBA_Float16)
                {               
                        data_type = GL_HALF_FLOAT; 
                        format = GL_RGBA;
                        pixels = new half[totalSize];
                }
#endif
                glPushAttrib(GL_ALL_ATTRIB_BITS); 

                glMatrixMode(GL_PROJECTION);    
                glLoadIdentity();
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();

                glPixelZoom( 1.0f, 1.0f );
                glPixelStorei(GL_PACK_ALIGNMENT, 1);
                glReadPixels(0, 0, width, height, format, data_type, pixels);

                unsigned char *pixelPtr = (unsigned char*)pixels;
                if (pixelPtr)
                {
                        unsigned int numPixels = width * height;
                        for (unsigned int i=0; i < numPixels; i++)
                        {
                                *pixelPtr = (255 - *pixelPtr);  
                                pixelPtr++;
                                *pixelPtr = (255 - *pixelPtr);  
                                pixelPtr++;                     
                                *pixelPtr = (255 - *pixelPtr);  
                                pixelPtr++;
                                *pixelPtr = 255;        
                                pixelPtr++;
                        }
                }

                glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
                glRasterPos2i( -1, -1 );

                // We only want to clobber RGB. Leave alpha as is.
                glColorMask( 1, 1, 1, 0 );

                // For orthographic views, we need to make sure that depth
                // test is disabled, otherwise the pixels will not draw.
                glDisable(GL_DEPTH_TEST);

                glDrawPixels(width, height, format, data_type, pixels); 

                if (pixels)
                {
                        if (colFmt == MHardwareRenderer::kRGBA_Fix8)
                        {
                                unsigned char *pixelPtr2 = (unsigned char*)pixels;
                                delete[] pixelPtr2;
                        }
#ifdef _SUPPORT_16_FLOAT_
                        else
                        {
                                half pixelPtr2 = (half*)pixels;
                                delete[] pixelPtr2;
                        }
#endif
                }


                glPopAttrib();
        }
        else
        {
                // Perform some pre-rendering, pre-exposure. Draw coloured
                // triangles.
                if ( (mLocation == MHardwareRenderer::kPreRendering ) ||
                         ( mLocation == MHardwareRenderer::kPreExposure) )
                {
                        cout<<"Call EXP["<<exposureNum<<"/"<<totalExposureCount
                                <<"] hwRenderEffect::execute("<<width<<", "<<height
                                <<") -- "<<fName.asChar()<<endl;

                        glPushAttrib(GL_ALL_ATTRIB_BITS); 

                        glMatrixMode(GL_PROJECTION);    
                        glLoadIdentity();
                        glMatrixMode(GL_MODELVIEW);
                        glLoadIdentity();

                        glShadeModel(GL_SMOOTH);
                        glDisable(GL_DEPTH_TEST);
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_ONE, GL_ZERO);

                        glColorMask( 1, 1, 1, 0 );
                        glBegin(GL_QUADS);
                        glColor4f(1.0f,1.0f,1.0f,0.5f);
                        glVertex3f( -1.0f, 1.0f, 0.0f);
                        glColor4f(0.0f,1.0f,1.0f,0.5f);
                        glVertex3f( 0.0f, 1.0f, 0.0f);
                        glColor4f(0.0f,1.0f,1.0f,0.5f);
                        glVertex3f(-1.0f,-1.0f, 0.0f);
                        glColor4f(1.0f,0.0f,1.0f,0.5f);
                        glVertex3f( 1.0f,-1.0f, 0.0f);
                        glEnd();

                        glEnable(GL_DEPTH_TEST);
                        glDisable(GL_BLEND);

                        glPopAttrib();

                }

                // Do some post exposure. Nothing for now...
                else if ( mLocation == MHardwareRenderer::kPostExposure )
                {
                        cout<<"Call EXP["<<exposureNum<<"/"<<totalExposureCount
                                <<"] hwRenderEffect::execute("<<width<<", "<<height<<") -- POST-EXPOSURE"<<endl;
                }
        }

        return true;
}

// Four callback classes.
static hwRenderEffect *fsPreRender = 0;
static hwRenderEffect *fsPreExposure = 0;
static hwRenderEffect *fsPostExposure = 0;
static hwRenderEffect *fsPostRender = 0;

MStatus initializePlugin( MObject obj )
{ 
        MStatus   status = MS::kSuccess;
        
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "7.0", "Any");

        // Register the callbacks.
        fsPreRender = (hwRenderEffect *)hwRenderEffect::createEffect(MString("PRE-RENDER"), fsPreRender, MHardwareRenderer::kPreRendering );
        fsPreExposure = (hwRenderEffect *)hwRenderEffect::createEffect(MString("PRE-EXPOSURE"), fsPreExposure, MHardwareRenderer::kPreExposure );
        fsPostExposure = (hwRenderEffect *)hwRenderEffect::createEffect(MString("POST-EXPOSURE"), fsPostExposure, MHardwareRenderer::kPostExposure );
        fsPostRender = (hwRenderEffect *)hwRenderEffect::createEffect(MString("POST-RENDER"), fsPostRender, MHardwareRenderer::kPostRendering );
        return status;
}

MStatus uninitializePlugin( MObject obj )
{
        MStatus   status = MS::kSuccess;
        
        // Unregister the callbacks.
        hwRenderEffect::deleteEffect(fsPreRender);
        fsPreRender = 0;
        hwRenderEffect::deleteEffect(fsPreExposure);
        fsPreExposure = 0;
        hwRenderEffect::deleteEffect(fsPostExposure);
        fsPostExposure = 0;
        hwRenderEffect::deleteEffect(fsPostRender);
        fsPostRender = 0;

        MFnPlugin plugin( obj );

        return status;
}

Autodesk® Maya® 2009 © 1997-2008 Autodesk, Inc. All rights reserved. Generated with doxygen 1.5.6