#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <maya/MFStream.h>
#include <maya/M3dView.h>
#include <maya/MPxGlBuffer.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MGlobal.h>
#include <maya/MAnimControl.h>
#include <maya/MImage.h>
#include <maya/MIOStream.h>
#define OUTPUT_IFF_FILES
typedef unsigned char uchar_t;
#define kOnscreenFlag       "-o"
#define kOnscreenFlagLong   "-onscreen"
#define kFilenameFlag       "-f"
#define kFilenameFlagLong   "-filename"
#define kStartFlag          "-s"
#define kStartFlagLong      "-start"
#define kEndFlag            "-e"
#define kEndFlagLong        "-stop"
#define commandName         "blast"
public: 
    virtual ~MyMPxGlBuffer();
    
};
MyMPxGlBuffer::MyMPxGlBuffer( 
M3dView &view ) : 
{
}
MyMPxGlBuffer::~MyMPxGlBuffer()
{
}
    
void MyMPxGlBuffer::beginBufferNotify()
{
    glClearColor( 0.0, 0.0, 0.0, 0.0 ); 
}
void MyMPxGlBuffer::endBufferNotify()
{
}
{
public:
    blastCmd();
    virtual         ~blastCmd(); 
    static void*    creator();
private:
    bool            onscreen;
    MyMPxGlBuffer   *offBuff;
    short           fHeight;
    short           fWidth;
    int             fPixelCnt;
    uchar_t         *fPixels;
};
blastCmd::blastCmd()
{
    offBuff = NULL;
}
blastCmd::~blastCmd()
{
    
    
    delete offBuff;
}
void* blastCmd::creator()
{
    return (void *)(new blastCmd);
}
{
     syntax.
addFlag(kOnscreenFlag, kOnscreenFlagLong);
     return syntax;
}
{
    onscreen = argData.isFlagSet(kOnscreenFlag);
    start = 0.0;
    end = 1.0;
    if (argData.isFlagSet(kFilenameFlag))
    {
        stat = argData.getFlagArgument(kFilenameFlag, 0, filename);
    }
    else
    {
        filename = "blastOut";
    }
    if (argData.isFlagSet(kStartFlag))
    {
        argData.getFlagArgument(kStartFlag, 0, start);
    }
    if (argData.isFlagSet(kEndFlag))
    {
        argData.getFlagArgument(kEndFlag, 0, end);
    }
    return stat;
}
{
    suffixName += ".";
    suffixName += frame.
value();
    
    
    
    
#ifdef OUTPUT_IFF_FILES
    char msgBuffer[256];
    
    
    {
        cerr << "Failed to create output image\n";
    }
    unsigned char *iffPixels = iffOutput.
pixels();
 
    unsigned char *glPixels = fPixels;
    for ( int pixCtr = 0; pixCtr < fPixelCnt; pixCtr++ )
    {
        *iffPixels = *glPixels; 
        glPixels++;
        iffPixels++;
        *iffPixels = *glPixels;     
        glPixels++;
        iffPixels++;
        *iffPixels = *glPixels;     
        glPixels++;
        iffPixels++;
        *iffPixels = *glPixels;     
        glPixels++;
        iffPixels++;
    };
    
    
    
    
    
    
    
    {
        
        
        sprintf(msgBuffer, "Failed to output image to %s\n", suffixName.asChar());
    }
    else
    {
        
        
        sprintf(msgBuffer, "output from %s buffer to %s done.\n",
                (onscreen ? "on-screen" : "off-screen"),
                suffixName.asChar());
    }
#else
    
    
    
    
    ofstream    image( suffixName.asChar() );
    
    
    
    image << "id=ImageMagick\n";
    image << "columns= " << fWidth << "\nrows=" << fHeight << "\n:\n";
    
    
    
    for( int row = fHeight-1; row >= 0 ; row-- )
    {
        const  uchar_t  *rowpixels = fPixels + ( row * fWidth * 4);
        for( int col = 0; col < fWidth; col++ )
        {
            image << *rowpixels++;
            image << *rowpixels++;
            image << *rowpixels++;
            image << *rowpixels++; 
        }
    }
    image.close();
    
    
    
#endif
    return stat;
}
{
    char msgBuffer[256];
    stat = parseArgs ( args );
    if ( !stat )
    {
        sprintf( msgBuffer, "Failed to parse args for %s command\n", commandName );
        return stat;
    }
    
    
    
    
    fPixelCnt = fWidth * fHeight;
    
    
    fPixels = new uchar_t[fPixelCnt * 4];
    
    
    if (!fPixels)
    {
    }
    if( !onscreen )
    {
        
        
        
        offBuff = new MyMPxGlBuffer( view );
        
        
        
        if( ! offBuff->openFbo( fWidth, fHeight, view ) ) 
        {
            
            
            
            
            
            delete offBuff;
            offBuff = NULL;
        }
    }
    for ( 
MTime curTime = start; curTime <= end; curTime++ )
 
    {
        if( !onscreen )
        {
            
            
            
            
            
            offBuff->bindFbo();
        }
        else
        {
            
            
            
            glReadBuffer(GL_FRONT);
        }
    
        
        
        
        
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glReadPixels(0, 0, fWidth, fHeight, GL_RGBA, GL_UNSIGNED_BYTE, fPixels);
        
        if ( offBuff ) { 
            offBuff->unbindFbo();
        }
        
        fileDump( curTime );
    }
    
    
    if ( offBuff ) { 
        offBuff->closeFbo( view );
        delete offBuff;
        offBuff = NULL;
    }
    delete [] fPixels;
    return stat;
}
{
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"6.0", 
"Any");
 
    status = plugin.registerCommand( commandName,
                                      blastCmd::creator,
                                      blastCmd::newSyntax);
    if (!status) {
        status.
perror(
"registerCommand");
        return status;
    }
    return status;
}
{
    status = plugin.deregisterCommand( commandName );
    if (!status) {
        status.
perror(
"deregisterCommand");
        return status;
    }
    return status;
}