namespace Msp {
namespace GL {
+bool VertexArray::legacy_used = false;
+
VertexArray::VertexArray(const VertexFormat &f)
{
reset(f);
clear();
format = f;
stride = get_stride(format);
+ legacy = false;
arrays.clear();
arr.component = *c;
arr.offset = offs;
+ if(*c<ATTRIB1)
+ legacy = true;
+
offs += get_component_size(*c);
}
}
return data.size()*sizeof(float);
}
-void VertexArray::bind() const
+void VertexArray::apply(bool use_legacy) const
{
if(format.empty())
throw invalid_operation("VertexArray::apply");
if(Mesh::current())
throw invalid_operation("VertexArray::apply");
+ /* Unbind first if the legacy flag changes. The logic for supporting it
+ directly in apply_arrays would get too complicated, and this also allows
+ rebinding the same array with different legacy setting. */
+ if(legacy_used!=use_legacy)
+ unbind();
+
+ if(!use_legacy)
+ static Require _req(ARB_vertex_shader);
+
const VertexArray *old = current();
/* If the array has been modified, apply it even if it was the last one to
be applied. This is necessary to get the data updated to vertex buffer, and
const float *base = (vbuf ? reinterpret_cast<float *>(get_offset()) : &data[0]);
unsigned stride_bytes = stride*sizeof(float);
- apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes);
+ apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes, use_legacy);
}
-void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes)
+void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes, bool use_legacy)
{
unsigned active_tex = 0;
unsigned n_arrays = arrays ? arrays->size() : 0;
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)
- glVertexPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
- array_type = GL_VERTEX_ARRAY;
- }
- else if(t==get_component_type(NORMAL3))
+ if(use_legacy)
{
- if(arr)
- glNormalPointer(GL_FLOAT, stride_bytes, base+arr->offset);
- array_type = GL_NORMAL_ARRAY;
- }
- else if(t==get_component_type(COLOR4_FLOAT))
- {
- if(arr)
+ GLenum array_type = 0;
+ if(t==get_component_type(VERTEX3))
{
- if(sz==1)
- glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset);
- else
- glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
+ if(arr)
+ glVertexPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
+ array_type = GL_VERTEX_ARRAY;
}
- array_type = GL_COLOR_ARRAY;
- }
- else if(comp>=TEXCOORD1 && comp<=TEXCOORD4+12)
- {
- t -= get_component_type(TEXCOORD1);
- if(t>0 || active_tex)
+ else if(t==get_component_type(NORMAL3))
+ {
+ if(arr)
+ glNormalPointer(GL_FLOAT, stride_bytes, base+arr->offset);
+ array_type = GL_NORMAL_ARRAY;
+ }
+ else if(t==get_component_type(COLOR4_FLOAT))
+ {
+ if(arr)
+ {
+ if(sz==1)
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset);
+ else
+ glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
+ }
+ array_type = GL_COLOR_ARRAY;
+ }
+ else if(comp>=TEXCOORD1 && comp<=TEXCOORD4+12)
{
- glClientActiveTexture(GL_TEXTURE0+t);
- active_tex = t;
+ t -= get_component_type(TEXCOORD1);
+ if(t>0 || active_tex)
+ {
+ glClientActiveTexture(GL_TEXTURE0+t);
+ active_tex = t;
+ }
+ if(arr)
+ glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
+ array_type = GL_TEXTURE_COORD_ARRAY;
+ }
+
+ if(array_type)
+ {
+ // Only change enable state if needed
+ if(arr && !old_arr)
+ glEnableClientState(array_type);
+ else if(old_arr && !arr)
+ glDisableClientState(array_type);
+
+ continue;
}
- if(arr)
- glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
- 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)
+ if(arr->component==COLOR4_UBYTE)
+ glVertexAttribPointer(t, 4, GL_UNSIGNED_BYTE, true, stride_bytes, base+arr->offset);
+ else
glVertexAttribPointer(t, sz, GL_FLOAT, false, stride_bytes, base+arr->offset);
}
// Only change enable state if needed
if(arr && !old_arr)
- {
- if(array_type)
- glEnableClientState(array_type);
- else
- glEnableVertexAttribArray(t);
- }
+ glEnableVertexAttribArray(t);
else if(old_arr && !arr)
- {
- if(array_type)
- glDisableClientState(array_type);
- else
- glDisableVertexAttribArray(t);
- }
+ glDisableVertexAttribArray(t);
}
if(active_tex)
glClientActiveTexture(GL_TEXTURE0);
+
+ legacy_used = use_legacy;
}
void VertexArray::unbind()
{
const VertexArray *old = current();
if(set_current(0))
- apply_arrays(0, &old->arrays, 0, 0);
+ apply_arrays(0, &old->arrays, 0, 0, legacy_used);
}