頂点ジオメトリビルダー
説明
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 )

// 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());
ワイヤーフレーム キューブの結果
下の画像は、結果のワイヤフレーム キューブを示しています。

-
SceneComposer でウィジェットを簡単に操作するために、すべてのシェーダーがソース ファイルにハードコードされ ( cgi_studio_player\src\LegacyWidgets\Tutorial\3D\VertexGeometryBuilderWidget.cpp を参照)、初期化時にウィジェットによって作成されます。
または、アプリケーションがアセット ライブラリを使用する場合は、Candera::AssetProvider (例: GetAssetProvider()->GetShader("..."))からシェーダーを取得します。
インデックス付きジオメトリ インデックス付きジオメトリ
例: 1 つの三角形ストリップからのソリッド キューブ
次の例では、 Candera::Meshオブジェクトを使用して、1 つの三角形ストリップからソリッド キューブを作成する方法を示します。この場合、立方体は、特別な方法で順序付けする必要がある 14 個の頂点のみによって決定されます。
次の図は、展開された立方体と、頂点の順序付けの考えられる解決策を示しています。

インデックス付き頂点シーケンス
頂点シーケンスは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());
ソリッド キューブの結果
以下の画像は、結果として得られる立体立方体を示しています。

頂点要素の削除と追加 頂点要素の削除と追加
例: テクスチャ キューブ
この例では、頂点ジオメトリ ビルダ オブジェクトを使用して、テクスチャ付き立方体の頂点ジオメトリを生成します。
メッシュにテクスチャを追加するには、その頂点に法線やテクスチャ座標などの特定の情報が含まれている必要があります。また、色情報は不要になったため、削除できます。
// 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();
}
立方体の各面の頂点は、以下に示すようにテクスチャ座標情報で設定する必要があります。

頂点のテクスチャ座標を設定します。
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++;
}
}
}
頂点バッファーは、前の例と同じ方法で作成および構成されます。
メッシュのセットアップも似ていますが、ソリッド キューブとは異なり、テクスチャ キューブの外観はテクスチャとテクスチャ シェーダで設定する必要があります。
テクスチャ キューブの結果
最終結果は次のとおりです。

範囲データの使用法 範囲データの使用法
例: 範囲データを使用したソリッド キューブ
この例では、 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 番目の例のものと同じです。
最終結果は次のとおりです。

ジオメトリの連結 ジオメトリの連結
VertexGeometryBuilder::SpliceGeometry
場合によっては、2 つの頂点ジオメトリを連結すると便利な場合があります。これは、以下に示すように、Candera::VertexGeometryBuilder::SpliceGeometryメソッドを使用して実行できます。
m_builder.SpliceGeometry(0, 0, vertexGeometry1);
m_builder.SpliceGeometry(vertexGeometry1->GetVertexCount(), vertexGeometry1->GetIndexCount(), vertexGeometry2);
vertexGeometry1cat2 = builder.GetGeometry();