]> git.tdb.fi Git - libs/gl.git/blobdiff - source/vertexarray.cpp
Make a const pointer to a Bufferable's buffer publicly accessible
[libs/gl.git] / source / vertexarray.cpp
index 867aee7b189b71f348950741e4f2ccda6ae18921..a4dffbb7bae4876af7c9535a1f965e8431b64f7b 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);
        }
 }
@@ -101,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");
@@ -109,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
@@ -117,17 +135,17 @@ void VertexArray::bind() const
        if(!set_current(this) && !dirty)
                return;
 
        if(!set_current(this) && !dirty)
                return;
 
-       Buffer *vbuf = get_buffer();
+       const Buffer *vbuf = get_buffer();
        Bind _bind_vbuf(vbuf, ARRAY_BUFFER);
        if(vbuf && dirty)
                update_buffer();
 
        const float *base = (vbuf ? reinterpret_cast<float *>(get_offset()) : &data[0]);
        unsigned stride_bytes = stride*sizeof(float);
        Bind _bind_vbuf(vbuf, ARRAY_BUFFER);
        if(vbuf && dirty)
                update_buffer();
 
        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;
@@ -143,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)
+                       {
+                               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)
                        {
                        {
-                               glClientActiveTexture(GL_TEXTURE0+t);
-                               active_tex = t;
+                               // 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);
 }
 
 
 }
 
 
@@ -225,6 +252,27 @@ VertexArray::Array::Array():
 VertexArray::Loader::Loader(VertexArray &a):
        VertexArrayBuilder(a)
 {
 VertexArray::Loader::Loader(VertexArray &a):
        VertexArrayBuilder(a)
 {
+       add("vertex", static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
+       add("vertex", static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
+       add("vertex", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
+       add("normal", static_cast<void (Loader::*)(float, float, float)>(&Loader::normal));
+       add("texcoord", static_cast<void (Loader::*)(float)>(&Loader::texcoord));
+       add("texcoord", static_cast<void (Loader::*)(float, float)>(&Loader::texcoord));
+       add("texcoord", static_cast<void (Loader::*)(float, float, float)>(&Loader::texcoord));
+       add("texcoord", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
+       add("multitexcoord", static_cast<void (Loader::*)(unsigned, float)>(&Loader::multitexcoord));
+       add("multitexcoord", static_cast<void (Loader::*)(unsigned, float, float)>(&Loader::multitexcoord));
+       add("multitexcoord", static_cast<void (Loader::*)(unsigned, float, float, float)>(&Loader::multitexcoord));
+       add("multitexcoord", static_cast<void (Loader::*)(unsigned, float, float, float, float)>(&Loader::multitexcoord));
+       add("color", static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
+       add("color", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
+       add("attrib", static_cast<void (Loader::*)(unsigned, float)>(&Loader::attrib));
+       add("attrib", static_cast<void (Loader::*)(unsigned, float, float)>(&Loader::attrib));
+       add("attrib", static_cast<void (Loader::*)(unsigned, float, float, float)>(&Loader::attrib));
+       add("attrib", static_cast<void (Loader::*)(unsigned, float, float, float, float)>(&Loader::attrib));
+       add("tangent", static_cast<void (Loader::*)(float, float, float)>(&Loader::tangent));
+       add("binormal", static_cast<void (Loader::*)(float, float, float)>(&Loader::binormal));
+
        add("vertex2",   static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
        add("vertex3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
        add("vertex4",   static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
        add("vertex2",   static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
        add("vertex3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
        add("vertex4",   static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));