#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()
{
}
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;
}
}
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;
}
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 );
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 );
glColorMask( 1, 1, 1, 0 );
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
{
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();
}
else if ( mLocation == MHardwareRenderer::kPostExposure )
{
cout<<"Call EXP["<<exposureNum<<"/"<<totalExposureCount
<<"] hwRenderEffect::execute("<<width<<", "<<height<<") -- POST-EXPOSURE"<<endl;
}
}
return true;
}
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");
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;
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;
}