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

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

    // This plugin uses OpenGL to capture the current 3D view to a ppm file.
    //
    // To use it, give it a filename as an argument into which the PPM image
    // of the current view should be written.
    //
    // Limitations:
    //  - any parts of other X windows that are obscuring the view
    //    will be captured rather than the view underneath.  This is
    //    an effect of the OpenGL buffer system on SGIs.
    //
    //  - colour index mode buffers cannot be read by this plugin, so
    //    the view should be set to shaded mode before doing the capture.
    //    It is posible to read an OpenGL colour index mode buffer, but it
    //    is more complicated, and is therefore an exercise left to the
    //    readers.

    #include "viewCapturePPM.h"   // PPM routines

    #include <maya/MSimple.h>
    #include <maya/MObject.h>
    #include <maya/MGlobal.h>
    #include <maya/M3dView.h>

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

    #include <stdlib.h>
    #include <maya/MIOStream.h>

    DeclareSimpleCommand( viewCapture, PLUGIN_COMPANY, "3.0")

    MStatus viewCapture::doIt( const MArgList& args )
    {
        MStatus status = MS::kSuccess;

        if ( args.length() != 1 ) {
            // Need the file name argument
            //
            return MS::kFailure;
        }

        MString fileName;
        args.get( 0, fileName );

        // Get the active 3D view
        //
        M3dView view = M3dView::active3dView();

        // Capture the current view
        //
        view.refresh();
        view.beginGL();

        // Set the target for our pixel read to be the front buffer.  First, the
        // current state is saved using the glPushAttrib call.  It is important
        // to leave the OpenGL in the same state that we found it.
        //
        glPushAttrib( GL_PIXEL_MODE_BIT );

        int width = view.portWidth();
        int height = view.portHeight();

        // Allocate buffers for the pixel data
        //
        GLfloat * red   = new GLfloat[width*height];
        GLfloat * green = new GLfloat[width*height];
        GLfloat * blue  = new GLfloat[width*height];

        // Read the values from the OpenGL frame buffer
        //
        glReadBuffer( GL_FRONT );
        glReadPixels( 0, 0, width, height, GL_RED, GL_FLOAT, red );
        glReadPixels( 0, 0, width, height, GL_GREEN, GL_FLOAT, green );
        glReadPixels( 0, 0, width, height, GL_BLUE, GL_FLOAT, blue );

        // Put the gl read target back
        //
        glPopAttrib();

        view.endGL();

        // Write file as a PPM
        //
        Pic_Pixel * line = PixelAlloc( width );
        int idx;

        Pic * file = PicOpen( fileName.asChar(), (short) width, (short) height );
        if ( NULL != file ) {
            for ( int row = height - 1; row >= 0; row-- ) {
                // Covert the row of pixels into PPM format
                //
                for ( int col = 0; col < width; col++ ) {
                    // Find the array elements for this pixel
                    //
                    idx = ( row * width ) + ( col );
                    line[col].r = (Pic_byte)( red[idx]   * 255.0 );
                    line[col].g = (Pic_byte)( green[idx] * 255.0 );
                    line[col].b = (Pic_byte)( blue[idx] * 255.0 );
                }
                // Write the line
                //
                if ( !PicWriteLine( file, line ) ) {
                    status = MS::kFailure;
                    return MS::kFailure;
                }
            }
            PicClose( file );
        }

        delete []red;
        delete []green;
        delete []blue;
        PixelFree( line );

        return status;
    }