From: Mikko Rasa Date: Mon, 3 Sep 2012 19:06:25 +0000 (+0300) Subject: Fix vertex array offsets X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=ab59f5a9e66b3fc7872ad96ec7949940189f0819;p=libs%2Fgl.git Fix vertex array offsets 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. --- diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index d834ab7c..6c0e5f1a 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -28,12 +28,18 @@ void VertexArray::reset(const VertexFormat &f) arrays.clear(); + unsigned offset = 0; 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); - arrays[slot] = *c; + + Array &arr = arrays[slot]; + arr.component = *c; + arr.offset = offset; + + offset += get_component_size(*c); } } @@ -133,7 +139,6 @@ void VertexArray::apply() const } const float *base = (vbuf ? 0 : &data[0]); - unsigned offset = 0; unsigned stride_bytes = stride*sizeof(float); unsigned active_tex = 0; unsigned n_arrays = arrays.size(); @@ -141,25 +146,25 @@ void VertexArray::apply() const n_arrays = max(n_arrays, old->arrays.size()); for(unsigned i=0; iarrays.size() ? old->arrays[i] : 0); + const Array *arr = ((iarrays.size() && old->arrays[i].component) ? &old->arrays[i] : 0); 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) - 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) - 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)) @@ -167,9 +172,9 @@ void VertexArray::apply() const if(arr) { if(sz==1) - glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+offset); + glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset); else - glColorPointer(sz, GL_FLOAT, stride_bytes, base+offset); + glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset); } array_type = GL_COLOR_ARRAY; } @@ -182,7 +187,7 @@ void VertexArray::apply() const 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 @@ -190,7 +195,7 @@ void VertexArray::apply() const 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 @@ -208,9 +213,6 @@ void VertexArray::apply() const else glDisableVertexAttribArray(t); } - - if(arr) - offset += sz; } if(active_tex) @@ -221,6 +223,12 @@ void VertexArray::apply() const } +VertexArray::Array::Array(): + component(0), + offset(0) +{ } + + VertexArray::Loader::Loader(VertexArray &a): VertexArrayBuilder(a) { diff --git a/source/vertexarray.h b/source/vertexarray.h index 26204b31..1887ad91 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -26,10 +26,18 @@ public: }; private: + struct Array + { + unsigned char component; + unsigned char offset; + + Array(); + }; + VertexFormat format; std::vector data; unsigned stride; - std::vector arrays; + std::vector arrays; RefPtr vbuf; bool defer_vbuf; mutable bool dirty;