From: Mikko Rasa Date: Thu, 17 Jun 2010 09:11:25 +0000 (+0000) Subject: Move the profiler and inspector tools to the gl flavor X-Git-Url: http://git.tdb.fi/?p=gldbg.git;a=commitdiff_plain;h=f53057ce9b5eb3c7256a4aca95b4944733e14503 Move the profiler and inspector tools to the gl flavor --- diff --git a/flavors/gl/source/arraystate.cpp b/flavors/gl/source/arraystate.cpp new file mode 100644 index 0000000..37db75a --- /dev/null +++ b/flavors/gl/source/arraystate.cpp @@ -0,0 +1,34 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include "arraystate.h" +#include "bufferstate.h" + +ArrayState::ArrayState(): + kind(0), + index(0), + enabled(false), + size(4), + type(GL_FLOAT), + normalized(false), + stride(0), + buffer(0), + pointer(0) +{ } + +void ArrayState::set(unsigned s, GLenum t, bool n, unsigned r, BufferState *b, long p) +{ + size = s; + type = t; + stride = r; + normalized = n; + buffer = b; + pointer = p; + + if(buffer) + buffer->content.update(*this); +} diff --git a/flavors/gl/source/arraystate.h b/flavors/gl/source/arraystate.h new file mode 100644 index 0000000..d755297 --- /dev/null +++ b/flavors/gl/source/arraystate.h @@ -0,0 +1,31 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef ARRAYSTATE_H_ +#define ARRAYSTATE_H_ + +#include "opengl.h" + +struct BufferState; + +struct ArrayState +{ + GLenum kind; + unsigned index; + bool enabled; + unsigned size; + GLenum type; + bool normalized; + unsigned stride; + BufferState *buffer; + long pointer; + + ArrayState(); + void set(unsigned, GLenum, bool, unsigned, BufferState *, long); +}; + +#endif diff --git a/flavors/gl/source/bufferstate.cpp b/flavors/gl/source/bufferstate.cpp new file mode 100644 index 0000000..356e82b --- /dev/null +++ b/flavors/gl/source/bufferstate.cpp @@ -0,0 +1,141 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include "arraystate.h" +#include "bufferstate.h" +#include "enums.h" + +using namespace std; +using namespace Msp; + +BufferContent::BufferContent(): + consistent(true), + stride(0) +{ } + +void BufferContent::update(const ArrayState &array) +{ + if(array.stride!=stride) + consistent = false; + + stride = array.stride; + + for(vector::iterator i=arrays.begin(); i!=arrays.end(); ++i) + if(i->kind==array.kind && i->index==array.index) + { + if(array.size!=i->size || array.type!=i->type || array.pointer!=i->offset) + { + consistent = false; + arrays.erase(i); + } + else + return; + + + break; + } + + vector::iterator place = arrays.end(); + for(vector::iterator i=arrays.begin(); i!=arrays.end(); ++i) + if(i->offset>array.pointer) + { + place = i; + break; + } + + arrays.insert(place, array); +} + +string BufferContent::describe() const +{ + if(arrays.empty()) + return "(unknown)"; + + string result; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + char kind = '?'; + if(i->kind==GL_VERTEX_ARRAY) + kind = 'V'; + else if(i->kind==GL_NORMAL_ARRAY) + kind = 'N'; + else if(i->kind==GL_COLOR_ARRAY) + kind = 'C'; + else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0) + kind = 'T'; + + char type[3] = { '?', 0, 0 }; + if(i->type==GL_FLOAT) + type[0] = 'F'; + else if(i->type==GL_DOUBLE) + type[0] = 'D'; + else if(i->type==GL_INT || i->type==GL_UNSIGNED_INT) + type[0] = 'I'; + else if(i->type==GL_SHORT || i->type==GL_UNSIGNED_SHORT) + type[0] = 'S'; + else if(i->type==GL_BYTE || i->type==GL_UNSIGNED_BYTE) + type[0] = 'B'; + + if(i->type==GL_UNSIGNED_INT || i->type==GL_UNSIGNED_SHORT || i->type==GL_UNSIGNED_BYTE) + { + type[1] = type[0]; + type[0] = 'U'; + } + + if(!result.empty()) + result += '_'; + result += format("%c%d%s", kind, i->size, type); + } + + return result; +} + + +BufferContent::Array::Array(const ArrayState &a): + kind(a.kind), + index(a.index), + size(a.size), + type(a.type), + offset(a.pointer) +{ } + + +BufferState::BufferState(): + usage(GL_STATIC_DRAW), + size(0), + data(0) +{ } + +void BufferState::set_data(unsigned sz, const void *ptr, GLenum use) +{ + usage = use; + size = sz; + delete[] data; + data = new char[size]; + if(ptr) + set_sub_data(0, size, ptr); + content = BufferContent(); +} + +void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr) +{ + if(data && off+sz<=size) + { + const char *cptr = reinterpret_cast(ptr); + copy(cptr, cptr+sz, data+off); + } +} + +string BufferState::describe() const +{ + if(content.stride) + return format("%s, %d vertices (%d bytes), %s", + content.describe(), size/content.stride, size, describe_enum(usage, "")); + else + return format("%d bytes, %s", size, describe_enum(usage, "")); +} diff --git a/flavors/gl/source/bufferstate.h b/flavors/gl/source/bufferstate.h new file mode 100644 index 0000000..c3f504b --- /dev/null +++ b/flavors/gl/source/bufferstate.h @@ -0,0 +1,54 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef BUFFERSTATE_H_ +#define BUFFERSTATE_H_ + +#include +#include +#include "opengl.h" + +struct ArrayState; + +struct BufferContent +{ + struct Array + { + GLenum kind; + unsigned index; + unsigned size; + GLenum type; + int offset; + + Array(const ArrayState &); + }; + + bool consistent; + unsigned stride; + std::vector arrays; + + BufferContent(); + void update(const ArrayState &); + std::string describe() const; +}; + +struct BufferState +{ + unsigned id; + GLenum target; + GLenum usage; + unsigned size; + char *data; + BufferContent content; + + BufferState(); + void set_data(unsigned, const void *, GLenum); + void set_sub_data(unsigned, unsigned, const void *); + std::string describe() const; +}; + +#endif diff --git a/flavors/gl/source/glstate.cpp b/flavors/gl/source/glstate.cpp new file mode 100644 index 0000000..1459324 --- /dev/null +++ b/flavors/gl/source/glstate.cpp @@ -0,0 +1,414 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include "glstate.h" + +using namespace std; +using namespace Msp; + +namespace { + +template +float normalize(T v); + +template<> +float normalize(GLubyte v) +{ return v/255.0f; } + +template<> +float normalize(GLbyte v) +{ return (2*v+1)/255.0f; } + +template +void wrap_normalized(void *user_data, T v0) +{ func(user_data, v0); } + +template +void wrap_normalized(void *user_data, T v0, T v1) +{ func(user_data, v0, v1); } + +template +void wrap_normalized(void *user_data, T v0, T v1, T v2) +{ func(user_data, v0, v1, v2); } + +template +void wrap_normalized(void *user_data, T v0, T v1, T v2, T v3) +{ func(user_data, v0, v1, v2, v3); } + +template +void wrap_array(void *user_data, const T *v) +{ func(user_data, v[0]); } + +template +void wrap_array(void *user_data, const T *v) +{ func(user_data, v[0], v[1]); } + +template +void wrap_array(void *user_data, const T *v) +{ func(user_data, v[0], v[1], v[2]); } + +template +void wrap_array(void *user_data, const T *v) +{ func(user_data, v[0], v[1], v[2], v[3]); } + +} + + +Vector3::Vector3(): + x(0), y(0), z(0) +{ } + + +Vector4::Vector4(): + x(0), y(0), z(0), w(1) +{ } + + +GlState::GlState(): + decoder(gldecoder_new(this, NULL)), + active_tex(0), + client_active_tex(0), + array_buffer(0), + element_buffer(0) +{ + vertex_array.kind = GL_VERTEX_ARRAY; + normal_array.kind = GL_NORMAL_ARRAY; + color_array.kind = GL_COLOR_ARRAY; + for(unsigned i=0; i<8; ++i) + { + texcoord_arrays[i].kind = GL_TEXTURE_COORD_ARRAY; + texcoord_arrays[i].index = i; + } + + decoder->glColor3ub = wrap_normalized; + decoder->glColor3ubv = wrap_array >; + decoder->glColor4ub = wrap_normalized; + decoder->glColor4ubv = wrap_array >; + decoder->glColor3f = glColor3f; + decoder->glColor3fv = wrap_array; + decoder->glColor4f = glColor4f; + decoder->glColor4fv = wrap_array; + decoder->glTexCoord1f = glTexCoord1f; + decoder->glTexCoord1fv = wrap_array; + decoder->glTexCoord2f = glTexCoord2f; + decoder->glTexCoord2fv = wrap_array; + decoder->glTexCoord3f = glTexCoord3f; + decoder->glTexCoord3fv = wrap_array; + decoder->glTexCoord4f = glTexCoord4f; + decoder->glTexCoord4fv = wrap_array; + decoder->glNormal3f = glNormal3f; + decoder->glNormal3fv = wrap_array; + + decoder->glActiveTexture = glActiveTexture; + decoder->glActiveTextureARB = glActiveTexture; + decoder->glBindTexture = glBindTexture; + decoder->glTexImage2D = glTexImage2D; + decoder->glTexParameteri = glTexParameteri; + decoder->glTexParameteriv = glTexParameteriv; + decoder->glDeleteTextures = glDeleteTextures; + + decoder->glVertexPointer = glVertexPointer; + decoder->glNormalPointer = glNormalPointer; + decoder->glColorPointer = glColorPointer; + decoder->glClientActiveTexture = glClientActiveTexture; + decoder->glClientActiveTextureARB = glClientActiveTexture; + decoder->glTexCoordPointer = glTexCoordPointer; + + decoder->glBindBuffer = glBindBuffer; + decoder->glBindBufferARB = glBindBuffer; + decoder->glBufferData = glBufferData; + decoder->glBufferDataARB = glBufferData; + decoder->glBufferSubData = glBufferSubData; + decoder->glBufferSubDataARB = glBufferSubData; + decoder->glDeleteBuffers = glDeleteBuffers; + decoder->glDeleteBuffersARB = glDeleteBuffers; +} + +GlState::~GlState() +{ + gldecoder_delete(decoder); +} + +int GlState::decode(const char *data, unsigned len) +{ + return gldecoder_decode(decoder, data, len); +} + +const TextureState &GlState::get_texture(unsigned id) const +{ + TextureMap::const_iterator i = textures.find(id); + if(i==textures.end()) + throw KeyError("Unknown texture"); + return i->second; +} + +const BufferState &GlState::get_buffer(unsigned id) const +{ + BufferMap::const_iterator i = buffers.find(id); + if(i==buffers.end()) + throw KeyError("Unknown buffer"); + return i->second; +} + +const BufferState *GlState::get_current_buffer(GLenum target) const +{ + return const_cast(this)->get_current_buffer(target); +} + +bool &GlState::get_boolean_state(GLenum state) +{ + if(state==GL_VERTEX_ARRAY) + return vertex_array.enabled; + else if(state==GL_NORMAL_ARRAY) + return normal_array.enabled; + else if(state==GL_COLOR_ARRAY) + return color_array.enabled; + else if(state==GL_TEXTURE_COORD_ARRAY) + return texcoord_arrays[client_active_tex].enabled; + + static bool dummy; + return dummy; +} + +TextureState *GlState::get_current_texture(GLenum target) +{ + return texunits[active_tex].get_current_texture(target); +} + +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; + 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 +{ + return texcoord_arrays[index]; +} + +const ArrayState &GlState::get_attrib_array(unsigned index) const +{ + map::const_iterator i = attrib_arrays.find(index); + if(i!=attrib_arrays.end()) + return i->second; + + // XXX Return a dummy? + throw KeyError("Unknown attribute array"); +} + +void GlState::set_current_texture(GLenum target, unsigned id) +{ + TexUnitState &unit = texunits[active_tex]; + TextureState *tex = 0; + if(id) + { + tex = &textures[id]; + if(!tex->id) + { + tex->id = id; + tex->target = target; + } + else if(tex->target!=target) + return; + } + unit.set_current_texture(target, tex); +} + +void GlState::set_current_buffer(GLenum target, unsigned id) +{ + BufferState *buf = 0; + if(id) + { + buf = &buffers[id]; + if(!buf->id) + buf->id = id; + } + + if(target==GL_ARRAY_BUFFER) + array_buffer = buf; + else if(target==GL_ELEMENT_ARRAY_BUFFER) + element_buffer = buf; +} + +// Boolean state + +void GlState::glEnableClientState(void *user_data, GLenum state) +{ + reinterpret_cast(user_data)->get_boolean_state(state) = true; +} + +void GlState::glDisableClientState(void *user_data, GLenum state) +{ + reinterpret_cast(user_data)->get_boolean_state(state) = false; +} + +void GlState::glEnableVertexAttribArray(void *user_data, unsigned index) +{ + reinterpret_cast(user_data)->attrib_arrays[index].enabled = true; +} + +void GlState::glDisableVertexAttribArray(void *user_data, unsigned index) +{ + reinterpret_cast(user_data)->attrib_arrays[index].enabled = false; +} + +// Vertex attributes + +void GlState::glColor3f(void *user_data, float r, float g, float b) +{ glColor4f(user_data, r, g, b, 1.0f); } + +void GlState::glColor4f(void *user_data, float r, float g, float b, float a) +{ + Vector4 &color = reinterpret_cast(user_data)->color; + color.r = r; + color.g = g; + color.b = b; + color.a = a; +} + +void GlState::glNormal3f(void *user_data, float x, float y, float z) +{ + Vector3 &normal = reinterpret_cast(user_data)->normal; + normal.x = x; + normal.y = y; + normal.z = z; +} + +void GlState::glTexCoord1f(void *user_data, float s) +{ glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f); } + +void GlState::glTexCoord2f(void *user_data, float s, float t) +{ glTexCoord4f(user_data, s, t, 0.0f, 1.0f); } + +void GlState::glTexCoord3f(void *user_data, float s, float t, float p) +{ glTexCoord4f(user_data, s, t, p, 1.0f); } + +void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q) +{ + unsigned index = reinterpret_cast(user_data)->active_tex; + glMultiTexCoord4f(user_data, index, s, t, p, q); +} + +void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q) +{ + Vector4 &texcoord = reinterpret_cast(user_data)->texcoord[index]; + texcoord.s = s; + texcoord.t = t; + texcoord.p = p; + texcoord.q = q; +} + +// Textures + +void GlState::glActiveTexture(void *user_data, unsigned index) +{ + reinterpret_cast(user_data)->active_tex = index-GL_TEXTURE0; +} + +void GlState::glBindTexture(void *user_data, GLenum target, unsigned id) +{ + reinterpret_cast(user_data)->set_current_texture(target, id); +} + +void GlState::glTexImage2D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int, GLenum, GLenum, const void *) +{ + if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) + tex->set_image_2d(level, ifmt, width, height); +} + +void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value) +{ glTexParameteriv(user_data, target, param, &value); } + +void GlState::glTexParameteriv(void *user_data, GLenum target, GLenum param, const int *values) +{ + if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) + tex->set_parameter(param, values); +} + +void GlState::glDeleteTextures(void *user_data, int count, const unsigned *ids) +{ + for(int i=0; i(user_data)->textures.erase(ids[i]); +} + +// Vertex arrays + +void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data) +{ + GlState *self = reinterpret_cast(user_data); + self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast(data)); +} + +void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data) +{ + GlState *self = reinterpret_cast(user_data); + self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast(data)); +} + +void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data) +{ + GlState *self = reinterpret_cast(user_data); + self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast(data)); +} + +void GlState::glClientActiveTexture(void *user_data, unsigned index) +{ + reinterpret_cast(user_data)->client_active_tex = index-GL_TEXTURE0; +} + +void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data) +{ + GlState *self = reinterpret_cast(user_data); + self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast(data)); +} + +void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, int norm, int stride, const void *data) +{ + GlState *self = reinterpret_cast(user_data); + self->attrib_arrays[index].set(size, type, norm, stride, self->array_buffer, reinterpret_cast(data)); +} + +// Buffer objects + +void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id) +{ reinterpret_cast(user_data)->set_current_buffer(target, id); } + +void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage) +{ + if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) + buf->set_data(size, data, usage); +} + +void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data) +{ + if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) + buf->set_sub_data(offset, size, data); +} + +void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids) +{ + for(int i=0; i(user_data)->buffers.erase(ids[i]); +} diff --git a/flavors/gl/source/glstate.h b/flavors/gl/source/glstate.h new file mode 100644 index 0000000..86cc538 --- /dev/null +++ b/flavors/gl/source/glstate.h @@ -0,0 +1,124 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef GLSTATE_H_ +#define GLSTATE_H_ + +#include +#include +#include "arraystate.h" +#include "bufferstate.h" +#include "gldecoder.h" +#include "texturestate.h" + +struct Vector3 +{ + float x, y, z; + + Vector3(); +}; + +struct Vector4 +{ + union { float x, r, s; }; + union { float y, g, t; }; + union { float z, b, p; }; + union { float w, a, q; }; + + Vector4(); +}; + +/** +Tracks OpenGL state based on the command stream. This class is essentially a +(partial) OpenGL implementation in itself. + +XXX Should determine the number of texture units the target implementation +actually supports. +*/ +class GlState +{ +public: + typedef std::map TextureMap; + typedef std::map BufferMap; + +private: + GlDecoder *decoder; + Vector4 color; + Vector4 texcoord[8]; + Vector3 normal; + unsigned active_tex; + unsigned client_active_tex; + TextureMap textures; + TexUnitState texunits[8]; + BufferMap buffers; + BufferState *array_buffer; + BufferState *element_buffer; + ArrayState vertex_array; + ArrayState normal_array; + ArrayState color_array; + ArrayState texcoord_arrays[8]; + std::map attrib_arrays; + +public: + GlState(); + ~GlState(); + + int decode(const char *, unsigned); + const Vector4 &get_color() const { return color; } + const Vector4 &get_texcoord(unsigned i) const { return texcoord[i]; } + const Vector3 &get_normal() const { return normal; } + const TextureMap &get_textures() const { return textures; } + const TextureState &get_texture(unsigned) const; + const TexUnitState &get_texture_unit(unsigned i) const { return texunits[i]; } + const BufferMap &get_buffers() const { return buffers; } + const BufferState &get_buffer(unsigned) const; + const BufferState *get_current_buffer(GLenum) const; + const ArrayState &get_array(GLenum) const; + const ArrayState &get_texture_coord_array(unsigned) const; + const ArrayState &get_attrib_array(unsigned) const; +private: + bool &get_boolean_state(GLenum); + TextureState *get_current_texture(GLenum); + BufferState *get_current_buffer(GLenum); + void set_current_texture(GLenum, unsigned); + void set_current_buffer(GLenum, unsigned); + + static void glEnableClientState(void *, GLenum); + static void glDisableClientState(void *, GLenum); + static void glEnableVertexAttribArray(void *, unsigned); + static void glDisableVertexAttribArray(void *, unsigned); + + static void glColor3f(void *, float, float, float); + static void glColor4f(void *, float, float, float, float); + static void glNormal3f(void *, float, float, float); + static void glTexCoord1f(void *, float); + static void glTexCoord2f(void *, float, float); + static void glTexCoord3f(void *, float, float, float); + static void glTexCoord4f(void *, float, float, float, float); + static void glMultiTexCoord4f(void *, unsigned, float, float, float, float); + + static void glActiveTexture(void *, unsigned); + static void glBindTexture(void *, GLenum, unsigned); + static void glTexImage2D(void *, GLenum, int, int, int, int, int, GLenum, GLenum, const void *); + static void glTexParameteri(void *, GLenum, GLenum, int); + static void glTexParameteriv(void *, GLenum, GLenum, const int *); + static void glDeleteTextures(void *, int, const unsigned *); + + static void glVertexPointer(void *, int, GLenum, int, const void *); + static void glNormalPointer(void *, GLenum, int, const void *); + static void glColorPointer(void *, int, GLenum, int, const void *); + static void glClientActiveTexture(void *, unsigned); + static void glTexCoordPointer(void *, int, GLenum, int, const void *); + static void glVertexAttribPointer(void *, unsigned, int, GLenum, int, int, const void *); + + static void glBindBuffer(void *, GLenum, unsigned); + static void glBufferData(void *, GLenum, int, const void *, GLenum); + static void glBufferSubData(void *, GLenum, int, int, const void *); + static void glDeleteBuffers(void *, int, const unsigned *); +}; + +#endif diff --git a/flavors/gl/source/inspector.cpp b/flavors/gl/source/inspector.cpp new file mode 100644 index 0000000..912214d --- /dev/null +++ b/flavors/gl/source/inspector.cpp @@ -0,0 +1,216 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include "enums.h" +#include "gldbg.h" +#include "inspector.h" + +using namespace std; +using namespace Msp; + +Inspector::Inspector(GlDbg &dbg) +{ + CommandInterpreter &cmd_interp = dbg.get_command_interpreter(); + + cmd_interp.register_command("state", this, &Inspector::cmd_state) + .set_help("Inspects general GL state", + "state vertex\n" + " Print current vertex attributes\n\n" + "state bind\n" + " Show current bindings\n"); + + cmd_interp.register_command("texture", this, &Inspector::cmd_texture) + .set_help("Inspect texture state", + "texture\n" + " Lists texture objects\n\n" + "texture ID\n" + " Print information about a texture object\n"); + + cmd_interp.register_command("buffer", this, &Inspector::cmd_buffer) + .set_help("Inspect buffer object state", + "buffer\n" + " Lists buffer objects\n\n" + "buffer ID\n" + " Print information about a buffer object\n"); +} + +void Inspector::decode(const char *data, unsigned len) +{ + state.decode(data, len); +} + +void Inspector::cmd_state(const string &args) +{ + const GlState &glstate = state; + if(args=="vertex") + { + IO::print("Current vertex attributes:\n"); + const Vector4 &color = glstate.get_color(); + IO::print(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a); + for(unsigned i=0; i<8; ++i) + { + const Vector4 &texcoord = glstate.get_texcoord(i); + IO::print(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q); + } + const Vector3 &normal = glstate.get_normal(); + IO::print(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z); + } + else if(args=="bind") + { + IO::print("Current bindings:\n"); + for(unsigned i=0; i<8; ++i) + { + IO::print(" Texture unit %d:\n", i); + const TexUnitState &unit = glstate.get_texture_unit(i); + IO::print(" GL_TEXTURE_2D: %s\n", unit.describe_binding(GL_TEXTURE_2D)); + IO::print(" GL_TEXTURE_3D: %s\n", unit.describe_binding(GL_TEXTURE_3D)); + } + IO::print(" Buffers:\n"); + const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER); + IO::print(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); + buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER); + IO::print(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); + } + else + throw InvalidParameterValue("Invalid or missing argument"); +} + +void Inspector::cmd_texture(const string &args) +{ + if(args.empty()) + { + const map &textures = state.get_textures(); + IO::print("%d texture objects:\n", textures.size()); + for(map::const_iterator i = textures.begin(); i!=textures.end(); ++i) + { + const TextureState &tex = i->second; + IO::print(" %d: %s, %d images\n", i->first, tex.describe(), tex.images.size()); + } + } + else + { + unsigned id = lexical_cast(args); + const TextureState &tex = state.get_texture(id); + IO::print("Texture object %d\n", id); + IO::print(" Target: %s\n", describe_enum(tex.target, "TextureTarget")); + IO::print(" Images:\n"); + for(unsigned i=0; ifirst, i->second.describe()); + } + else + { + unsigned id = lexical_cast(args); + const BufferState &buf = state.get_buffer(id); + IO::print("Buffer %d:\n", id); + IO::print(" Size: %d bytes\n", buf.size); + IO::print(" Usage: %s\n", describe_enum(buf.usage, "")); + if(buf.content.stride) + { + IO::print(" Stride: %d bytes\n", buf.content.stride); + + IO::print(" Arrays:\n"); + const vector &arrays = buf.content.arrays; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(i->kind) + IO::print(" %2d: %s, %d %s\n", i->offset, + describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType")); + else + IO::print(" %2d: Attrib %d, %d %s\n", i->offset, + i->index, i->size, describe_enum(i->type, "DataType")); + } + + IO::print(" Data:\n"); + string header; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(!header.empty()) + header += " | "; + + string label; + if(i->kind==GL_VERTEX_ARRAY) + label = "Vertex"; + else if(i->kind==GL_NORMAL_ARRAY) + label = "Normal"; + else if(i->kind==GL_COLOR_ARRAY) + label = "Color"; + else if(i->kind==GL_TEXTURE_COORD_ARRAY) + { + if(i->size==1) + label = "TexC"; + else + label = "TexCoord"; + } + else if(!i->kind) + { + if(i->size==1) + label = format("A %d", i->index); + else + label = format("Attrib %d", i->index); + } + + unsigned width = i->size; + if(i->type==GL_FLOAT) + width *= 5; + else if(i->type==GL_UNSIGNED_BYTE) + width *= 3; + width += i->size-1; + + header.append((width-label.size())/2, ' '); + header += label; + header.append((width-label.size()+1)/2, ' '); + } + IO::print(" %s\n", header); + + unsigned n_verts = buf.size/buf.content.stride; + for(unsigned i=0; i::const_iterator j=arrays.begin(); j!=arrays.end(); ++j) + { + if(!line.empty()) + line += " |"; + + const char *base = vertex+j->offset; + for(unsigned k=0; ksize; ++k) + { + if(j->type==GL_FLOAT) + line += format(" %5.2f", *(reinterpret_cast(base)+k)); + else if(j->type==GL_UNSIGNED_BYTE) + line += format(" %3u", *(reinterpret_cast(base)+k)); + } + } + + IO::print("%3d:%s\n", i, line); + } + } + } +} diff --git a/flavors/gl/source/inspector.h b/flavors/gl/source/inspector.h new file mode 100644 index 0000000..91e2a46 --- /dev/null +++ b/flavors/gl/source/inspector.h @@ -0,0 +1,29 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef INSPECTOR_H_ +#define INSPECTOR_H_ + +#include "glstate.h" +#include "tool.h" + +class Inspector: public RegisteredTool +{ +private: + GlState state; + +public: + Inspector(GlDbg &); + + virtual void decode(const char *, unsigned); +private: + void cmd_state(const std::string &); + void cmd_texture(const std::string &); + void cmd_buffer(const std::string &); +}; + +#endif diff --git a/flavors/gl/source/profiler.cpp b/flavors/gl/source/profiler.cpp new file mode 100644 index 0000000..37caa68 --- /dev/null +++ b/flavors/gl/source/profiler.cpp @@ -0,0 +1,110 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include +#include +#include "gldbg.h" +#include "profiler.h" + +using namespace std; +using namespace Msp; + +Profiler::Profiler(GlDbg &dbg): + decoder(gldecoder_new(this, 0)), + enabled(false) +{ + dbg.get_command_interpreter().register_command("profile", this, &Profiler::cmd_profile) + .set_help("Profiles GL usage and performance", + "profile {on|off}\n" + " Enables or disables profiling\n"); + + decoder->glDrawArrays = glDrawArrays; + decoder->glDrawElements = glDrawElements; + decoder->glDrawRangeElements = glDrawRangeElements; + decoder->glXSwapBuffers = glXSwapBuffers; +} + +void Profiler::decode(const char *data, unsigned len) +{ + if(enabled) + gldecoder_decode(decoder, data, len); +} + +void Profiler::cmd_profile(const string &args) +{ + if(args.empty() || args=="on") + { + enabled = true; + frames = 0; + draw_calls = 0; + vertices = 0; + triangles = 0; + start = Msp::Time::now(); + } + else if(args=="off") + enabled = false; + else + throw InvalidParameterValue("Invalid argument"); +} + +void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count) +{ + glDrawElements(user_data, mode, count, 0, 0); +} + +void Profiler::glDrawElements(void *user_data, GLenum mode, int count, GLenum, const void *) +{ + Profiler *self = reinterpret_cast(user_data); + + ++self->draw_calls; + self->vertices += count; + + switch(mode) + { + case GL_TRIANGLES: + self->triangles += count/3; + break; + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + if(count>2) + self->triangles += count-2; + break; + case GL_QUADS: + self->triangles += count/4; + break; + case GL_QUAD_STRIP: + if(count>3) + self->triangles += count/2-1; + break; + } +} + +void Profiler::glDrawRangeElements(void *user_data, GLenum mode, unsigned, unsigned, int count, GLenum type, const void *data) +{ + glDrawElements(user_data, mode, count, type, data); +} + +void Profiler::glXSwapBuffers(void *user_data, Display *, GLXDrawable) +{ + Profiler *self = reinterpret_cast(user_data); + + IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles); + self->draw_calls = 0; + self->vertices = 0; + self->triangles = 0; + + ++self->frames; + Msp::Time::TimeStamp t = Msp::Time::now(); + Msp::Time::TimeDelta dt = t-self->start; + if(dt>Msp::Time::sec) + { + Msp::IO::print("%d frames in %s seconds\n", self->frames, dt); + self->start = t; + self->frames = 0; + } +} diff --git a/flavors/gl/source/profiler.h b/flavors/gl/source/profiler.h new file mode 100644 index 0000000..4d5c5a8 --- /dev/null +++ b/flavors/gl/source/profiler.h @@ -0,0 +1,39 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef PROFILER_H_ +#define PROFILER_H_ + +#include +#include "gldecoder.h" +#include "tool.h" + +class Profiler: public RegisteredTool +{ +private: + GlDecoder *decoder; + bool enabled; + Msp::Time::TimeStamp start; + unsigned frames; + unsigned draw_calls; + unsigned vertices; + unsigned triangles; + +public: + Profiler(GlDbg &); + + virtual void decode(const char *, unsigned); +private: + void cmd_profile(const std::string &); + + static void glDrawArrays(void *, GLenum, int, int); + static void glDrawElements(void *, GLenum, int, GLenum, const void *); + static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *); + static void glXSwapBuffers(void *, Display *, GLXDrawable); +}; + +#endif diff --git a/flavors/gl/source/texturestate.cpp b/flavors/gl/source/texturestate.cpp new file mode 100644 index 0000000..187707c --- /dev/null +++ b/flavors/gl/source/texturestate.cpp @@ -0,0 +1,152 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include "enums.h" +#include "texturestate.h" + +using namespace std; +using namespace Msp; + +TexImageState::TexImageState(): + width(0), + height(0), + depth(0), + internal_format(0) +{ } + +void TexImageState::set_2d(GLenum ifmt, unsigned wd, unsigned ht) +{ + width = wd; + height = ht; + depth = 0; + internal_format = ifmt; +} + +string TexImageState::describe() const +{ + string descr = format("%d", width); + if(height) + { + descr += format("x%d", height); + if(depth) + descr += format("x%d", height); + } + descr += format(", %s", describe_enum(internal_format, "PixelFormat")); + return descr; +} + + +TextureState::TextureState(): + id(0), + target(0), + min_filter(GL_LINEAR_MIPMAP_LINEAR), + mag_filter(GL_LINEAR), + wrap_s(GL_REPEAT), + wrap_t(GL_REPEAT), + wrap_r(GL_REPEAT), + compare_mode(GL_NONE), + compare_func(GL_LEQUAL), + generate_mipmap(false) +{ } + +void TextureState::set_image_2d(unsigned level, GLenum ifmt, unsigned wd, unsigned ht) +{ + while(1) + { + if(images.size()<=level) + images.resize(level+1); + images[level].set_2d(ifmt, wd, ht); + + if(generate_mipmap) + { + if(wd==1 && ht==1) + break; + ++level; + if(wd>1) + wd /= 2; + if(ht>1) + ht /= 2; + } + else + break; + } +} + +void TextureState::set_parameter(GLenum pname, const int *values) +{ + if(pname==GL_TEXTURE_MIN_FILTER) + min_filter = values[0]; + else if(pname==GL_TEXTURE_MAG_FILTER) + mag_filter = values[0]; + else if(pname==GL_TEXTURE_WRAP_S) + wrap_s = values[0]; + else if(pname==GL_TEXTURE_WRAP_T) + wrap_t = values[0]; + else if(pname==GL_TEXTURE_WRAP_R) + wrap_r = values[0]; + else if(pname==GL_TEXTURE_COMPARE_MODE) + compare_mode = values[0]; + else if(pname==GL_TEXTURE_COMPARE_FUNC) + compare_func = values[0]; + else if(pname==GL_GENERATE_MIPMAP) + generate_mipmap = values[0]; +} + +string TextureState::describe() const +{ + string descr = describe_enum(target, "TextureTarget"); + if(images.empty()) + descr += ", undefined"; + else + descr += format(", %s", images.front().describe()); + return descr; +} + + +TexUnitState::TexUnitState(): + current_2d(0), + current_3d(0) +{ } + +void TexUnitState::set_current_texture(GLenum target, TextureState *tex) +{ + if(target==GL_TEXTURE_2D) + current_2d = tex; + else if(target==GL_TEXTURE_3D) + current_3d = tex; +} + +TextureState *TexUnitState::get_current_texture(GLenum target) +{ + if(target==GL_TEXTURE_2D) + return current_2d; + else if(target==GL_TEXTURE_3D) + return current_3d; + else + return 0; +} + +const TextureState *TexUnitState::get_current_texture(GLenum target) const +{ + return const_cast(this)->get_current_texture(target); +} + +string TexUnitState::describe_binding(GLenum target) const +{ + if(const TextureState *tex = get_current_texture(target)) + { + string descr = format("%d ", tex->id); + if(tex->images.empty()) + descr += "(undefined)"; + else + descr += format("(%s)", tex->images.front().describe()); + return descr; + } + else + return "None"; +} diff --git a/flavors/gl/source/texturestate.h b/flavors/gl/source/texturestate.h new file mode 100644 index 0000000..37cbfdd --- /dev/null +++ b/flavors/gl/source/texturestate.h @@ -0,0 +1,61 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef TEXTURESTATE_H_ +#define TEXTURESTATE_H_ + +#include +#include +#include "opengl.h" +#include "autoconstptr.h" + +struct TexImageState +{ + unsigned width; + unsigned height; + unsigned depth; + GLenum internal_format; + + TexImageState(); + void set_2d(GLenum, unsigned, unsigned); + std::string describe() const; +}; + +struct TextureState +{ + unsigned id; + GLenum target; + std::vector images; + GLenum min_filter; + GLenum mag_filter; + GLenum wrap_s; + GLenum wrap_t; + GLenum wrap_r; + GLenum compare_mode; + GLenum compare_func; + bool generate_mipmap; + + TextureState(); + void set_image_2d(unsigned, GLenum, unsigned, unsigned); + void set_parameter(GLenum, const int *); + std::string describe() const; +}; + +struct TexUnitState +{ + AutoConstPtr current_2d; + AutoConstPtr current_3d; + + TexUnitState(); + + void set_current_texture(GLenum, TextureState *); + TextureState *get_current_texture(GLenum); + const TextureState *get_current_texture(GLenum) const; + std::string describe_binding(GLenum) const; +}; + +#endif diff --git a/source/arraystate.cpp b/source/arraystate.cpp deleted file mode 100644 index 37db75a..0000000 --- a/source/arraystate.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include "arraystate.h" -#include "bufferstate.h" - -ArrayState::ArrayState(): - kind(0), - index(0), - enabled(false), - size(4), - type(GL_FLOAT), - normalized(false), - stride(0), - buffer(0), - pointer(0) -{ } - -void ArrayState::set(unsigned s, GLenum t, bool n, unsigned r, BufferState *b, long p) -{ - size = s; - type = t; - stride = r; - normalized = n; - buffer = b; - pointer = p; - - if(buffer) - buffer->content.update(*this); -} diff --git a/source/arraystate.h b/source/arraystate.h deleted file mode 100644 index d755297..0000000 --- a/source/arraystate.h +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef ARRAYSTATE_H_ -#define ARRAYSTATE_H_ - -#include "opengl.h" - -struct BufferState; - -struct ArrayState -{ - GLenum kind; - unsigned index; - bool enabled; - unsigned size; - GLenum type; - bool normalized; - unsigned stride; - BufferState *buffer; - long pointer; - - ArrayState(); - void set(unsigned, GLenum, bool, unsigned, BufferState *, long); -}; - -#endif diff --git a/source/bufferstate.cpp b/source/bufferstate.cpp deleted file mode 100644 index 356e82b..0000000 --- a/source/bufferstate.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include -#include "arraystate.h" -#include "bufferstate.h" -#include "enums.h" - -using namespace std; -using namespace Msp; - -BufferContent::BufferContent(): - consistent(true), - stride(0) -{ } - -void BufferContent::update(const ArrayState &array) -{ - if(array.stride!=stride) - consistent = false; - - stride = array.stride; - - for(vector::iterator i=arrays.begin(); i!=arrays.end(); ++i) - if(i->kind==array.kind && i->index==array.index) - { - if(array.size!=i->size || array.type!=i->type || array.pointer!=i->offset) - { - consistent = false; - arrays.erase(i); - } - else - return; - - - break; - } - - vector::iterator place = arrays.end(); - for(vector::iterator i=arrays.begin(); i!=arrays.end(); ++i) - if(i->offset>array.pointer) - { - place = i; - break; - } - - arrays.insert(place, array); -} - -string BufferContent::describe() const -{ - if(arrays.empty()) - return "(unknown)"; - - string result; - for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) - { - char kind = '?'; - if(i->kind==GL_VERTEX_ARRAY) - kind = 'V'; - else if(i->kind==GL_NORMAL_ARRAY) - kind = 'N'; - else if(i->kind==GL_COLOR_ARRAY) - kind = 'C'; - else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0) - kind = 'T'; - - char type[3] = { '?', 0, 0 }; - if(i->type==GL_FLOAT) - type[0] = 'F'; - else if(i->type==GL_DOUBLE) - type[0] = 'D'; - else if(i->type==GL_INT || i->type==GL_UNSIGNED_INT) - type[0] = 'I'; - else if(i->type==GL_SHORT || i->type==GL_UNSIGNED_SHORT) - type[0] = 'S'; - else if(i->type==GL_BYTE || i->type==GL_UNSIGNED_BYTE) - type[0] = 'B'; - - if(i->type==GL_UNSIGNED_INT || i->type==GL_UNSIGNED_SHORT || i->type==GL_UNSIGNED_BYTE) - { - type[1] = type[0]; - type[0] = 'U'; - } - - if(!result.empty()) - result += '_'; - result += format("%c%d%s", kind, i->size, type); - } - - return result; -} - - -BufferContent::Array::Array(const ArrayState &a): - kind(a.kind), - index(a.index), - size(a.size), - type(a.type), - offset(a.pointer) -{ } - - -BufferState::BufferState(): - usage(GL_STATIC_DRAW), - size(0), - data(0) -{ } - -void BufferState::set_data(unsigned sz, const void *ptr, GLenum use) -{ - usage = use; - size = sz; - delete[] data; - data = new char[size]; - if(ptr) - set_sub_data(0, size, ptr); - content = BufferContent(); -} - -void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr) -{ - if(data && off+sz<=size) - { - const char *cptr = reinterpret_cast(ptr); - copy(cptr, cptr+sz, data+off); - } -} - -string BufferState::describe() const -{ - if(content.stride) - return format("%s, %d vertices (%d bytes), %s", - content.describe(), size/content.stride, size, describe_enum(usage, "")); - else - return format("%d bytes, %s", size, describe_enum(usage, "")); -} diff --git a/source/bufferstate.h b/source/bufferstate.h deleted file mode 100644 index c3f504b..0000000 --- a/source/bufferstate.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef BUFFERSTATE_H_ -#define BUFFERSTATE_H_ - -#include -#include -#include "opengl.h" - -struct ArrayState; - -struct BufferContent -{ - struct Array - { - GLenum kind; - unsigned index; - unsigned size; - GLenum type; - int offset; - - Array(const ArrayState &); - }; - - bool consistent; - unsigned stride; - std::vector arrays; - - BufferContent(); - void update(const ArrayState &); - std::string describe() const; -}; - -struct BufferState -{ - unsigned id; - GLenum target; - GLenum usage; - unsigned size; - char *data; - BufferContent content; - - BufferState(); - void set_data(unsigned, const void *, GLenum); - void set_sub_data(unsigned, unsigned, const void *); - std::string describe() const; -}; - -#endif diff --git a/source/glstate.cpp b/source/glstate.cpp deleted file mode 100644 index 1459324..0000000 --- a/source/glstate.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include -#include "glstate.h" - -using namespace std; -using namespace Msp; - -namespace { - -template -float normalize(T v); - -template<> -float normalize(GLubyte v) -{ return v/255.0f; } - -template<> -float normalize(GLbyte v) -{ return (2*v+1)/255.0f; } - -template -void wrap_normalized(void *user_data, T v0) -{ func(user_data, v0); } - -template -void wrap_normalized(void *user_data, T v0, T v1) -{ func(user_data, v0, v1); } - -template -void wrap_normalized(void *user_data, T v0, T v1, T v2) -{ func(user_data, v0, v1, v2); } - -template -void wrap_normalized(void *user_data, T v0, T v1, T v2, T v3) -{ func(user_data, v0, v1, v2, v3); } - -template -void wrap_array(void *user_data, const T *v) -{ func(user_data, v[0]); } - -template -void wrap_array(void *user_data, const T *v) -{ func(user_data, v[0], v[1]); } - -template -void wrap_array(void *user_data, const T *v) -{ func(user_data, v[0], v[1], v[2]); } - -template -void wrap_array(void *user_data, const T *v) -{ func(user_data, v[0], v[1], v[2], v[3]); } - -} - - -Vector3::Vector3(): - x(0), y(0), z(0) -{ } - - -Vector4::Vector4(): - x(0), y(0), z(0), w(1) -{ } - - -GlState::GlState(): - decoder(gldecoder_new(this, NULL)), - active_tex(0), - client_active_tex(0), - array_buffer(0), - element_buffer(0) -{ - vertex_array.kind = GL_VERTEX_ARRAY; - normal_array.kind = GL_NORMAL_ARRAY; - color_array.kind = GL_COLOR_ARRAY; - for(unsigned i=0; i<8; ++i) - { - texcoord_arrays[i].kind = GL_TEXTURE_COORD_ARRAY; - texcoord_arrays[i].index = i; - } - - decoder->glColor3ub = wrap_normalized; - decoder->glColor3ubv = wrap_array >; - decoder->glColor4ub = wrap_normalized; - decoder->glColor4ubv = wrap_array >; - decoder->glColor3f = glColor3f; - decoder->glColor3fv = wrap_array; - decoder->glColor4f = glColor4f; - decoder->glColor4fv = wrap_array; - decoder->glTexCoord1f = glTexCoord1f; - decoder->glTexCoord1fv = wrap_array; - decoder->glTexCoord2f = glTexCoord2f; - decoder->glTexCoord2fv = wrap_array; - decoder->glTexCoord3f = glTexCoord3f; - decoder->glTexCoord3fv = wrap_array; - decoder->glTexCoord4f = glTexCoord4f; - decoder->glTexCoord4fv = wrap_array; - decoder->glNormal3f = glNormal3f; - decoder->glNormal3fv = wrap_array; - - decoder->glActiveTexture = glActiveTexture; - decoder->glActiveTextureARB = glActiveTexture; - decoder->glBindTexture = glBindTexture; - decoder->glTexImage2D = glTexImage2D; - decoder->glTexParameteri = glTexParameteri; - decoder->glTexParameteriv = glTexParameteriv; - decoder->glDeleteTextures = glDeleteTextures; - - decoder->glVertexPointer = glVertexPointer; - decoder->glNormalPointer = glNormalPointer; - decoder->glColorPointer = glColorPointer; - decoder->glClientActiveTexture = glClientActiveTexture; - decoder->glClientActiveTextureARB = glClientActiveTexture; - decoder->glTexCoordPointer = glTexCoordPointer; - - decoder->glBindBuffer = glBindBuffer; - decoder->glBindBufferARB = glBindBuffer; - decoder->glBufferData = glBufferData; - decoder->glBufferDataARB = glBufferData; - decoder->glBufferSubData = glBufferSubData; - decoder->glBufferSubDataARB = glBufferSubData; - decoder->glDeleteBuffers = glDeleteBuffers; - decoder->glDeleteBuffersARB = glDeleteBuffers; -} - -GlState::~GlState() -{ - gldecoder_delete(decoder); -} - -int GlState::decode(const char *data, unsigned len) -{ - return gldecoder_decode(decoder, data, len); -} - -const TextureState &GlState::get_texture(unsigned id) const -{ - TextureMap::const_iterator i = textures.find(id); - if(i==textures.end()) - throw KeyError("Unknown texture"); - return i->second; -} - -const BufferState &GlState::get_buffer(unsigned id) const -{ - BufferMap::const_iterator i = buffers.find(id); - if(i==buffers.end()) - throw KeyError("Unknown buffer"); - return i->second; -} - -const BufferState *GlState::get_current_buffer(GLenum target) const -{ - return const_cast(this)->get_current_buffer(target); -} - -bool &GlState::get_boolean_state(GLenum state) -{ - if(state==GL_VERTEX_ARRAY) - return vertex_array.enabled; - else if(state==GL_NORMAL_ARRAY) - return normal_array.enabled; - else if(state==GL_COLOR_ARRAY) - return color_array.enabled; - else if(state==GL_TEXTURE_COORD_ARRAY) - return texcoord_arrays[client_active_tex].enabled; - - static bool dummy; - return dummy; -} - -TextureState *GlState::get_current_texture(GLenum target) -{ - return texunits[active_tex].get_current_texture(target); -} - -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; - 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 -{ - return texcoord_arrays[index]; -} - -const ArrayState &GlState::get_attrib_array(unsigned index) const -{ - map::const_iterator i = attrib_arrays.find(index); - if(i!=attrib_arrays.end()) - return i->second; - - // XXX Return a dummy? - throw KeyError("Unknown attribute array"); -} - -void GlState::set_current_texture(GLenum target, unsigned id) -{ - TexUnitState &unit = texunits[active_tex]; - TextureState *tex = 0; - if(id) - { - tex = &textures[id]; - if(!tex->id) - { - tex->id = id; - tex->target = target; - } - else if(tex->target!=target) - return; - } - unit.set_current_texture(target, tex); -} - -void GlState::set_current_buffer(GLenum target, unsigned id) -{ - BufferState *buf = 0; - if(id) - { - buf = &buffers[id]; - if(!buf->id) - buf->id = id; - } - - if(target==GL_ARRAY_BUFFER) - array_buffer = buf; - else if(target==GL_ELEMENT_ARRAY_BUFFER) - element_buffer = buf; -} - -// Boolean state - -void GlState::glEnableClientState(void *user_data, GLenum state) -{ - reinterpret_cast(user_data)->get_boolean_state(state) = true; -} - -void GlState::glDisableClientState(void *user_data, GLenum state) -{ - reinterpret_cast(user_data)->get_boolean_state(state) = false; -} - -void GlState::glEnableVertexAttribArray(void *user_data, unsigned index) -{ - reinterpret_cast(user_data)->attrib_arrays[index].enabled = true; -} - -void GlState::glDisableVertexAttribArray(void *user_data, unsigned index) -{ - reinterpret_cast(user_data)->attrib_arrays[index].enabled = false; -} - -// Vertex attributes - -void GlState::glColor3f(void *user_data, float r, float g, float b) -{ glColor4f(user_data, r, g, b, 1.0f); } - -void GlState::glColor4f(void *user_data, float r, float g, float b, float a) -{ - Vector4 &color = reinterpret_cast(user_data)->color; - color.r = r; - color.g = g; - color.b = b; - color.a = a; -} - -void GlState::glNormal3f(void *user_data, float x, float y, float z) -{ - Vector3 &normal = reinterpret_cast(user_data)->normal; - normal.x = x; - normal.y = y; - normal.z = z; -} - -void GlState::glTexCoord1f(void *user_data, float s) -{ glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f); } - -void GlState::glTexCoord2f(void *user_data, float s, float t) -{ glTexCoord4f(user_data, s, t, 0.0f, 1.0f); } - -void GlState::glTexCoord3f(void *user_data, float s, float t, float p) -{ glTexCoord4f(user_data, s, t, p, 1.0f); } - -void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q) -{ - unsigned index = reinterpret_cast(user_data)->active_tex; - glMultiTexCoord4f(user_data, index, s, t, p, q); -} - -void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q) -{ - Vector4 &texcoord = reinterpret_cast(user_data)->texcoord[index]; - texcoord.s = s; - texcoord.t = t; - texcoord.p = p; - texcoord.q = q; -} - -// Textures - -void GlState::glActiveTexture(void *user_data, unsigned index) -{ - reinterpret_cast(user_data)->active_tex = index-GL_TEXTURE0; -} - -void GlState::glBindTexture(void *user_data, GLenum target, unsigned id) -{ - reinterpret_cast(user_data)->set_current_texture(target, id); -} - -void GlState::glTexImage2D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int, GLenum, GLenum, const void *) -{ - if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) - tex->set_image_2d(level, ifmt, width, height); -} - -void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value) -{ glTexParameteriv(user_data, target, param, &value); } - -void GlState::glTexParameteriv(void *user_data, GLenum target, GLenum param, const int *values) -{ - if(TextureState *tex = reinterpret_cast(user_data)->get_current_texture(target)) - tex->set_parameter(param, values); -} - -void GlState::glDeleteTextures(void *user_data, int count, const unsigned *ids) -{ - for(int i=0; i(user_data)->textures.erase(ids[i]); -} - -// Vertex arrays - -void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data) -{ - GlState *self = reinterpret_cast(user_data); - self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast(data)); -} - -void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data) -{ - GlState *self = reinterpret_cast(user_data); - self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast(data)); -} - -void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data) -{ - GlState *self = reinterpret_cast(user_data); - self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast(data)); -} - -void GlState::glClientActiveTexture(void *user_data, unsigned index) -{ - reinterpret_cast(user_data)->client_active_tex = index-GL_TEXTURE0; -} - -void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data) -{ - GlState *self = reinterpret_cast(user_data); - self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast(data)); -} - -void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, int norm, int stride, const void *data) -{ - GlState *self = reinterpret_cast(user_data); - self->attrib_arrays[index].set(size, type, norm, stride, self->array_buffer, reinterpret_cast(data)); -} - -// Buffer objects - -void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id) -{ reinterpret_cast(user_data)->set_current_buffer(target, id); } - -void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage) -{ - if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) - buf->set_data(size, data, usage); -} - -void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data) -{ - if(BufferState *buf = reinterpret_cast(user_data)->get_current_buffer(target)) - buf->set_sub_data(offset, size, data); -} - -void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids) -{ - for(int i=0; i(user_data)->buffers.erase(ids[i]); -} diff --git a/source/glstate.h b/source/glstate.h deleted file mode 100644 index 86cc538..0000000 --- a/source/glstate.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef GLSTATE_H_ -#define GLSTATE_H_ - -#include -#include -#include "arraystate.h" -#include "bufferstate.h" -#include "gldecoder.h" -#include "texturestate.h" - -struct Vector3 -{ - float x, y, z; - - Vector3(); -}; - -struct Vector4 -{ - union { float x, r, s; }; - union { float y, g, t; }; - union { float z, b, p; }; - union { float w, a, q; }; - - Vector4(); -}; - -/** -Tracks OpenGL state based on the command stream. This class is essentially a -(partial) OpenGL implementation in itself. - -XXX Should determine the number of texture units the target implementation -actually supports. -*/ -class GlState -{ -public: - typedef std::map TextureMap; - typedef std::map BufferMap; - -private: - GlDecoder *decoder; - Vector4 color; - Vector4 texcoord[8]; - Vector3 normal; - unsigned active_tex; - unsigned client_active_tex; - TextureMap textures; - TexUnitState texunits[8]; - BufferMap buffers; - BufferState *array_buffer; - BufferState *element_buffer; - ArrayState vertex_array; - ArrayState normal_array; - ArrayState color_array; - ArrayState texcoord_arrays[8]; - std::map attrib_arrays; - -public: - GlState(); - ~GlState(); - - int decode(const char *, unsigned); - const Vector4 &get_color() const { return color; } - const Vector4 &get_texcoord(unsigned i) const { return texcoord[i]; } - const Vector3 &get_normal() const { return normal; } - const TextureMap &get_textures() const { return textures; } - const TextureState &get_texture(unsigned) const; - const TexUnitState &get_texture_unit(unsigned i) const { return texunits[i]; } - const BufferMap &get_buffers() const { return buffers; } - const BufferState &get_buffer(unsigned) const; - const BufferState *get_current_buffer(GLenum) const; - const ArrayState &get_array(GLenum) const; - const ArrayState &get_texture_coord_array(unsigned) const; - const ArrayState &get_attrib_array(unsigned) const; -private: - bool &get_boolean_state(GLenum); - TextureState *get_current_texture(GLenum); - BufferState *get_current_buffer(GLenum); - void set_current_texture(GLenum, unsigned); - void set_current_buffer(GLenum, unsigned); - - static void glEnableClientState(void *, GLenum); - static void glDisableClientState(void *, GLenum); - static void glEnableVertexAttribArray(void *, unsigned); - static void glDisableVertexAttribArray(void *, unsigned); - - static void glColor3f(void *, float, float, float); - static void glColor4f(void *, float, float, float, float); - static void glNormal3f(void *, float, float, float); - static void glTexCoord1f(void *, float); - static void glTexCoord2f(void *, float, float); - static void glTexCoord3f(void *, float, float, float); - static void glTexCoord4f(void *, float, float, float, float); - static void glMultiTexCoord4f(void *, unsigned, float, float, float, float); - - static void glActiveTexture(void *, unsigned); - static void glBindTexture(void *, GLenum, unsigned); - static void glTexImage2D(void *, GLenum, int, int, int, int, int, GLenum, GLenum, const void *); - static void glTexParameteri(void *, GLenum, GLenum, int); - static void glTexParameteriv(void *, GLenum, GLenum, const int *); - static void glDeleteTextures(void *, int, const unsigned *); - - static void glVertexPointer(void *, int, GLenum, int, const void *); - static void glNormalPointer(void *, GLenum, int, const void *); - static void glColorPointer(void *, int, GLenum, int, const void *); - static void glClientActiveTexture(void *, unsigned); - static void glTexCoordPointer(void *, int, GLenum, int, const void *); - static void glVertexAttribPointer(void *, unsigned, int, GLenum, int, int, const void *); - - static void glBindBuffer(void *, GLenum, unsigned); - static void glBufferData(void *, GLenum, int, const void *, GLenum); - static void glBufferSubData(void *, GLenum, int, int, const void *); - static void glDeleteBuffers(void *, int, const unsigned *); -}; - -#endif diff --git a/source/inspector.cpp b/source/inspector.cpp deleted file mode 100644 index 912214d..0000000 --- a/source/inspector.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include -#include "enums.h" -#include "gldbg.h" -#include "inspector.h" - -using namespace std; -using namespace Msp; - -Inspector::Inspector(GlDbg &dbg) -{ - CommandInterpreter &cmd_interp = dbg.get_command_interpreter(); - - cmd_interp.register_command("state", this, &Inspector::cmd_state) - .set_help("Inspects general GL state", - "state vertex\n" - " Print current vertex attributes\n\n" - "state bind\n" - " Show current bindings\n"); - - cmd_interp.register_command("texture", this, &Inspector::cmd_texture) - .set_help("Inspect texture state", - "texture\n" - " Lists texture objects\n\n" - "texture ID\n" - " Print information about a texture object\n"); - - cmd_interp.register_command("buffer", this, &Inspector::cmd_buffer) - .set_help("Inspect buffer object state", - "buffer\n" - " Lists buffer objects\n\n" - "buffer ID\n" - " Print information about a buffer object\n"); -} - -void Inspector::decode(const char *data, unsigned len) -{ - state.decode(data, len); -} - -void Inspector::cmd_state(const string &args) -{ - const GlState &glstate = state; - if(args=="vertex") - { - IO::print("Current vertex attributes:\n"); - const Vector4 &color = glstate.get_color(); - IO::print(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a); - for(unsigned i=0; i<8; ++i) - { - const Vector4 &texcoord = glstate.get_texcoord(i); - IO::print(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q); - } - const Vector3 &normal = glstate.get_normal(); - IO::print(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z); - } - else if(args=="bind") - { - IO::print("Current bindings:\n"); - for(unsigned i=0; i<8; ++i) - { - IO::print(" Texture unit %d:\n", i); - const TexUnitState &unit = glstate.get_texture_unit(i); - IO::print(" GL_TEXTURE_2D: %s\n", unit.describe_binding(GL_TEXTURE_2D)); - IO::print(" GL_TEXTURE_3D: %s\n", unit.describe_binding(GL_TEXTURE_3D)); - } - IO::print(" Buffers:\n"); - const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER); - IO::print(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); - buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER); - IO::print(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); - } - else - throw InvalidParameterValue("Invalid or missing argument"); -} - -void Inspector::cmd_texture(const string &args) -{ - if(args.empty()) - { - const map &textures = state.get_textures(); - IO::print("%d texture objects:\n", textures.size()); - for(map::const_iterator i = textures.begin(); i!=textures.end(); ++i) - { - const TextureState &tex = i->second; - IO::print(" %d: %s, %d images\n", i->first, tex.describe(), tex.images.size()); - } - } - else - { - unsigned id = lexical_cast(args); - const TextureState &tex = state.get_texture(id); - IO::print("Texture object %d\n", id); - IO::print(" Target: %s\n", describe_enum(tex.target, "TextureTarget")); - IO::print(" Images:\n"); - for(unsigned i=0; ifirst, i->second.describe()); - } - else - { - unsigned id = lexical_cast(args); - const BufferState &buf = state.get_buffer(id); - IO::print("Buffer %d:\n", id); - IO::print(" Size: %d bytes\n", buf.size); - IO::print(" Usage: %s\n", describe_enum(buf.usage, "")); - if(buf.content.stride) - { - IO::print(" Stride: %d bytes\n", buf.content.stride); - - IO::print(" Arrays:\n"); - const vector &arrays = buf.content.arrays; - for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) - { - if(i->kind) - IO::print(" %2d: %s, %d %s\n", i->offset, - describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType")); - else - IO::print(" %2d: Attrib %d, %d %s\n", i->offset, - i->index, i->size, describe_enum(i->type, "DataType")); - } - - IO::print(" Data:\n"); - string header; - for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) - { - if(!header.empty()) - header += " | "; - - string label; - if(i->kind==GL_VERTEX_ARRAY) - label = "Vertex"; - else if(i->kind==GL_NORMAL_ARRAY) - label = "Normal"; - else if(i->kind==GL_COLOR_ARRAY) - label = "Color"; - else if(i->kind==GL_TEXTURE_COORD_ARRAY) - { - if(i->size==1) - label = "TexC"; - else - label = "TexCoord"; - } - else if(!i->kind) - { - if(i->size==1) - label = format("A %d", i->index); - else - label = format("Attrib %d", i->index); - } - - unsigned width = i->size; - if(i->type==GL_FLOAT) - width *= 5; - else if(i->type==GL_UNSIGNED_BYTE) - width *= 3; - width += i->size-1; - - header.append((width-label.size())/2, ' '); - header += label; - header.append((width-label.size()+1)/2, ' '); - } - IO::print(" %s\n", header); - - unsigned n_verts = buf.size/buf.content.stride; - for(unsigned i=0; i::const_iterator j=arrays.begin(); j!=arrays.end(); ++j) - { - if(!line.empty()) - line += " |"; - - const char *base = vertex+j->offset; - for(unsigned k=0; ksize; ++k) - { - if(j->type==GL_FLOAT) - line += format(" %5.2f", *(reinterpret_cast(base)+k)); - else if(j->type==GL_UNSIGNED_BYTE) - line += format(" %3u", *(reinterpret_cast(base)+k)); - } - } - - IO::print("%3d:%s\n", i, line); - } - } - } -} diff --git a/source/inspector.h b/source/inspector.h deleted file mode 100644 index 91e2a46..0000000 --- a/source/inspector.h +++ /dev/null @@ -1,29 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef INSPECTOR_H_ -#define INSPECTOR_H_ - -#include "glstate.h" -#include "tool.h" - -class Inspector: public RegisteredTool -{ -private: - GlState state; - -public: - Inspector(GlDbg &); - - virtual void decode(const char *, unsigned); -private: - void cmd_state(const std::string &); - void cmd_texture(const std::string &); - void cmd_buffer(const std::string &); -}; - -#endif diff --git a/source/profiler.cpp b/source/profiler.cpp deleted file mode 100644 index 37caa68..0000000 --- a/source/profiler.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include -#include -#include -#include "gldbg.h" -#include "profiler.h" - -using namespace std; -using namespace Msp; - -Profiler::Profiler(GlDbg &dbg): - decoder(gldecoder_new(this, 0)), - enabled(false) -{ - dbg.get_command_interpreter().register_command("profile", this, &Profiler::cmd_profile) - .set_help("Profiles GL usage and performance", - "profile {on|off}\n" - " Enables or disables profiling\n"); - - decoder->glDrawArrays = glDrawArrays; - decoder->glDrawElements = glDrawElements; - decoder->glDrawRangeElements = glDrawRangeElements; - decoder->glXSwapBuffers = glXSwapBuffers; -} - -void Profiler::decode(const char *data, unsigned len) -{ - if(enabled) - gldecoder_decode(decoder, data, len); -} - -void Profiler::cmd_profile(const string &args) -{ - if(args.empty() || args=="on") - { - enabled = true; - frames = 0; - draw_calls = 0; - vertices = 0; - triangles = 0; - start = Msp::Time::now(); - } - else if(args=="off") - enabled = false; - else - throw InvalidParameterValue("Invalid argument"); -} - -void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count) -{ - glDrawElements(user_data, mode, count, 0, 0); -} - -void Profiler::glDrawElements(void *user_data, GLenum mode, int count, GLenum, const void *) -{ - Profiler *self = reinterpret_cast(user_data); - - ++self->draw_calls; - self->vertices += count; - - switch(mode) - { - case GL_TRIANGLES: - self->triangles += count/3; - break; - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - if(count>2) - self->triangles += count-2; - break; - case GL_QUADS: - self->triangles += count/4; - break; - case GL_QUAD_STRIP: - if(count>3) - self->triangles += count/2-1; - break; - } -} - -void Profiler::glDrawRangeElements(void *user_data, GLenum mode, unsigned, unsigned, int count, GLenum type, const void *data) -{ - glDrawElements(user_data, mode, count, type, data); -} - -void Profiler::glXSwapBuffers(void *user_data, Display *, GLXDrawable) -{ - Profiler *self = reinterpret_cast(user_data); - - IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles); - self->draw_calls = 0; - self->vertices = 0; - self->triangles = 0; - - ++self->frames; - Msp::Time::TimeStamp t = Msp::Time::now(); - Msp::Time::TimeDelta dt = t-self->start; - if(dt>Msp::Time::sec) - { - Msp::IO::print("%d frames in %s seconds\n", self->frames, dt); - self->start = t; - self->frames = 0; - } -} diff --git a/source/profiler.h b/source/profiler.h deleted file mode 100644 index 4d5c5a8..0000000 --- a/source/profiler.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef PROFILER_H_ -#define PROFILER_H_ - -#include -#include "gldecoder.h" -#include "tool.h" - -class Profiler: public RegisteredTool -{ -private: - GlDecoder *decoder; - bool enabled; - Msp::Time::TimeStamp start; - unsigned frames; - unsigned draw_calls; - unsigned vertices; - unsigned triangles; - -public: - Profiler(GlDbg &); - - virtual void decode(const char *, unsigned); -private: - void cmd_profile(const std::string &); - - static void glDrawArrays(void *, GLenum, int, int); - static void glDrawElements(void *, GLenum, int, GLenum, const void *); - static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *); - static void glXSwapBuffers(void *, Display *, GLXDrawable); -}; - -#endif diff --git a/source/texturestate.cpp b/source/texturestate.cpp deleted file mode 100644 index 187707c..0000000 --- a/source/texturestate.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#include -#include "enums.h" -#include "texturestate.h" - -using namespace std; -using namespace Msp; - -TexImageState::TexImageState(): - width(0), - height(0), - depth(0), - internal_format(0) -{ } - -void TexImageState::set_2d(GLenum ifmt, unsigned wd, unsigned ht) -{ - width = wd; - height = ht; - depth = 0; - internal_format = ifmt; -} - -string TexImageState::describe() const -{ - string descr = format("%d", width); - if(height) - { - descr += format("x%d", height); - if(depth) - descr += format("x%d", height); - } - descr += format(", %s", describe_enum(internal_format, "PixelFormat")); - return descr; -} - - -TextureState::TextureState(): - id(0), - target(0), - min_filter(GL_LINEAR_MIPMAP_LINEAR), - mag_filter(GL_LINEAR), - wrap_s(GL_REPEAT), - wrap_t(GL_REPEAT), - wrap_r(GL_REPEAT), - compare_mode(GL_NONE), - compare_func(GL_LEQUAL), - generate_mipmap(false) -{ } - -void TextureState::set_image_2d(unsigned level, GLenum ifmt, unsigned wd, unsigned ht) -{ - while(1) - { - if(images.size()<=level) - images.resize(level+1); - images[level].set_2d(ifmt, wd, ht); - - if(generate_mipmap) - { - if(wd==1 && ht==1) - break; - ++level; - if(wd>1) - wd /= 2; - if(ht>1) - ht /= 2; - } - else - break; - } -} - -void TextureState::set_parameter(GLenum pname, const int *values) -{ - if(pname==GL_TEXTURE_MIN_FILTER) - min_filter = values[0]; - else if(pname==GL_TEXTURE_MAG_FILTER) - mag_filter = values[0]; - else if(pname==GL_TEXTURE_WRAP_S) - wrap_s = values[0]; - else if(pname==GL_TEXTURE_WRAP_T) - wrap_t = values[0]; - else if(pname==GL_TEXTURE_WRAP_R) - wrap_r = values[0]; - else if(pname==GL_TEXTURE_COMPARE_MODE) - compare_mode = values[0]; - else if(pname==GL_TEXTURE_COMPARE_FUNC) - compare_func = values[0]; - else if(pname==GL_GENERATE_MIPMAP) - generate_mipmap = values[0]; -} - -string TextureState::describe() const -{ - string descr = describe_enum(target, "TextureTarget"); - if(images.empty()) - descr += ", undefined"; - else - descr += format(", %s", images.front().describe()); - return descr; -} - - -TexUnitState::TexUnitState(): - current_2d(0), - current_3d(0) -{ } - -void TexUnitState::set_current_texture(GLenum target, TextureState *tex) -{ - if(target==GL_TEXTURE_2D) - current_2d = tex; - else if(target==GL_TEXTURE_3D) - current_3d = tex; -} - -TextureState *TexUnitState::get_current_texture(GLenum target) -{ - if(target==GL_TEXTURE_2D) - return current_2d; - else if(target==GL_TEXTURE_3D) - return current_3d; - else - return 0; -} - -const TextureState *TexUnitState::get_current_texture(GLenum target) const -{ - return const_cast(this)->get_current_texture(target); -} - -string TexUnitState::describe_binding(GLenum target) const -{ - if(const TextureState *tex = get_current_texture(target)) - { - string descr = format("%d ", tex->id); - if(tex->images.empty()) - descr += "(undefined)"; - else - descr += format("(%s)", tex->images.front().describe()); - return descr; - } - else - return "None"; -} diff --git a/source/texturestate.h b/source/texturestate.h deleted file mode 100644 index 37cbfdd..0000000 --- a/source/texturestate.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - -#ifndef TEXTURESTATE_H_ -#define TEXTURESTATE_H_ - -#include -#include -#include "opengl.h" -#include "autoconstptr.h" - -struct TexImageState -{ - unsigned width; - unsigned height; - unsigned depth; - GLenum internal_format; - - TexImageState(); - void set_2d(GLenum, unsigned, unsigned); - std::string describe() const; -}; - -struct TextureState -{ - unsigned id; - GLenum target; - std::vector images; - GLenum min_filter; - GLenum mag_filter; - GLenum wrap_s; - GLenum wrap_t; - GLenum wrap_r; - GLenum compare_mode; - GLenum compare_func; - bool generate_mipmap; - - TextureState(); - void set_image_2d(unsigned, GLenum, unsigned, unsigned); - void set_parameter(GLenum, const int *); - std::string describe() const; -}; - -struct TexUnitState -{ - AutoConstPtr current_2d; - AutoConstPtr current_3d; - - TexUnitState(); - - void set_current_texture(GLenum, TextureState *); - TextureState *get_current_texture(GLenum); - const TextureState *get_current_texture(GLenum) const; - std::string describe_binding(GLenum) const; -}; - -#endif