描画とリフレッシュ

描画は、2 つの手順によるプロセスです。第 1 のプロセスでは、ジオメトリとマテリアルが評価され、描画に必要なすべての情報がキューに配置されます。第 2 のプロセスでは、実際の OpenGL 描画が発生します。この 2 つの手順によるプロセスで、シェイプに対して Maya のマルチスレッド描画機能を活用することができます。

描画は、カメラが変更されるたび、またはビューをリフレッシュする必要が生じるたびに実行されます。これが実行されると、MPxSurfaceShapeUI::getDrawRequest 関数がコールされます。これが、描画する内容を Maya がシェイプに尋ねる方法です。この関数の内部で、MDrawInfo を使用して描画の状態が調べられ、描画要求(MDrawRequest)を構築して待ち行列に配置します。多くの場合は、この関数内で複数の要求を待ち行列(MDrawRequestQueue)に配置します。たとえばシェーディング モードでは、シェイプが選択された場合、シェーディング オブジェクトを描画する要求を追加し、シェーディング オブジェクトの上にワイヤフレームを描画する、別の要求を追加します。

描画データ(MDrawData)には、Maya では本質的に識別できないシェイプに特定した情報が保持されます。描画データは、描画要求待ち行列を通してジオメトリを渡すコンテナとして働きます。それぞれの描画要求では、ジオメトリ固有の情報を含む描画データ オブジェクトを作成して追加する必要があります。この情報は、後で MPxSurfaceShapeUI::draw をコールする場合に必要となります。

描画データを作成するには関数 MPxSurfaceShapeUI::getDrawData を使用し、データを要求に追加するには MDrawRequest::setDrawData を使用します。以下は、ジオメトリの描画要求と描画データを作成する方法の例です。

void yourShapeUI::getDrawRequests( const MDrawInfo & info,
 bool objectAndActiveOnly,
 MDrawRequestQueue & queue )
{
    MDrawData data;
    MDrawRequest request = info.getPrototype( *this );
    yourShape* shapeNode = (yourShape*)surfaceShape();
    yourGeom* geom = shapeNode->geometry();
    getDrawData( geom, data );
    request.setDrawData( data );
    ...
}

描画要求(MDrawRequest)は、オーバーライドした MPxSurfaceShapeUI::getDrawRequests メソッド内で作成する必要があります。要求を作成したら、このクラスの適切な「設定」メソッドを使用して、要求するものを定義します。次に MDrawRequestQueue::add を使用し、要求を描画要求待ち行列に配置します。

描画トークンは整数値で、これを使用すると、描画するものを指定できます。これはオブジェクトに固有なので、必要な情報で enum を定義し、MPxSurfaceShapeUI::draw メソッドで描画するものを決める必要があります。以下は、メッシュ オブジェクトの描画トークンの例です。

 enum {
          kDrawVertices, // component token
          kDrawWireframe,
          kDrawWireframeOnShaded,
          kDrawSmoothShaded,
          kDrawFlatShaded,
          kLastToken
      };

Maya は描画要求待ち行列を処理し、描画要求ごとに、対応するオブジェクト描画関数をコールします。ユーザ定義シェイプの場合は、MPxSurfaceShapeUI::draw メソッドがコールされます。

シェーディング モードで描画する

シェーディング モード表示のサポートは、2 つの手順で処理されます。最初の手順は getDrawRequests 関数で行います。ここではマテリアルの「評価」つまりセットアップを行い、オブジェクトを描画する場合にマテリアルを表示できるようにします。次の手順は描画関数内で実行されます。ここでは、ビューをセットアップしてマテリアルを表示する必要があります。

以下のコードは、要求がシェーディング モード表示である場合に getDrawRequests 関数でマテリアルをセットアップする方法の例です。

 MDagPath path = info.multiPath();
 M3dView view = info.view();
 MMaterial material = MPxSurfaceShapeUI::material( path );
 material.evaluateMaterial( view, path );
 if ( material.materialIsTextured() ) {
     material.evaluateTexture( data );
 }
 request.setMaterial( material );

描画関数ではシーン ビューをセットアップし、マテリアルを表示できるようにする必要があります。これは MMaterial::setMaterial を使用して実行します。シーン ビューをセットアップしてテクスチャを表示するには、MMaterial::applyTexture を使用します。以下のコードはこの例です。

void yourShapeUI::draw( const MDrawRequest& request,
 M3dView & view ) const
{
     ...
     MMaterial material = request.material();
     material.setMaterial( request.isTransparent() );
     drawTexture = material.materialIsTextured();
     if ( drawTexture ) glEnable(GL_TEXTURE_2D);
     if ( drawTexture ) {
         material.applyTexture( view, data );
     }
     ...
}
注:

すべての OpenGLは、M3dView::beginGL()M3dView::endGL() のコールの間にコールする必要があります。