-/* $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 {
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;
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>;
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()
{
TextureMap::const_iterator i = textures.find(id);
if(i==textures.end())
- throw KeyError("Unknown texture");
+ throw runtime_error("Unknown texture");
return i->second;
}
{
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);
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)
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
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
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))
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);
+}