OpenGLのC++でモデルローダーを記述しました。頂点データを格納するために_std::vector
_ sを使用しましたが、これをglBufferData()
に渡したいのですが、データ型が大きく異なります。 _std::vector
_をドキュメント化された_const GLvoid *
_からglBufferData()
に変換する方法があるかどうか知りたい。
_typedef struct
{
float x, y, z;
float nx, ny, nz;
float u, v;
}
Vertex;
vector<Vertex> vertices;
_
_glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
_
次の(予期される)エラーが発生します。
_error: cannot convert ‘std::vector<Vertex>’ to ‘const GLvoid*’ in argument passing
_
ベクターをglBufferData()
と互換性のある型に変換するにはどうすればよいですか?
現時点では、正しいメモリ割り当ては気にしていません。vertices.size() * 3 * sizeof(float)
はsegfaultの可能性が高いですが、タイプエラーを最初に解決したいと思います。
std::vector<T> v
がある場合は、式T*
を使用して、連続するデータ(OpenGLの後に続くデータ)の開始を指す&v[0]
を取得できます。
あなたの場合、これはVertex*
をglBufferData
に渡すことを意味します:
glBufferData(
GL_ARRAY_BUFFER,
vertices.size() * sizeof(Vertex),
&vertices[0],
GL_STATIC_DRAW
);
またはこれは同じです:
glBufferData(
GL_ARRAY_BUFFER,
vertices.size() * sizeof(Vertex),
&vertices.front(),
GL_STATIC_DRAW
);
ここでは、Vertex*
からvoid const*
への暗黙的な変換を利用できます。それは問題にならないはずです。
これでうまくいくはずです:
_&vertices[0]
_
一部の人は&vertices.front()
を好みますが、それはよりタイピングが多く、私は骨の折れる仕事です。
さらに遅延させるには、glBufferData
をオーバーロードすることができます。
_template <class T>
inline void glBufferData(GLenum target, const vector<T>& v, GLenum usage) {
glBufferData(target, v.size() * sizeof(T), &v[0], usage);
}
_
それからあなたは書くことができます:
_glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
_
また、バグを回避します(構造体が3 * sizeof(float)
より大きい)。