Skip to main content

頂点ジオメトリビルダー

説明

Candera ::VertexGeometryBuilderクラスは、Candera::VertexGeometryオブジェクトを効果的に構築するのに役立ちます。

ソリューション例

  • cgi_studio_player/content/Tutorials/03_SceneGraphAndNodesフォルダー内のVertexGeometryBuilderSolution
  • 基本的な頂点ジオメトリ ビルダー操作は、ウィジェットVertexGeometryBuilderWidgetで例示されています。基本的に、ウィジェットが行うことは、ウィジェット プロパティ「モデル タイプ」に設定された値に応じて、シーン内で連続してレンダリングされる 4 つの 3D モデルの頂点バッファーを生成することです。


手続き型ジオメトリ  

例: LineList を使用したワイヤーフレーム キューブ

最初の例は、 Candera::LineListオブジェクトを使用してワイヤーフレーム キューブを生成する方法を示しています

頂点ジオメトリは、 Candera::VertexGeometryBuilderオブジェクト (例: m_builder )を使用して手続き的に生成されます。

頂点要素の形式: 位置と色

最初に、頂点にどのような情報を設定するかを指定する必要があります。もちろん、位置に関する情報が必要です。オプションで、視覚効果を向上させるために色情報を追加することもできます。

    // Set the data type to be used: position & color
    m_builder.SetVertexElementFormat(VertexGeometry::Position, 0, VertexGeometry::Float32_3);
    m_builder.SetVertexElementFormat(VertexGeometry::Color, 0, VertexGeometry::Float32_4);
頂点データ: 位置

頂点の位置情報は配列c_cubeDataから取得されます。この配列には、実際には点 A と G の座標が格納されています。残りの頂点の座標は、この点に対して相対的に取得されます (たとえば、F(X A , Y G , Z G ) または D(X G , Y A , Z A )

drawing-4-1676882299.png


// Coordinates for the points A & G
static const Float c_cubeData[2][3] = {
    {-1.0F, -1.0F, -1.0F },
    {1.0F, 1.0F, 1.0F }
};
VertexGeometryBuilder: 頂点要素の設定

LineList オブジェクトの LineType プロパティが LineType::Lines に設定されるため、頂点バッファーには立方体の各ラインの頂点のペアが含まれている必要があります: 2 頂点/ライン * 12 ライン = 24 頂点。

    // Set the position & color information for each vertex
    // Line segment AD
    m_builder.SetVertexElement(VertexGeometry::Position, 0, c_cubeData[0][0], c_cubeData[0][1], c_cubeData[0][2]); // A
    m_builder.SetVertexElement(VertexGeometry::Color, 0, 1.F, 0.F, 1.F, 1.F); // magenta
    // Increment the vertex cursor
    m_builder.IncrementVertexCursor();
    m_builder.SetVertexElement(VertexGeometry::Position, 0, c_cubeData[1][0], c_cubeData[0][1], c_cubeData[0][2]); // D
    m_builder.SetVertexElement(VertexGeometry::Color, 0, 1.F, 1.F, 1.F, 1.F); // white
    m_builder.IncrementVertexCursor();
    // Line segment AB
    m_builder.SetVertexElement(VertexGeometry::Position, 0, c_cubeData[0][0], c_cubeData[0][1], c_cubeData[0][2]); // A
    m_builder.SetVertexElement(VertexGeometry::Color, 0, 1.F, 0.F, 1.F, 1.F); // magenta
    m_builder.IncrementVertexCursor();
    m_builder.SetVertexElement(VertexGeometry::Position, 0, c_cubeData[0][0], c_cubeData[0][1], c_cubeData[1][2]); // B
    m_builder.SetVertexElement(VertexGeometry::Color, 0, 1.F, 1.F, 0.F, 1.F); // yellow
    // ...
頂点バッファを作成

Candera::VertexBufferオブジェクトを作成し、 Candera::VertexGeometryBuilderから取得した頂点ジオメトリをアタッチします

    VertexGeometry* vertexGeom = m_builder.GetVertexGeometry();
    SharedPointer<VertexBuffer> vertexBuffer = VertexBuffer::Create();
    static_cast<void>(vertexBuffer->SetVertexGeometry(vertexGeom, VertexBuffer::VertexGeometryDisposer::Dispose));
    vertexBuffer->SetPrimitiveType(VertexBuffer::Lines);
Vertex Buffer を使用して LineList を作成する

頂点バッファーを LineList オブジェクトにアタッチします。

    // Create and configure the line list object
    m_lineList = LineList::Create();
    m_lineList->SetAppearance(Appearance::Create());
    m_lineList->GetAppearance()->SetMaterial(Material::Create());
    m_lineList->GetAppearance()->GetMaterial()->SetEmissive(Color(1.0F, 1.0F, 0.0F));
    m_lineList->GetAppearance()->SetShader(m_shaderLightMaterial);
    m_lineList->SetLineType(LineList::Lines);
    m_lineList->SetWidth(1.0);
    m_lineList->SetIntersectionTestEnabled(false);
    m_lineList->SetVertexBuffer(vertexBuffer);
    m_lineList->SetScopeMask(ScopeMask(false));
    static_cast<void>(m_lineList->SetScopeEnabled(1, true));
    m_lineList->SetRenderingEnabled(true);
    m_lineList->SetName("Wireframe");
    static_cast<void>(m_lineList->Upload());
ワイヤーフレーム キューブの結果

下の画像は、結果のワイヤフレーム キューブを示しています。

drawing-4-1676882342.png

SceneComposer でウィジェットを簡単に操作するために、すべてのシェーダーがソース ファイルにハードコードされ ( cgi_studio_player\src\LegacyWidgets\Tutorial\3D\VertexGeometryBuilderWidget.cpp を参照)、初期化時にウィジェットによって作成されます。

または、アプリケーションがアセット ライブラリを使用する場合は、Candera::AssetProvider (例: GetAssetProvider()->GetShader("..."))からシェーダーを取得します。

メニューに戻る


インデックス付きジオメトリ インデックス付きジオメトリ 

例: 1 つの三角形ストリップからのソリッド キューブ

次の例では、 Candera::Meshオブジェクトを使用して、1 つの三角形ストリップからソリッド キューブを作成する方法を示しますこの場合、立方体は、特別な方法で順序付けする必要がある 14 個の頂点のみによって決定されます。

次の図は、展開された立方体と、頂点の順序付けの考えられる解決策を示しています。

drawing-4-1676882414.png

インデックス付き頂点シーケンス

頂点シーケンスはc_index_order配列に格納され、順序がエンコードされます。

  • G->C->F->B->A->C->D->H->A->E->F->H->G->C .

各配列要素は、頂点バッファー内のオフセットを表します。

// The vertex sequence - triangle strip
static const UInt16 c_index_order[] = { 12, 11, 7, 3, 0, 11, 1, 17, 0, 5, 7, 17, 12, 11 };

前の例で使用された頂点ジオメトリ ビルダー オブジェクトには、位置と色の情報が設定された 24 個の頂点が既に含まれています。この場合、必要な頂点は 24 個のうち 14 個だけであり、それらのシーケンスも異なる必要があるため、インデックス バッファーが追加されます。

    // Change the order of the vertices using indexes
    for (Int index = 0; index < 14; index++) {
        // Define the value of the index
        m_builder.SetIndexElement(c_index_order[index]);
        // Increment the index cursor
        m_builder.IncrementIndexCursor();
    }
TriangleStrip 頂点バッファーの作成

ビルダーからのジオメトリを使用して頂点バッファーを作成します。

    VertexGeometry* vertexGeom = m_builder.GetVertexGeometry();
    SharedPointer<VertexBuffer> vertexBuffer = VertexBuffer::Create();
    static_cast<void>(vertexBuffer->SetVertexGeometry(vertexGeom, VertexBuffer::VertexGeometryDisposer::Dispose));
    vertexBuffer->SetPrimitiveType(VertexBuffer::TriangleStrip);
頂点バッファーを使用してメッシュを作成する

メッシュを構成し、頂点バッファーをアタッチします。

    m_mesh = Mesh::Create();
    m_mesh->SetVertexBuffer(vertexBuffer);
    m_mesh->SetAppearance(appearance);
    m_mesh->SetRenderingEnabled(false);
    m_mesh->SetName("SolidNonTextured");
    static_cast<void>(m_mesh->Upload());
ソリッド キューブの結果

以下の画像は、結果として得られる立体立方体を示しています。

drawing-4-1676882451.png



頂点要素の削除と追加 頂点要素の削除と追加 

例: テクスチャ キューブ

この例では、頂点ジオメトリ ビルダ オブジェクトを使用して、テクスチャ付き立方体の頂点ジオメトリを生成します。

メッシュにテクスチャを追加するには、その頂点に法線テクスチャ座標などの特定の情報が含まれている必要があります。また、情報は不要になったため、削除できます。

    // Vertex Elements Manipulation
    // Remove color data associated to the vertices
    m_builder.RemoveVertexElement(VertexGeometry::Color,0);
    // Add data type to be used: texture coordinate & normal
    m_builder.SetVertexElementFormat(VertexGeometry::TextureCoordinate, 0, VertexGeometry::Float32_2);
    m_builder.SetVertexElementFormat(VertexGeometry::Normal, 0, VertexGeometry::Float32_3);
頂点データ: 法線とテクスチャ座標

頂点の新しいデータ型を追加したら、対応する情報を追加します。まず、頂点の法線を追加します。

    // Move the cursor to the first vertex
    m_builder.SetVertexCursor();
    for (UInt32 i = 0; i < m_builder.GetVertexCount(); i++ )
    {
        m_builder.SetVertexElement(VertexGeometry::Normal, 0, 0.0F, 0.0F, 1.0F);
        m_builder.IncrementVertexCursor();
    }

UV テクスチャ座標値を正しくマッピングするには、面ごとに 4 つの頂点を使用して立方体面を描画する必要があるため、この場合は 24 個の頂点すべてが使用されます。もちろん、頂点の順序を調整する必要があります。

新しい頂点の順序は、c_indexDataTexturedCube配列に格納されます。

// Vertex order - textured cube
static const UInt16 c_indexDataTexturedCube[24] = {
    1,17,0,5,
    2,6,3,7,
    9,8,11,12,
    13,14,19,21,
    15,23,16,22,
    4,10,20,18
};

次に、頂点を並べ替えます。

    // Overwrite the index buffer
    // Move the cursor to the first index
    m_builder.SetIndexCursor();
    for (UInt32 i = 0; i < m_builder.GetVertexCount(); i++ )
    {
        // Define the value of the index
        m_builder.SetIndexElement(c_indexDataTexturedCube[i]);
        m_builder.IncrementIndexCursor();
    }

立方体の各面の頂点は、以下に示すようにテクスチャ座標情報で設定する必要があります。

drawing-4-1676882513.png



頂点のテクスチャ座標を設定します。

    Int idx = 0;
    for (Int nb_of_faces = 0; nb_of_faces<6; nb_of_faces++) {
        for (Int u=0; u<=1; u++) {
            for (Int v=0; v<=1; v++) {
                //Set the position of the vertex cursor
                m_builder.SetVertexCursor(c_indexDataTexturedCube[idx]);
                m_builder.SetVertexElement(VertexGeometry::TextureCoordinate, 0, static_cast<Float>(u), static_cast<Float>(v));
                idx++;
            }
        }
    }

頂点バッファーは、前の例と同じ方法で作成および構成されます

メッシュのセットアップも似ていますが、ソリッド キューブとは異なり、テクスチャ キューブの外観はテクスチャとテクスチャ シェーダで設定する必要があります。

テクスチャ キューブの結果

最終結果は次のとおりです。

drawing-4-1676882532.png

メニューに戻る



範囲データの使用法 範囲データの使用法 

例: 範囲データを使用したソリッド キューブ

この例では、 2 番目の例と同様にソリッド キューブを作成する方法を示しますが、範囲データを使用します。

最初に、頂点ジオメトリ ビルダーからのすべての既存データが削除されます。

    // Clear all data stored by the builder
    m_builder.Clear();

頂点データは、2 つのバッファーc_positionDataおよびc_colorDataから取得されます。

static const Float c_positionData[8][3] = {
    { -1.0F, 1.0F, 1.0F},
    { 1.0F, 1.0F, 1.0F},
    { -1.0F, -1.0F, 1.0F},
    { 1.0F, -1.0F, 1.0F},
    { -1.0F, 1.0F, -1.0F},
    { 1.0F, 1.0F, -1.0F},
    { -1.0F, -1.0F, -1.0F},
    { 1.0F, -1.0F, -1.0F}
};

static const Float c_colorData[8][4] = {
    { 0.0F, 0.0F, 1.0F, 1.0F},
    { 0.0F, 1.0F, 0.0F, 1.0F},
    { 0.0F, 1.0F, 1.0F, 1.0F},
    { 1.0F, 0.0F, 0.0F, 1.0F},
    { 1.0F, 0.0F, 1.0F, 1.0F},
    { 1.0F, 1.0F, 0.0F, 1.0F},
    { 1.0F, 1.0F, 1.0F, 1.0F},
    { 1.0F, 0.5F, 1.0F, 1.0F}
};

頂点シーケンスは、配列c_indexDataから取得されます。

// Range data index
static const UInt16 c_indexData[] = {3, 2, 1, 0, 4, 2, 6, 3, 7, 1, 5, 4, 7, 6 };

メソッドCandera::VertexGeometryBuilder::SetVertexElementRangeおよびCandera::VertexGeometryBuilder::SetIndexElementRange を使用して、必要な情報を追加します。

    // Add position, color and an index from range data
    // Splice values to the position buffer starting with the first vertex
    static_cast<void>(m_builder.SetVertexElementRange(VertexGeometry::Position, 0, 0, VertexGeometry::Float32_3,
        8, 3*sizeof(Float), c_positionData ));
    // Splice values to the color buffer starting with the first vertex
    static_cast<void>(m_builder.SetVertexElementRange(VertexGeometry::Color, 0, 0, VertexGeometry::Float32_4,
        8, 4*sizeof(Float), c_colorData ));

    // Splice values to the index buffer starting with the first index
    static_cast<void>(m_builder.SetIndexElementRange(0, sizeof(c_indexData)/sizeof(UInt16),c_indexData));

頂点バッファーの構成メッシュのセットアップは、2 番目の例のものと同じです。

最終結果は次のとおりです。

drawing-4-1676882596.png

メニューに戻る


ジオメトリの連結 ジオメトリの連結 

VertexGeometryBuilder::SpliceGeometry

場合によっては、2 つの頂点ジオメトリを連結すると便利な場合があります。これは、以下に示すように、Candera::VertexGeometryBuilder::SpliceGeometryメソッドを使用して実行できます。

    m_builder.SpliceGeometry(0, 0, vertexGeometry1);
    m_builder.SpliceGeometry(vertexGeometry1->GetVertexCount(), vertexGeometry1->GetIndexCount(), vertexGeometry2);
    vertexGeometry1cat2 = builder.GetGeometry();

メニューに戻る