]> git.tdb.fi Git - libs/gl.git/blobdiff - source/vertexarray.cpp
Check for OES_mapbuffer in Buffer::unmap
[libs/gl.git] / source / vertexarray.cpp
index 042f58c758b41ac48af3fccd52dcb7ec5f75440b..5674bbe0ddda48472cc0423b5230fe754710b3fc 100644 (file)
@@ -1,5 +1,6 @@
 #include <msp/gl/extensions/arb_multitexture.h>
 #include <msp/gl/extensions/arb_vertex_shader.h>
 #include <msp/gl/extensions/arb_multitexture.h>
 #include <msp/gl/extensions/arb_vertex_shader.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "buffer.h"
 #include "error.h"
 #include "gl.h"
 #include "buffer.h"
 #include "error.h"
 #include "gl.h"
@@ -11,6 +12,8 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
 namespace Msp {
 namespace GL {
 
+bool VertexArray::legacy_used = false;
+
 VertexArray::VertexArray(const VertexFormat &f)
 {
        reset(f);
 VertexArray::VertexArray(const VertexFormat &f)
 {
        reset(f);
@@ -29,6 +32,7 @@ void VertexArray::reset(const VertexFormat &f)
        clear();
        format = f;
        stride = get_stride(format);
        clear();
        format = f;
        stride = get_stride(format);
+       legacy = false;
 
        arrays.clear();
 
 
        arrays.clear();
 
@@ -43,6 +47,9 @@ void VertexArray::reset(const VertexFormat &f)
                arr.component = *c;
                arr.offset = offs;
 
                arr.component = *c;
                arr.offset = offs;
 
+               if(*c<ATTRIB1)
+                       legacy = true;
+
                offs += get_component_size(*c);
        }
 }
                offs += get_component_size(*c);
        }
 }
@@ -85,6 +92,7 @@ void VertexArray::reserve(unsigned n)
 float *VertexArray::append()
 {
        data.insert(data.end(), stride, 0.0f);
 float *VertexArray::append()
 {
        data.insert(data.end(), stride, 0.0f);
+       update_offset();
        dirty = true;
        return &*(data.end()-stride);
 }
        dirty = true;
        return &*(data.end()-stride);
 }
@@ -100,7 +108,7 @@ unsigned VertexArray::get_data_size() const
        return data.size()*sizeof(float);
 }
 
        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(format.empty())
                throw invalid_operation("VertexArray::apply");
@@ -108,6 +116,17 @@ void VertexArray::bind() const
        if(Mesh::current())
                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);
+       else if(legacy)
+               static Require _req(MSP_legacy_features);
+
        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 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
@@ -123,10 +142,10 @@ void VertexArray::bind() const
 
        const float *base = (vbuf ? reinterpret_cast<float *>(get_offset()) : &data[0]);
        unsigned stride_bytes = stride*sizeof(float);
 
        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 active_tex = 0;
        unsigned n_arrays = arrays ? arrays->size() : 0;
@@ -142,76 +161,85 @@ void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array>
                unsigned char comp = (arr ? arr->component : old_arr->component);
                unsigned sz = get_component_size(comp);
                unsigned t = get_component_type(comp);
                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)
                                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)
                else if(old_arr && !arr)
-               {
-                       if(array_type)
-                               glDisableClientState(array_type);
-                       else
-                               glDisableVertexAttribArray(t);
-               }
+                       glDisableVertexAttribArray(t);
        }
 
        if(active_tex)
                glClientActiveTexture(GL_TEXTURE0);
        }
 
        if(active_tex)
                glClientActiveTexture(GL_TEXTURE0);
+
+       legacy_used = use_legacy;
 }
 
 void VertexArray::unbind()
 {
        const VertexArray *old = current();
        if(set_current(0))
 }
 
 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);
 }
 
 
 }