Custom event loop for a visual debugger

I would like to be able to display graphical elements one by one from inside the loop of a function I’m debugging, e.g.:

void foo() {
...
  for (...) {
    ...
    display(e);
    waitForKey();
  }
...
}

I don’t see an easy way to do it by inheriting from AppBasic. Is there an example how to do it?

EDIT

A visual debugger is what I have in mind. Imagine analyzing/debugging a complex algorithm and instead of watching values of variables changing step by step in the debugger window, you have a purely graphical representation of your algorithm’s state updated each time you press F10 key to step forward.

Hi,

it sounds like you’re trying to debug graphics, hoping to figure out what’s going on by stepping through your code and look at the output in your window. However, this is not how things work. Your code runs on the CPU and all draw commands are collected and then sent to the GPU. If you step through your code, your window remains blank. You can force the GPU to render by calling gl::flush() and swapping the front and back buffers manually (I don’t know by heart how to do that) between each draw call, but this is not the right way to do things.

If you’re debugging graphics on an NVIDIA GPU, I would recommend using Nvidia Nsight, NVIDIA Nsight Graphics | NVIDIA Developer . Choose the stand-alone version, not the one for Visual Studio. Build your application’s Release target, then run it from within Nsight. You’ll be able to step through the frame you’re debugging and see precisely what is drawn, in what order, what the state of OpenGL is, etc. There is a little learning curve, but once you get comfortable with it, it will save you countless hours of time.


An alternative to Nsight is Crytek’s CRYENGINE | RenderDoc , which is also a free debugging tool.

You can add markers to your code that will make it easier to see what’s what. Here’s a Gist with a Marker class that you can use like this:

void YourApp::draw() 
{
    tools::ScopedMarker m("Draw");

    // do your drawing
}

or

void YourApp::draw()
{
    tools::Marker::push("Draw");
    // do your drawing
    tools::Marker::pop();
}

~Paul

Thank you for the detailed response. My case is different. I’m not debugging/profiling graphics performance. I’m debugging/researching a computer vision algorithm. Instead of looking at values of variables in the debugger window, I prefer to see a step by step graphical representation of what my algorithm is doing. I used to do it on Windows with MFC framework, using its immediate drawing mode. Right now, I’m on Linux and trying to find a more modern substitute of MFC for visualization. Performance is not an issue in this case.

It seems that the way to accomplish it is to replace the main function defined by CINDER_APP_LINUX with a custom one to implement an immediate drawing mode. I wonder if someone has done that before, so I can avoid reinventing a wheel.

Why not use ImGui for this? How are you intending to visualize your algorithm?

Here is a simple example of visualization:

2x2 grad link to largest congruent one 3

which shows a highly zoomed image with lines and text. In step by step mode, the lines would be added one by one, perhaps some of them would change color. Most of the graphical elements stay unchanged in the process. I don’t know that ImGui can do it.

I would dump all of those lines into a single buffer and then modify the end index to control how many were drawn.

gl::draw ( _linesVboMesh, 0, _currentStep * 2 );
1 Like

It is an option, but it requires a level of indirection:

  1. Run the algorithm and collect all graphical items to the buffer
  2. (Re)animate the buffer, increasing displayed length at each step

It would work for some scenarios I usually deal with, but often I have to select the graphical item during the algorithm run, which affects what is being displayed or even the control flow. Buffering preserves only temporal order, but not spatial and logical relationships, which are critical for analysis.

Frankly, the only option I would be comfortable with is direct drawing. Separating my algorithm control flow from display logic is too cumbersome.

You could indeed draw that from within you’re algorithm’s lopp using ImGui’s ImDrawList, which would effectively be doing what @lithium is suggesting - build a buffer of drawing primitives then draw it outside of your algorithm loop. It would be running in real-time this way.

If it were me I would start by making something like a std::vector<LineVisual>, build it during your algorithm loop, then draw it from the main draw() function. Very similar to @lithium’s suggestion, just simpler and slower (which might not matter).

If you want to draw directly in your algorithm loop, you can consider drawing to an offscreen buffer (eg gl::Fbo), and then draw that to the main render buffer in App::draw().

1 Like