J'ai écrit un chargeur de modèle en C++ un OpenGL. J'ai utilisé std::vector
S pour stocker mes données de sommet, mais maintenant je veux les transmettre à glBufferData()
, mais les types de données sont très différents. Je veux savoir s'il existe un moyen de convertir entre std::vector
En const GLvoid *
Documenté pour 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);
J'obtiens l'erreur (attendue) suivante:
error: cannot convert ‘std::vector<Vertex>’ to ‘const GLvoid*’ in argument passing
Comment puis-je convertir le vecteur en un type compatible avec glBufferData()
?
NB. Je ne me soucie pas de l'allocation de mémoire correcte pour le moment; vertices.size() * 3 * sizeof(float)
sera très probablement un défaut de segmentation, mais je veux d'abord résoudre l'erreur de type.
Si tu as un std::vector<T> v
, vous pouvez obtenir un T*
pointant vers le début des données contiguës (qui est ce qu'OpenGL recherche) avec l'expression &v[0]
.
Dans votre cas, cela signifie passer un Vertex*
à glBufferData
:
glBufferData(
GL_ARRAY_BUFFER,
vertices.size() * sizeof(Vertex),
&vertices[0],
GL_STATIC_DRAW
);
Ou comme ça, qui est le même:
glBufferData(
GL_ARRAY_BUFFER,
vertices.size() * sizeof(Vertex),
&vertices.front(),
GL_STATIC_DRAW
);
Vous pouvez compter sur la conversion implicite de Vertex*
à void const*
ici; cela ne devrait pas poser de problème.
Cela devrait faire l'affaire:
&vertices[0]
Certains préfèrent &vertices.front()
, mais c'est plus typé et je suis paresseux.
Pour être encore plus paresseux, vous pourriez surcharger glBufferData
ainsi:
template <class T>
inline void glBufferData(GLenum target, const vector<T>& v, GLenum usage) {
glBufferData(target, v.size() * sizeof(T), &v[0], usage);
}
Ensuite, vous pouvez écrire:
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
et évitez également les bugs (votre structure est plus grande que 3 * sizeof(float)
).