I've been wandering how I can expand the number of different vertex structures I can support to increase the flexibility of data I can load in. Currently my data is structured something like this:
struct Vertex
{
vec3 pos;
vec3 norm;
vec2 uv;
vec3 tan;
vec3 binorm;
};
glVertexAttribPointer(...) x 5
But what happens If I load some data in which doesn't contain tangents and binormals? It'd be wasting precious space.
I was thinking a possible solution would be something like this:
enum VertexFormat
{
POS_NORM_TEX = 0,
POS_NORM_COL = 1,
POS_NORM_TEX_TAN_BIT = 2,
};
class Vertex
{
public:
Vertex();
~Vertex();
void PushAttribute(float val) { m_data.push_back(val); }
void PushAttribute(vec3& val)
{
m_data.push_back(val.x);
// etc
}
void PushAttribute(vec2& val) { //same as above }
float* GetFloatBuffer() { return &m_data[0]; }
private:
std::vector<float> m_data;
};
then the VBO will know the format of all of it's vertices that are added
class VertexBufferObject
{
public:
VertexBufferObject(VertexFormat format)
: m_format(format) {}
float* GetArray();
int GetSize();
private:
vector<Vertex> m_vertices;
VertexFormat m_format;
};
This would allow the graphics module to bind the correct attributes based on the VertexFormat of the buffer. But at the same time, It doesn't ensure that each Vertex is guaranteed to be in the format specified which won't be a problem if I'm controlling the data coming in from my own asset pipeline.
I want to know if this is a good way to go about things? What have other people done and is there a clearly better way that I'm missing?
Thanks guys,
Rocklobster