#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:
~MyMPxGlBuffer() override;
};
MyMPxGlBuffer::MyMPxGlBuffer(
M3dView &view ) :
{
}
MyMPxGlBuffer::~MyMPxGlBuffer()
{
}
void MyMPxGlBuffer::beginBufferNotify()
{
glPushAttrib(GL_COLOR_BUFFER_BIT);
glClearColor( 0.0, 0.0, 0.0, 0.0 );
}
void MyMPxGlBuffer::endBufferNotify()
{
glPopAttrib();
}
{
public:
blastCmd();
~blastCmd() override;
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];
if( iffOutput.
create( fWidth, fHeight ) != MS::kSuccess )
{
cerr << "Failed to create output image\n";
return MS::kFailure;
}
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());
stat = MS::kFailure;
}
else
{
sprintf(msgBuffer, "output from %s buffer to %s done.\n",
(onscreen ? "on-screen" : "off-screen"),
suffixName.asChar());
stat = MS::kSuccess;
}
#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)
{
return MS::kFailure;
}
if( !onscreen )
{
offBuff = new MyMPxGlBuffer( view );
if( ! offBuff->openFbo( fWidth, fHeight, view ) )
{
delete offBuff;
offBuff = NULL;
return MS::kFailure;
}
}
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;
}