2016-05-02 3 views
0

ちょっと、私はstd :: vectorに問題があり、あなたの助けが必要です。 現在、新しいvulkan apiを使用してレンダリングエンジンをプログラミングしています。異なるメッシュの異なる頂点レイアウトをサポートしたいと考えています。 問題は、std :: vector :: data()が必要な生データを返さないということです。ここに私の頂点の構造体です:C++ std :: vectorサブクラスから生データを取得しない

struct Vertex 
{ 
}; 
struct VertexColor : public Vertex 
{ 
public: 
    VertexColor(Vec3f pos, Vec3f col) : position(pos), color(col) {} 
    Vec3f position; 
    Vec3f color; 
}; 

これは私が実際に持っているとどのような作品です:

 std::vector<VertexColor> cubeVertexBuffer = { 
     VertexColor{ Vec3f(-1.0f, -1.0f, 1.0f), Vec3f(0.0f, 0.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, -1.0f, 1.0f ), Vec3f(1.0f, 0.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, 1.0f, 1.0f ), Vec3f(1.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, 1.0f, 1.0f ), Vec3f(0.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, -1.0f, -1.0f), Vec3f(0.0f, 0.0f, 1.0f) }, 
     VertexColor{ Vec3f(1.0f, -1.0f, -1.0f), Vec3f(0.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, 1.0f, -1.0f ), Vec3f(1.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, 1.0f, -1.0f), Vec3f(1.0f, 0.0f, 0.0f) } 
}; 

uint32_t size = 8 * sizeof(VertexColor); 
Vertex* vertices = (Vertex*)malloc(size); 
memcpy(vertices, cubeVertexBuffer.data(), size); 

std::vector<uint32_t> cubeIndexBuffer = { 1,2,0, 2,3,0, 
              0,3,4, 3,7,4, 
              5,1,4, 1,0,4, 
              2,6,3, 6,7,3, 
              5,6,1, 6,2,1, 
              6,5,7, 5,4,7 }; 

Cube::cubeMesh = new Mesh(vertices, size, cubeIndexBuffer); 

私が欲しいもの:

std::vector<Vertex> cubeVertexBuffer = { 
     VertexColor{ Vec3f(-1.0f, -1.0f, 1.0f), Vec3f(0.0f, 0.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, -1.0f, 1.0f ), Vec3f(1.0f, 0.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, 1.0f, 1.0f ), Vec3f(1.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, 1.0f, 1.0f ), Vec3f(0.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, -1.0f, -1.0f), Vec3f(0.0f, 0.0f, 1.0f) }, 
     VertexColor{ Vec3f(1.0f, -1.0f, -1.0f), Vec3f(0.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(1.0f, 1.0f, -1.0f ), Vec3f(1.0f, 1.0f, 0.0f) }, 
     VertexColor{ Vec3f(-1.0f, 1.0f, -1.0f), Vec3f(1.0f, 0.0f, 0.0f) } 
}; 

std::vector<uint32_t> cubeIndexBuffer = { 1,2,0, 2,3,0, 
              0,3,4, 3,7,4, 
              5,1,4, 1,0,4, 
              2,6,3, 6,7,3, 
              5,6,1, 6,2,1, 
              6,5,7, 5,4,7 }; 

Cube::cubeMesh = new Mesh(cubeVertexBuffer, cubeIndexBuffer); 

私は、全体の頂点データを必要と言及したようにgpuへのマッピングのためのメモリ内の連続したフォーマットではありませんが、std :: vectorを使った.data()関数は "実データ"を返しません。私はどのようにstd :: vectorで継承を使って "サブクラスからの生データ"を得ることができるのかわかりません。 あなたは私を助けることを願っています! ありがとう

EDIT:メモリをチェックして、VertexColor(..)データを置くstd :: vectorのメモリにデータを設定しませんでした。それは "Vertex"構造体にメンバーがないためですか?

+0

メッシュには2つのベクトルを取るコンストラクタがありますか? –

+0

はい、もちろんです。これは私が望むコンストラクタです:Mesh(const std :: vector &vertices、const std :: vector &indices);最初のバージョン(memcpy)では、最初のstd :: vectorの代わりにポインタを持つ別のコンストラクタとバイト単位のサイズを持っています。 –

+0

メッシュコンストラクタを表示してください。プロトタイプ、少なくとも。 – kfsone

答えて

0

まず、std :: vectorから継承しないでください。それはお勧めではないし、おそらく悪い習慣です。

Vec3fもご覧ください。仮想メソッドやデストラクタはありますか?あなたは、あなたが定義したメンバーだけでなく、クラス内にもっと多くのデータを置いているかもしれません。使用する構造体は、ポリモーフィックなプロパティを持たない普通の古いC++オブジェクト(つまり、プレーンなCスタイルの構造体)である必要があります。

また、メンバーのバイト境界を確認してください。構造体からすべてのパディングを削除するには、次のようにします。

#pragma pack(push) 
    #pragma pack(1) 
    struct ... 
    { 
     ... 
    } 
    #pragma pack(pop) 

これが起こったら教えてください。

さらに、個々の要素のサイズが異なるため、vector<Vertex>vector<VertexColor>は比較できません。私の経験では、3D APIはデータを非常に特定のフォーマットで取得する予定であり、APIがまだあなたのフォーマットを提供していない場合は一般的にはできません。

Jensが示唆しているようにスライスすることもできます。

+0

お返事ありがとうございました。私はstd :: vectorから継承しません。私が実際に意味することは、のベクトルを持っていますが、それには(Vertexを継承しています)を与えます。だから、今私はその設定とベクトルに.data()を使用しようとすると、私はうんざりを取得し、私はなぜか分からない。 Vec3fには仮想メソッドはありません。それ以外に、私が(頂点の代わりに)を使ってstd :: vectorを使用すると、すべて正常に動作しますが、一般的にしたいです。 –

+0

私の答えが更新されました。また、Jensは良い点を持っています。 –

+0

@SilvanHauジェネリックにしたいのであれば、これは通常テンプレートを意味します。 VertexのメンバーだけをコピーするVertexオブジェクトにVertexColorオブジェクトを割り当てます。 – Jens

0

あなたが経験していることをスライシングといいます。 vector<Vertex>を宣言すると、Vertexのインスタンスが保持されます。各「セル」は、頂点のデータに十分な大きさになります。 VertexはVertexColorの基本クラスであるため、VertexColorオブジェクトをVertexに割り当てることはできますが、これはVertexからのデータメンバーのみをコピーします。頂点にはメンバーがいないので、vector<Vertex>の内容は何でしょうか?

この場合、継承は設計方法が間違っています。私が見るところでは、Meshはテンプレートクラスtemplate<typename V> class Mesh<V>で、異なる頂点タイプをサポートする必要があります。標準レイアウトタイプ(enable_if<is_standard_layout<V>::value, V, V>::type)に制限されています。

+0

説明をありがとう、私はちょっとこれを考えた。私はテンプレートを使ってみるつもりです:) –

+0

まあ、私は私の必要性に合うテンプレートなしで別の解決策を見つけました。私は現在、私のエンジンのすべての頂点フォーマットでstd :: vector <>を受け入れる中間の "VertexBuffer"オブジェクトを使用しています。これをメッシュクラスのコンストラクタで使用すると、異なるstd :: vectorsを渡すことができます。欠点:新しい頂点レイアウトを作成する場合、「VertexBuffer」クラスを修正する必要がありますが、これは大きな問題ではありません –