1

私は OpenGL を使用してレンダラーに取り組んでいます。

私は最初のクラス、ジオメトリを持っています:

class Geometry
{
 public:

    void setIndices( const unsigned int* indices, int indicesCount );

 private:
    std::vector<unsigned char> colors;
    std::vector<float>         positions;
    std::vector<unsigned int>  indices;
};

時々、私のジオメトリは、異なるタイプの彼のインデックスをストックする必要があります。データは次のようになります:

1. std::vector<unsigned char> 
2. std::vector<short> 
3. std::vector<int>

// I've already think about std::vector<void>, but it sound dirty :/.

現在、どこでもunsigned intを使用しており、ジオメトリに設定したいときにデータをキャストしています。

const char* indices = { 0, 1, 2, 3 };
geometry.setIndices( (const unsigned int*) indices, 4 );

後で、実行時にこの配列を更新または読み取りたい (配列には 60000 を超えるインデックスを格納できる場合がある) ため、次のようにします。

std::vector<unsigned int>* indices = geometry.getIndices();
indices->resize(newIndicesCount);

std::vector<unsigned int>::iterator it = indices->begin();

問題は、イテレータがunsigned int配列でループするため、イテレータが 4 バイトから 4 バイトに移動し、初期データが char (1 バイトから 1 バイト) になる可能性があることです。初期データを読み取ったり、新しいデータで更新したりすることはできません。

ベクトルを更新したい場合、唯一の解決策は、新しい配列を作成し、データを入力してから、符号なし int 配列にキャストすることです。インデックス ポインターを反復処理したいと思います。

  1. どうすれば一般的なことを行うことができますか (unsigned int、char、および short を操作する)?
  2. コピーせずに配列を反復処理するにはどうすればよいですか?

御時間ありがとうございます!

4

1 に答える 1

2

間違ったポインター型にキャストすると、未定義の動作が発生し、ここのように型のサイズが間違っていると確実に失敗します。

どうすれば一般的なことを行うことができますか (unsigned int、char、および short を操作する)?

テンプレートは、それを汎用にする最も簡単な方法です。

template <typename InputIterator>
void setIndices(InputIterator begin, InputIterator end) {
    indices.assign(begin, end);
}

使用法 (ポインターではなく配列を使用するように例を修正します):

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(std::begin(indices), std::end(indices));

コンテナー、配列、およびその他の範囲型を直接受け取る便利なオーバーロードを検討することもできます。

template <typename Range>
void setIndices(Range const & range) {
    setIndices(std::begin(range), std::end(range));
}

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(indices);

コピーせずに配列を反復処理するにはどうすればよいですか?

データをコピーせずに配列の型を変更することはできません。コピーを避けるには、正しい配列型を期待する必要があります。

于 2013-10-08T15:21:32.260 に答える