]> git.tdb.fi Git - gldbg.git/blobdiff - flavors/gl/source/glstate.cpp
Track uniform buffer bindings
[gldbg.git] / flavors / gl / source / glstate.cpp
index 1459324232f36d3b6af583bfe1def2a3e0ffb22a..0163c2f884605603170f60303ad9d856e611ea28 100644 (file)
@@ -1,15 +1,7 @@
-/* $Id$
-
-This file is part of gldbg
-Copyright © 2009-2010  Mikko Rasa, Mikkosoft Productions
-Distributed under the GPL
-*/
-
-#include <msp/core/except.h>
+#include <stdexcept>
 #include "glstate.h"
 
 using namespace std;
-using namespace Msp;
 
 namespace {
 
@@ -74,7 +66,9 @@ GlState::GlState():
        active_tex(0),
        client_active_tex(0),
        array_buffer(0),
-       element_buffer(0)
+       element_buffer(0),
+       uniform_buffer(0),
+       uniform_bind_points(64)
 {
        vertex_array.kind = GL_VERTEX_ARRAY;
        normal_array.kind = GL_NORMAL_ARRAY;
@@ -85,6 +79,13 @@ GlState::GlState():
                texcoord_arrays[i].index = i;
        }
 
+       decoder->glEnableClientState = glEnableClientState;
+       decoder->glDisableClientState = glDisableClientState;
+       decoder->glEnableVertexAttribArray = glEnableVertexAttribArray;
+       decoder->glEnableVertexAttribArrayARB = glEnableVertexAttribArray;
+       decoder->glDisableVertexAttribArray = glDisableVertexAttribArray;
+       decoder->glDisableVertexAttribArrayARB = glDisableVertexAttribArray;
+
        decoder->glColor3ub = wrap_normalized<GLubyte, glColor3f>;
        decoder->glColor3ubv = wrap_array<GLubyte, wrap_normalized<GLubyte, glColor3f> >;
        decoder->glColor4ub = wrap_normalized<GLubyte, glColor4f>;
@@ -118,15 +119,23 @@ GlState::GlState():
        decoder->glClientActiveTexture = glClientActiveTexture;
        decoder->glClientActiveTextureARB = glClientActiveTexture;
        decoder->glTexCoordPointer = glTexCoordPointer;
+       decoder->glVertexAttribPointer = glVertexAttribPointer;
+       decoder->glVertexAttribPointerARB = glVertexAttribPointer;
 
        decoder->glBindBuffer = glBindBuffer;
        decoder->glBindBufferARB = glBindBuffer;
+       decoder->glBindBufferBase = glBindBufferBase;
+       decoder->glBindBufferRange = glBindBufferRange;
        decoder->glBufferData = glBufferData;
        decoder->glBufferDataARB = glBufferData;
        decoder->glBufferSubData = glBufferSubData;
        decoder->glBufferSubDataARB = glBufferSubData;
        decoder->glDeleteBuffers = glDeleteBuffers;
        decoder->glDeleteBuffersARB = glDeleteBuffers;
+
+       decoder->glDrawElements = glDrawElements;
+       decoder->glDrawRangeElements = glDrawRangeElements;
+       decoder->glDrawRangeElementsEXT = glDrawRangeElements;
 }
 
 GlState::~GlState()
@@ -143,7 +152,7 @@ const TextureState &GlState::get_texture(unsigned id) const
 {
        TextureMap::const_iterator i = textures.find(id);
        if(i==textures.end())
-               throw KeyError("Unknown texture");
+               throw runtime_error("Unknown texture");
        return i->second;
 }
 
@@ -151,10 +160,46 @@ const BufferState &GlState::get_buffer(unsigned id) const
 {
        BufferMap::const_iterator i = buffers.find(id);
        if(i==buffers.end())
-               throw KeyError("Unknown buffer");
+               throw runtime_error("Unknown buffer");
        return i->second;
 }
 
+const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
+{
+       if(target==GL_UNIFORM_BUFFER)
+               return uniform_bind_points[index];
+       throw runtime_error("This buffer target does not have indexed binding points");
+}
+
+const ArrayState &GlState::get_array(GLenum array) const
+{
+       if(array==GL_VERTEX_ARRAY)
+               return vertex_array;
+       else if(array==GL_NORMAL_ARRAY)
+               return normal_array;
+       else if(array==GL_COLOR_ARRAY)
+               return color_array;
+       else if(array==GL_TEXTURE_COORD_ARRAY)
+               return texcoord_arrays[client_active_tex];
+       else
+               throw logic_error("Invalid array");
+}
+
+const ArrayState &GlState::get_texture_coord_array(unsigned index) const
+{
+       return texcoord_arrays[index];
+}
+
+const ArrayState &GlState::get_attrib_array(unsigned index) const
+{
+       map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
+       if(i!=attrib_arrays.end())
+               return i->second;
+
+       // XXX Return a dummy?
+       throw runtime_error("Unknown attribute array");
+}
+
 const BufferState *GlState::get_current_buffer(GLenum target) const
 {
        return const_cast<GlState *>(this)->get_current_buffer(target);
@@ -180,42 +225,28 @@ TextureState *GlState::get_current_texture(GLenum target)
        return texunits[active_tex].get_current_texture(target);
 }
 
+BufferState *GlState::get_buffer_object(unsigned id)
+{
+       BufferMap::iterator i = buffers.find(id);
+       return (i==buffers.end() ? 0 : &i->second);
+}
+
 BufferState *GlState::get_current_buffer(GLenum target)
 {
        if(target==GL_ARRAY_BUFFER)
                return array_buffer;
        else if(target==GL_ELEMENT_ARRAY_BUFFER)
                return element_buffer;
+       else if(target==GL_UNIFORM_BUFFER)
+               return uniform_buffer;
        return 0;
 }
 
-const ArrayState &GlState::get_array(GLenum array) const
-{
-       if(array==GL_VERTEX_ARRAY)
-               return vertex_array;
-       else if(array==GL_NORMAL_ARRAY)
-               return normal_array;
-       else if(array==GL_COLOR_ARRAY)
-               return color_array;
-       else if(array==GL_TEXTURE_COORD_ARRAY)
-               return texcoord_arrays[client_active_tex];
-       else
-               throw InvalidParameterValue("Invalid array");
-}
-
-const ArrayState &GlState::get_texture_coord_array(unsigned index) const
+BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
 {
-       return texcoord_arrays[index];
-}
-
-const ArrayState &GlState::get_attrib_array(unsigned index) const
-{
-       map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
-       if(i!=attrib_arrays.end())
-               return i->second;
-
-       // XXX Return a dummy?
-       throw KeyError("Unknown attribute array");
+       if(target==GL_UNIFORM_BUFFER)
+               return &uniform_bind_points[index];
+       return 0;
 }
 
 void GlState::set_current_texture(GLenum target, unsigned id)
@@ -250,6 +281,20 @@ void GlState::set_current_buffer(GLenum target, unsigned id)
                array_buffer = buf;
        else if(target==GL_ELEMENT_ARRAY_BUFFER)
                element_buffer = buf;
+       else if(target==GL_UNIFORM_BUFFER)
+               uniform_buffer = buf;
+}
+
+ArrayState &GlState::get_attrib_array(unsigned index)
+{
+       map<unsigned, ArrayState>::iterator i = attrib_arrays.find(index);
+       if(i!=attrib_arrays.end())
+               return i->second;
+
+       ArrayState &array = attrib_arrays[index];
+       array.index = index;
+
+       return array;
 }
 
 // Boolean state
@@ -384,10 +429,10 @@ void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stri
        self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
 }
 
-void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, int norm, int stride, const void *data)
+void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data)
 {
        GlState *self = reinterpret_cast<GlState *>(user_data);
-       self->attrib_arrays[index].set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
+       self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
 }
 
 // Buffer objects
@@ -395,6 +440,23 @@ void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, G
 void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id)
 { reinterpret_cast<GlState *>(user_data)->set_current_buffer(target, id); }
 
+void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id)
+{
+       if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
+               glBindBufferRange(user_data, target, index, id, 0, buffer->size);
+}
+
+void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size)
+{
+       GlState *self = reinterpret_cast<GlState *>(user_data);
+       if(BufferBindingState *binding = self->get_buffer_binding(target, index))
+       {
+               binding->buffer = self->get_buffer_object(id);
+               binding->offset = offset;
+               binding->size = size;
+       }
+}
+
 void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage)
 {
        if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
@@ -412,3 +474,15 @@ void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids)
        for(int i=0; i<count; ++i)
                reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
 }
+
+void GlState::glDrawElements(void *user_data, GLenum, int, GLenum type, const void *)
+{
+       if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
+               buf->content.update_elements(type);
+}
+
+void GlState::glDrawRangeElements(void *user_data, GLenum, unsigned, unsigned, int, GLenum type, const void *)
+{
+       if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
+               buf->content.update_elements(type);
+}