/* $Id$
This file is part of gldbg
-Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
" Gives detailed information on a command\n");
commands["exit"] = Command(&CommandInterpreter::cmd_exit,
"Ends the debugging session");
+ commands["quit"] = Command(&commands["exit"]);
commands["run"] = Command(&CommandInterpreter::cmd_run,
"Starts the program");
commands["trace"] = Command(&CommandInterpreter::cmd_trace,
"Traces GL function calls",
"trace\n"
- " Send trace output to stdout.\n"
+ " Send trace output to stdout.\n\n"
"trace FILE\n"
" Send trace output to FILE (- for stdout).\n\n"
"trace {off|on}\n"
"trace end\n"
" Terminate trace, closing the file.\n");
+ commands["profile"] = Command(&CommandInterpreter::cmd_profile,
+ "Profiles GL usage and performance",
+ "profile {on|off}\n"
+ " Enables or disables profiling\n");
+
commands["state"] = Command(&CommandInterpreter::cmd_state,
"Inspects general GL state",
"state vertex\n"
if(args.empty())
{
for(map<string, Command>::const_iterator i=commands.begin(); i!=commands.end(); ++i)
- IO::print("%-10s : %s\n", i->first, i->second.description);
+ if(!i->second.alias_for)
+ IO::print("%-10s : %s\n", i->first, i->second.description);
}
else
{
map<string, Command>::const_iterator i = commands.find(args);
if(i==commands.end())
throw KeyError("Unknown command", args);
- IO::print("%s : %s\n", i->first, i->second.description);
+
+ const Command *cmd = &i->second;
+ while(cmd->alias_for)
+ cmd = cmd->alias_for;
+
+ IO::print("%s : %s\n", i->first, cmd->description);
if(!i->second.help.empty())
- IO::print("\n%s", i->second.help);
+ IO::print("\n%s", cmd->help);
}
}
}
}
+void CommandInterpreter::cmd_profile(const string &args)
+{
+ Profiler &profiler = gldbg.get_profiler();
+ if(args.empty() || args=="on")
+ profiler.enable();
+ else if(args=="off")
+ profiler.disable();
+ else
+ throw InvalidParameterValue("Invalid argument");
+}
+
void CommandInterpreter::cmd_state(const string &args)
{
const GlState &glstate = gldbg.get_glstate();
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<BufferContent::Array> &arrays = buf.content.arrays;
+ for(vector<BufferContent::Array>::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<BufferContent::Array>::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<n_verts; ++i)
+ {
+ const char *vertex = buf.data+i*buf.content.stride;
+
+ string line;
+ for(vector<BufferContent::Array>::const_iterator j=arrays.begin(); j!=arrays.end(); ++j)
+ {
+ if(!line.empty())
+ line += " |";
+
+ const char *base = vertex+j->offset;
+ for(unsigned k=0; k<j->size; ++k)
+ {
+ if(j->type==GL_FLOAT)
+ line += format(" %5.2f", *(reinterpret_cast<const float *>(base)+k));
+ else if(j->type==GL_UNSIGNED_BYTE)
+ line += format(" %3u", *(reinterpret_cast<const unsigned char *>(base)+k));
+ }
+ }
+
+ IO::print("%3d:%s\n", i, line);
+ }
+ }
}
}
CommandInterpreter::Command::Command():
- func(0)
+ func(0),
+ alias_for(0)
+{ }
+
+CommandInterpreter::Command::Command(Command *cmd):
+ func(cmd->func),
+ alias_for(cmd)
{ }
CommandInterpreter::Command::Command(Func f, const string &d):
func(f),
- description(d)
+ description(d),
+ alias_for(0)
{ }
CommandInterpreter::Command::Command(Func f, const string &d, const string &h):
func(f),
description(d),
- help(h)
+ help(h),
+ alias_for(0)
{ }