Process


詳細

レンダリング エンジンがプロセスを実行するように要求されるときに常に発生します(たとえば、フレームをレンダリングするとき)。 シーケンスの場合、他のレンダ ジョブに切り替える前に、シーケンス内のすべてのフレームが呼び出されます(ただし、シーケンスが完了する前にレンダを終了することができます)。 これによって、レンダラは前のフレームのデータを確実に再利用できます。

Process コールバックは、RendererContext を使用してレンダラ オプションのプロパティを取得し、Framebuffer 情報を取得して、タイル データを Render Manager に返します。


適用対象

カスタム レンダラ


構文

CStatus <renderer_name>_Process( CRef& in_context )
{ 
        ... 
}

<renderer_name> は、PluginRegistrar::RegisterRenderer の呼び出しで指定されている名前です。この名前に含まれるスペースはアンダースコアに置き換えられます。


パラメータ

パラメータ Language タイプ 詳細
in_context C++ CRef& RendererContext オブジェクトへのリファレンス。 Context::GetSourceRenderer を返します。

コンテキスト属性

Attribute タイプ 詳細
RenderID unsigned int この特定のレンダリング ジョブの一意の識別子。 Softimage は、レンダリングされた出力が必要なときには常にレンダリング ジョブを作成します。 したがって、シングル パス レンダは 1 つのレンダリング ジョブ、シェーダボール イメージはそれぞれが 1 つのレンダリング ジョブ、各レンダー領域は個別のレンダリング ジョブになります。
Process siRenderProcessType Render Manager が要求するプロセス タイプ。
RenderType CString 実行されているレンダリングの現在のタイプ。 たとえば、PassRegionShaderball などです。
Scene Model オブジェクトの CRefArray レンダリングするシーンを構成するモデルのリスト。 現在のシーンをレンダリングする場合は、単にシーン ルート モデルです。 シェーダボールをレンダリングする場合は、ヒーロー オブジェクト(りんごなど)と背景オブジェクト(チェッカーボードの模様など)を組み合わせたものになります。
ObjectList X3DObjectCRefArray (省略可) Scene 属性で指定されているシーン ルートからレンダリングするオブジェクトのサブセット。 これらのオブジェクトは、SelectionOnly のみの属性を含め、現在選択されているすべてのオブジェクトをオーバーライドします。 また、TrackSelection 属性も、現在の選択ではなく、このリストで指定されているオブジェクトを含むように動作を変更します。
DirtyList X3DObjectCRefArray 定義されている場合、このレンダリング エンジンが最後に呼び出されたとき以降に変更されたオブジェクトをリスト表示します。 リストが空である場合は、何も変更されておらず、ユーザがレンダの更新を要求したばかりである可能性があります。 この属性が定義されていない場合は、シーン全体がダーティであると見なすことができます。 ダーティ リストから項目を選択的に削除して次回のレンダリングで表示されないようにするには、RendererContext::SetObjectClean を使用します。
Lights Light オブジェクトの CRefArray シーン ライトのリスト。 このリストは利便性の向上を目的としており、レンダラはシーン モデルを調べてすべてのライトを取得したり、その表示状態を確認したりする必要がありません。
Camera Primitive このレンダの表示カメラ Primitive。 カメラのキネマティクス状態やその他のプロパティにアクセスするために、ProjectItem::GetParent3DObject を使用して、オーナーの X3DObject を取得します。
Material Material または Shader オブジェクトのマテリアルに何も接続されていない場合に使用するマテリアルまたはシェーダ。 これは、シェーダボールのプレビューでのみ使用します。
警告: この属性は、領域およびパス レンダリングでは使用できません。
ImageWidth unsigned int イメージ出力の幅(ピクセル)。
ImageHeight unsigned int イメージ出力の高さ(ピクセル)。
CropLeft unsigned int 矩形切り抜きの左側のオフセット。
CropBottom unsigned int 矩形切り抜きの下側のオフセット。
CropWidth unsigned int 矩形切り抜きの幅。
CropHeight unsigned int 矩形切り抜きの高さ。
SelectionOnly bool 選択されているオブジェクトのみをレンダします。
TrackSelection bool 選択されているオブジェクトに合うように、自動的にクロップ ウィンドウを調整します(画面空間内で)。 この場合、指定されているクロップ値は無視する必要があります。
MotionBlur bool モーション ブラーが有効になっています。
ShutterSpeed double シャッターが開いている時間(フレーム)。
ShutterOffset double シャッターのオフセット(フレーム)。
ShutterType siRenderShutterType 3 つのシャッター タイプ(センター、フレームで終了、フレームで開始)。
MotionBlurDeformation bool モーション ブラーは、変換だけではなくデフォーメーションに影響します。
FileOutput bool イメージはディスクに書き込まれる必要があります。ディスクに書き込まれない場合、フラグメントのみが送信されます。
SkipExistingFiles bool 既存のファイルが既にレンダリングされているとみなされた場合、これらをスキップします。 2 台のマシンでお互いのファイルを上書きしないようにするには、ロックしなければなりません。
FieldRender bool フィールド レンダリングが有効になっています。
FieldInterleave siRenderFieldType フィールド インターリーブのタイプ(なし、偶数/NTSC、奇数/PAL)。
ArchiveFileName CString 使用する現在のフレームのアーカイブ ファイル名。 複数フレームのアーカイブの場合、この名前はシーケンス内のすべてのフレームで同じファイル名になります。
この属性と次の属性は、プロセス タイプが siRenderProcessExportArchive または siRenderProcessExportObjectArchive である場合のみ設定されます。
ArchiveMultiFrame bool すべてのフレームを 1 つのアーカイブ ファイルに埋め込みます。
ArchiveDisplayProxies bool レンダ エンジンは書き出されたフレームごとに 3 つのイメージを生成します。 これらのイメージはビューポートでオブジェクト アーカイブ コンテンツをカードボード スタイルで表示するために使用されます。 3 つのイメージは、オーソグラフィック カメラ モードで -Z、-Y、および -X 軸をそれぞれ見下ろし、XY、XZ、および YZ 軸の各平面に投影された状態として生成されます。 また、すべてのジオメトリをキャプチャするために、カメラはバウンディング ボックスの外側に配置される必要があります。
この属性は、プロセスタイプが siRenderProcessExportObjectArchive の場合のみ設定されます。
RenderMapList Property オブジェクトの CRefArray RegenerateMaps コマンドによって生成される RenderMap プロパティのリストです。
この属性は、プロセスタイプが siRenderProcessRenderMap の場合のみ設定されます。
RenderMapTileSize unsigned int RegenerateMaps コマンドによって得られるタイル サイズです。
この属性は、プロセスタイプが siRenderProcessRenderMap の場合のみ設定されます。

戻り値

CStatus

Process コールバックは、レンダが成功したか、中止されたか、内部エラーがあったかに応じてステータス コードを返します。

ステータス 詳細
CStatus::OK レンダは正常に完了しました。つまり、要求されたすべてのデータが正常に書き出されたか、Softimageに戻されました。
CStatus::Abort これは、Process コールバックが Abort コールバックの呼び出しに応答している場合のみ返されます。 これ以外の状況では返されることはありません。
CStatus::Fail 致命的ではないエラー状態が検出されました。たとえば、テクスチャが見つからない、イベントから (RendererContext::TriggerEvent 呼び出しから)の中止要求などです。 この場合、パス レンダや書き出しなどの 1 回限りのレンダはキャンセルされます。 継続するレンダ操作(レンダ領域やシェーダボールなど)は、リフレッシュされるまで単に更新を停止します。
(その他のエラーコード) レンダラに破壊的なエラーが発生しました。 この時点で、レンダ ジョブ全体がキャンセルされます。 ジョブが領域によって作成された場合は、その領域が自動的に閉じます。 シェーダボールでエラーが発生した場合は、そのシェーダボールが更新を停止します。

//
// Example rendering engine
//

// There is only ever *one* instance of this plug-in running so global variables
// are "ok".

#include <xsi_application.h>
#include <xsi_camera.h>
#include <xsi_context.h>
#include <xsi_decl.h>
#include <xsi_longarray.h>
#include <xsi_math.h>
#include <xsi_pluginregistrar.h>
#include <xsi_renderer.h>
#include <xsi_renderercontext.h>
#include <xsi_customproperty.h>
#include <xsi_ppglayout.h>
#include <xsi_pass.h>
#include <xsi_project.h>
#include <xsi_scene.h>
#include <xsi_passcontainer.h>
#include <xsi_primitive.h>
#include <xsi_x3dobject.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

using namespace XSI; 

SICALLBACK XSILoadPlugin( PluginRegistrar& in_reg )
{
        in_reg.PutAuthor(L"Softimage");
        in_reg.PutName(L"Color Renderer");
        in_reg.PutEmail(L"support@softimage.com");
        in_reg.PutURL(L"http://www.softimage.com");
        in_reg.PutVersion(1,0);
        in_reg.RegisterProperty( L"Color Renderer Options" );
        in_reg.RegisterRenderer( L"Color Renderer" );

        return CStatus::OK;
}

////////////////////////////////////////////////////////////////////////////////
// Rendering Engine Section

/*! Abort handling.
*/
static bool                             g_bAborted;
HANDLE                                  g_hAbort;
CRITICAL_SECTION                g_barrierAbort;

void setAbort( bool in_bAbort )
{
        ::EnterCriticalSection( &g_barrierAbort );
        g_bAborted = in_bAbort;
        if( in_bAbort )
                ::SetEvent( g_hAbort );
        else
                ::ResetEvent( g_hAbort );
        ::LeaveCriticalSection( &g_barrierAbort );
}

bool isAborted( )
{
        bool            bAbort;
        ::EnterCriticalSection( &g_barrierAbort );
        bAbort= g_bAborted;
        ::LeaveCriticalSection( &g_barrierAbort );

        return( bAbort );
}


/*! Initialization function for the renderer, called when the
        plug-in is loaded.

        This is where the rendering engine tells the environment what 
        process types it can perform (render, export archives etc.), 
        which property to use for its options and which output formats 
        it supports (and how those formats are defined).

        The renderer can perform any other one-time initialization here also.
*/
SICALLBACK ColorRenderer_Init( CRef &in_ctxt )
{
        Context         ctxt( in_ctxt );
        Renderer        renderer = ctxt.GetSource();

        // Tell the render manager what render processes we support.
        CLongArray      process;
        process.Add( siRenderProcessRender );
        renderer.PutProcessTypes( process );

        // Specify the custom property to use for the renderer options
        renderer.AddProperty( siRenderPropertyOptions, L"Color Renderer.Color Renderer Options" );

        // Add the Softimage PIC format as an output format.
        renderer.AddOutputImageFormat( L"Softimage PIC", L"pic" );
        renderer.AddOutputImageFormatSubType( siRenderChannelColorType, L"RGBA", siImageBitDepthInteger8 );

        // And some arbitrary image format.
        renderer.AddOutputImageFormat( L"Foo Format", L"foo" );
        renderer.AddOutputImageFormatSubType( siRenderChannelColorType, L"RGBA", siImageBitDepthInteger8 );
        renderer.AddOutputImageFormatSubType( siRenderChannelColorType, L"RGBA", siImageBitDepthInteger16 );
        renderer.AddOutputImageFormatSubType( siRenderChannelColorType, L"RGB", siImageBitDepthInteger8 );
        renderer.AddOutputImageFormatSubType( siRenderChannelGrayscaleType, L"Gray", siImageBitDepthInteger16 );

        // Create the handles for a thread-safe abort
        g_bAborted = false;
        ::InitializeCriticalSection( &g_barrierAbort );
        g_hAbort = ::CreateEvent( NULL, FALSE, FALSE, NULL );
        
        return( CStatus::OK );
}


/*! This is called when the plug-in is unloaded.
        The rendering engine should shut down completely and clean 
        out any global data. Any rendering jobs using this engine
        have already been terminated at this point.
*/
SICALLBACK ColorRenderer_Term( CRef &in_ctxt )
{
        ::DeleteObject( g_hAbort );
        ::DeleteCriticalSection( &g_barrierAbort );

        g_hAbort = NULL;
        ::ZeroMemory( &g_barrierAbort, sizeof( g_barrierAbort ) );

        return( CStatus::OK );
}

class MyFragment : public RendererImageFragment
{
public:
        MyFragment( 
                unsigned int in_offX, unsigned int in_offY, unsigned int in_width, unsigned int in_height, 
                double in_color[ 4 ] )
        {
                offX = in_offX;
                offY = in_offY;
                width = in_width;
                height = in_height;

                unsigned int            r, g, b, a;

                r = (unsigned int)( in_color[ 0 ] * 255.0 );
                g = (unsigned int)( in_color[ 1 ] * 255.0 );
                b = (unsigned int)( in_color[ 2 ] * 255.0 );
                a = (unsigned int)( in_color[ 3 ] * 255.0 );

                color = ( a << 24 ) | ( b << 16 ) | ( g << 8 ) | ( r );
        }

        unsigned int GetOffsetX( ) const { return( offX ); }
        unsigned int GetOffsetY( ) const { return( offY ); }
        unsigned int GetWidth( ) const { return( width ); }
        unsigned int GetHeight( ) const { return( height ); }
        bool GetScanlineRGBA( unsigned int in_uiRow, siImageBitDepth in_eBitDepth, unsigned char *out_pScanline ) const
        {
                unsigned int            *pScanline = (unsigned int *)out_pScanline;
                for( unsigned int i = 0; i < width; i++ )
                        pScanline[ i ] = color;

                return( true );
        }

private:
        unsigned int    offX, offY, width, height;
        unsigned int    color;
};

/*! This is the main function that gets called by the render manager
        whenever the rendering engine is requested to perform a process
        (render a frame, export an archive, etc.).

        It is called with a specialized Context object, called RendererContext.
        The RendererContext allows to retrieving the renderer options property,
        getting framebuffer information and sending tile data back to the render 
        manager.
*/
SICALLBACK ColorRenderer_Process( CRef &in_ctxt )
{
        setAbort( false );

        RendererContext ctxt( in_ctxt );
        Renderer                renderer = ctxt.GetSource();

        // The LockSceneData method *must* be called before accessing any potential
        // scene data. This is to ensure that multiple threads do not concurrently access
        // and/or modify the scene data. It is also important that the renderer does *not*
        // modify any scene data at all. It can modify its own private data but nothing
        // that is a part of the scene or the current application state, unless explicitly
        // allowed.
        if( renderer.LockSceneData() != CStatus::OK )
                return( CStatus::Abort );

        Primitive                       camera_prim = ctxt.GetAttribute( L"Camera" );
        X3DObject                       camera_obj      = camera_prim.GetOwners( )[ 0 ];
        Camera                          camera          = camera_obj;
        CString                         camera_name     = camera_obj.GetName();
        const wchar_t           *wcsCameraName = camera_name.GetWideString();

        // Get the size of the image to render (in pixels). The origin is defiend as the
        // bottom-left corner of the image.
        unsigned int            width, height;
        width = (ULONG)ctxt.GetAttribute( L"ImageWidth" );
        height = (ULONG)ctxt.GetAttribute( L"ImageHeight" );

        // Check if there is a crop area defined. If the offset is 0,0 and the crop 
        // width/height is the same as the image width/height, then no cropping should take
        // place. The crop window is always fully inside of the rendered image.
        unsigned int            cropOffsetX, cropOffsetY;
        unsigned int            cropWidth, cropHeight;

        cropOffsetX = (ULONG)ctxt.GetAttribute( L"CropLeft" );
        cropOffsetY = (ULONG)ctxt.GetAttribute( L"CropBottom" );
        cropWidth = (ULONG)ctxt.GetAttribute( L"CropWidth" );
        cropHeight = (ULONG)ctxt.GetAttribute( L"CropHeight" );

        // Get our render property evaluated at the correct time. If rendering fields, any 
        // parameter that is animated, needs to be evaluated at the half-frame in between the
        // current frame and the next frame after. Same goes potentially for motion blur, unless
        // the renderer is incapable of interpolating the data, in which case it should use
        // the current frame as a base.
        CTime           evalTime = ctxt.GetTime();

        Property        myProp = ctxt.GetRendererProperty( evalTime );

        double                  color[ 4 ];
        
        color[ 0 ] = myProp.GetParameterValue( L"Color_R", evalTime );
        color[ 1 ] = myProp.GetParameterValue( L"Color_G", evalTime );
        color[ 2 ] = myProp.GetParameterValue( L"Color_B", evalTime );
        color[ 3 ] = myProp.GetParameterValue( L"Color_A", evalTime );

        // Unlock the scene data *before* we start rendering and sending tile data back.
        renderer.UnlockSceneData();
        
        // Check after the scene data has been evaluted whether the abort flag is set.
        if( isAborted() )
                return( CStatus::Abort );

        // Notify the renderer manager that a new frame is about to begin. This is necessary so
        // that any recipient tile sink can re-adjust its own size to accommodate.
        ctxt.NewFrame( width, height );

        unsigned int     tileSize = 32;

        for( unsigned y = 0; y <= ( cropHeight / tileSize ); y++ )
        {
                for( unsigned x = 0; x <= ( cropWidth / tileSize ); x++ )
                {
                        unsigned int            ox, oy, sx, sy;

                        ox = x * tileSize;
                        oy = y * tileSize;
                        sx = tileSize;
                        sy = tileSize;

                        if( ( ox + tileSize ) > cropWidth )
                                sx = width - ox;
                        else
                                sx = tileSize;

                        if( ( oy + tileSize ) > cropHeight )
                                sy = height - oy;
                        else
                                sy = tileSize;

                        MyFragment              fragment( 
                                ox + cropOffsetX, oy + cropOffsetY, sx, sy, color );

                        // Send back a new tile.
                        ctxt.NewFragment( fragment );

                        DWORD           dwResult = ::WaitForSingleObject( g_hAbort, 40 );
                        if( dwResult != WAIT_TIMEOUT )
                                return( CStatus::Abort );
                }
        }

        return( CStatus::OK );
}

/*! Called by the render manager when the renderer should do a full 
        cleanup of any data that got created by the Process function. 
        This is usually called when the current scene is being destroyed,
        or if the specific render process (region, pass render, export)
        requests that data be cleaned up after the process has completed.
*/
SICALLBACK ColorRenderer_Cleanup( CRef &in_ctxt )
{
        Context         ctxt( in_ctxt );
        Renderer        renderer = ctxt.GetSource();
        
        return( CStatus::OK );
}


/*! Called when the render needs to be aborted. The function should
        trigger an abort and return as quickly as possible. It should
        *not* refer to any scene data and not perform any processing
        besides triggering the abort. It is up to the Process function
        to ensure a clean abort is done upon the receipt of an abort
        signal.
*/
SICALLBACK ColorRenderer_Abort( CRef &in_ctxt )
{
        Context         ctxt( in_ctxt );
        Renderer        renderer = ctxt.GetSource();

        setAbort( true );

        return( CStatus::OK );
}


/*! This function serves two purposes: To return the current "quality"
        level of the render options and to set a preset for the given
        "quality" level. The calculated quality level should be simply
        the value that corresponds to the closest match to a level
        preset.
        \note This mechanism might be aborted shortly and replaced by
                something else that gets handled by Softimage directly.
*/
SICALLBACK ColorRenderer_Quality( CRef &in_ctxt )
{
        Context         ctxt( in_ctxt );
        Renderer        renderer = ctxt.GetSource();

        CValue          quality = ctxt.GetAttribute( L"Quality" );
        Property        prop = ctxt.GetAttribute( L"Property" );

        static const double levels[ 5 ][ 4 ] = {
                { 1.0, 0.0, 0.0, 1.0 },
                { 0.0, 1.0, 0.0, 1.0 },
                { 1.0, 0.0, 1.0, 1.0 },
                { 1.0, 0.5, 0.5, 1.0 },
                { 0.7, 0.4, 0.3, 0.5 },
        };

        if( quality.IsEmpty() )
        {
                double  color[ 4 ];
                int             closest = -1;
                double  maxclose = DBL_MAX;

                color[ 0 ] = prop.GetParameterValue( L"Color_R", CTime() );
                color[ 1 ] = prop.GetParameterValue( L"Color_G", CTime() );
                color[ 2 ] = prop.GetParameterValue( L"Color_B", CTime() );
                color[ 3 ] = prop.GetParameterValue( L"Color_A", CTime() );

                // We're being asked for the quality value (0-4).
                // Find the closest color match.
                for( int i = 0; i < 5; i++ )
                {
                        double          close;
                        double          dist = 0.0;

                        for( int j = 0; j < 4; j++ )
                        {
                                dist += ( color[ j ] - levels[ i ][ j ] ) * ( color[ j ] - levels[ i ][ j ] );
                        }
                        close = sqrt( dist );
                        if( close < maxclose )
                        {
                                maxclose = close;
                                closest = i;
                        }
                }

                ctxt.PutAttribute( L"Quality", closest );
        }
        else
        {
                // Set a quality value based on the five levels (0-4).
                prop.PutParameterValue( L"Color_R", levels[ (ULONG)quality ][ 0 ] );
                prop.PutParameterValue( L"Color_G", levels[ (ULONG)quality ][ 1 ] );
                prop.PutParameterValue( L"Color_B", levels[ (ULONG)quality ][ 2 ] );
                prop.PutParameterValue( L"Color_A", levels[ (ULONG)quality ][ 3 ] );
        }

        return( CStatus::OK );
}


////////////////////////////////////////////////////////////////////////////////
// Renderer Options Property

SICALLBACK ColorRendererOptions_Define( CRef& in_ctxt )
{
        Context ctxt( in_ctxt );
        CustomProperty oCustomProperty;
        Parameter oParam;
        oCustomProperty = ctxt.GetSource();
        oCustomProperty.AddParameter(L"Color_R",CValue::siDouble,siPersistable,L"",L"",0l,0l,1l,0l,1l,oParam);
        oCustomProperty.AddParameter(L"Color_G",CValue::siDouble,siPersistable,L"",L"",0l,0l,1l,0l,1l,oParam);
        oCustomProperty.AddParameter(L"Color_B",CValue::siDouble,siPersistable,L"",L"",0l,0l,1l,0l,1l,oParam);
        oCustomProperty.AddParameter(L"Color_A",CValue::siDouble,siPersistable,L"",L"",0l,0l,1l,0l,1l,oParam);
        return CStatus::OK;
}

SICALLBACK ColorRendererOptions_DefineLayout( CRef& in_ctxt )
{
        Context ctxt( in_ctxt );
        PPGLayout oLayout;
        PPGItem oItem;
        oLayout = ctxt.GetSource();
        oLayout.Clear();
        oLayout.AddColor(L"Color_R",L"Color",true);
        return CStatus::OK;
}

関連項目