Since array application order may now be different from the format order,
and VertexArrayBuilder stores components in the latter, calculating the
offsets while applying arrays gives wrong results.
for(const unsigned char *c=format.begin(); c!=format.end(); ++c)
{
unsigned slot = get_array_slot(*c);
if(slot>=arrays.size())
arrays.resize(slot+1);
for(const unsigned char *c=format.begin(); c!=format.end(); ++c)
{
unsigned slot = get_array_slot(*c);
if(slot>=arrays.size())
arrays.resize(slot+1);
+
+ Array &arr = arrays[slot];
+ arr.component = *c;
+ arr.offset = offset;
+
+ offset += get_component_size(*c);
}
const float *base = (vbuf ? 0 : &data[0]);
}
const float *base = (vbuf ? 0 : &data[0]);
unsigned stride_bytes = stride*sizeof(float);
unsigned active_tex = 0;
unsigned n_arrays = arrays.size();
unsigned stride_bytes = stride*sizeof(float);
unsigned active_tex = 0;
unsigned n_arrays = arrays.size();
n_arrays = max(n_arrays, old->arrays.size());
for(unsigned i=0; i<n_arrays; ++i)
{
n_arrays = max(n_arrays, old->arrays.size());
for(unsigned i=0; i<n_arrays; ++i)
{
- unsigned char arr = (i<arrays.size() ? arrays[i] : 0);
- unsigned char old_arr = (old && i<old->arrays.size() ? old->arrays[i] : 0);
+ const Array *arr = ((i<arrays.size() && arrays[i].component) ? &arrays[i] : 0);
+ const Array *old_arr = ((old && i<old->arrays.size() && old->arrays[i].component) ? &old->arrays[i] : 0);
if(!arr && !old_arr)
continue;
if(!arr && !old_arr)
continue;
- unsigned char comp = (arr ? arr : old_arr);
+ unsigned char comp = (arr ? arr->component : old_arr->component);
unsigned sz = get_component_size(comp);
unsigned t = get_component_type(comp);
GLenum array_type = 0;
if(t==get_component_type(VERTEX3))
{
if(arr)
unsigned sz = get_component_size(comp);
unsigned t = get_component_type(comp);
GLenum array_type = 0;
if(t==get_component_type(VERTEX3))
{
if(arr)
- glVertexPointer(sz, GL_FLOAT, stride_bytes, base+offset);
+ glVertexPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
array_type = GL_VERTEX_ARRAY;
}
else if(t==get_component_type(NORMAL3))
{
if(arr)
array_type = GL_VERTEX_ARRAY;
}
else if(t==get_component_type(NORMAL3))
{
if(arr)
- glNormalPointer(GL_FLOAT, stride_bytes, base+offset);
+ glNormalPointer(GL_FLOAT, stride_bytes, base+arr->offset);
array_type = GL_NORMAL_ARRAY;
}
else if(t==get_component_type(COLOR4_FLOAT))
array_type = GL_NORMAL_ARRAY;
}
else if(t==get_component_type(COLOR4_FLOAT))
- glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+offset);
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset);
- glColorPointer(sz, GL_FLOAT, stride_bytes, base+offset);
+ glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
}
array_type = GL_COLOR_ARRAY;
}
}
array_type = GL_COLOR_ARRAY;
}
active_tex = t;
}
if(arr)
active_tex = t;
}
if(arr)
- glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+offset);
+ glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
array_type = GL_TEXTURE_COORD_ARRAY;
}
else
array_type = GL_TEXTURE_COORD_ARRAY;
}
else
if(t>=get_component_type(ATTRIB1))
t -= get_component_type(ATTRIB1);
if(arr)
if(t>=get_component_type(ATTRIB1))
t -= get_component_type(ATTRIB1);
if(arr)
- glVertexAttribPointer(t, sz, GL_FLOAT, false, stride_bytes, base+offset);
+ glVertexAttribPointer(t, sz, GL_FLOAT, false, stride_bytes, base+arr->offset);
}
// Only change enable state if needed
}
// Only change enable state if needed
else
glDisableVertexAttribArray(t);
}
else
glDisableVertexAttribArray(t);
}
-
- if(arr)
- offset += sz;
+VertexArray::Array::Array():
+ component(0),
+ offset(0)
+{ }
+
+
VertexArray::Loader::Loader(VertexArray &a):
VertexArrayBuilder(a)
{
VertexArray::Loader::Loader(VertexArray &a):
VertexArrayBuilder(a)
{
+ struct Array
+ {
+ unsigned char component;
+ unsigned char offset;
+
+ Array();
+ };
+
VertexFormat format;
std::vector<float> data;
unsigned stride;
VertexFormat format;
std::vector<float> data;
unsigned stride;
- std::vector<unsigned char> arrays;
+ std::vector<Array> arrays;
RefPtr<Buffer> vbuf;
bool defer_vbuf;
mutable bool dirty;
RefPtr<Buffer> vbuf;
bool defer_vbuf;
mutable bool dirty;