From: Mikko Rasa Date: Fri, 17 Oct 2014 18:30:08 +0000 (+0300) Subject: Allow applying a VertexArray in non-legacy mode X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=d6ec375442b31d052b9fcb013508ad7523749147 Allow applying a VertexArray in non-legacy mode Mesh::bind now has consistent results whether or not vertex array objects are available. This is unlikely to be needed on full OpenGL, but is necessary for OpenGL ES 2.0 support (ES 3.0 has VAOs). --- diff --git a/source/mesh.cpp b/source/mesh.cpp index 3e9e118a..869ea671 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -183,7 +183,7 @@ void Mesh::bind() const if(!vao_id) { unbind(); - vertices.apply(); + vertices.apply(false); } else if(set_current(this)) { diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index 867aee7b..db102ab4 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -11,6 +11,8 @@ using namespace std; namespace Msp { namespace GL { +bool VertexArray::legacy_used = false; + VertexArray::VertexArray(const VertexFormat &f) { reset(f); @@ -29,6 +31,7 @@ void VertexArray::reset(const VertexFormat &f) clear(); format = f; stride = get_stride(format); + legacy = false; arrays.clear(); @@ -43,6 +46,9 @@ void VertexArray::reset(const VertexFormat &f) arr.component = *c; arr.offset = offs; + if(*c(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 *arrays, const vector *old_arrays, const float *base, unsigned stride_bytes) +void VertexArray::apply_arrays(const vector *arrays, const vector *old_arrays, const float *base, unsigned stride_bytes, bool use_legacy) { unsigned active_tex = 0; unsigned n_arrays = arrays ? arrays->size() : 0; @@ -143,76 +158,85 @@ void VertexArray::apply_arrays(const vector *arrays, const vector 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); } diff --git a/source/vertexarray.h b/source/vertexarray.h index 9fa55b71..d6dee7dd 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -39,6 +39,9 @@ private: std::vector data; unsigned stride; std::vector arrays; + bool legacy; + + static bool legacy_used; VertexArray(const VertexArray &); VertexArray &operator=(const VertexArray &); @@ -68,10 +71,10 @@ public: const std::vector &get_data() const { return data; } const float *operator[](unsigned i) const { return &data[0]+i*stride; } - void bind() const; - void apply() const { bind(); } + void bind() const { apply(); } + void apply(bool = true) const; private: - static void apply_arrays(const std::vector *, const std::vector *, const float *, unsigned); + static void apply_arrays(const std::vector *, const std::vector *, const float *, unsigned, bool); public: static void unbind(); };