Running OpenGL code in ROOT for imgui integration

Hello everyone,

I am currently working on integrating the dear imgui library into ROOT. To be able to achieve this, I am trying to understand how OpenGL is used within ROOT. After digging through the code for some days I could find some places where 3D rendering takes place, however I still don’t fully understand the underlying architecture. Is there maybe some documentation on the underlying architecture available (I found the slides about 3D-graphics on the user guides and manuals pages, but there is quite some information in them which is already outdated and where the code differs from the one in the slides)? Or is the only way to find out more by going on looking through the code?

For the first step I would like to find out where I can simply run simple some “normal” OpenGL code which then is rendered inside a ROOT canvas. This could be something as simple as drawing a triangle with three given vertices. I opened a TCanvas in the ROOT shell and I don’t get any errors when I run some OpenGL commands afterwards. However I don’t see anything changing on the canvas and calling Draw() gives me a segfault. I also tried the DrawPlot() method of a new class extending TGLPlotPainter, but I feel, that the TGLPlotPainter is already making a lot of assupmtions about what it is used for and is too “heavyweight” for just running some OpenGL code. So for the first step it would be very helpful if someone could point me towards a place where my OpenGL code can be executed and gets shown. It would also be interesting if there is some kind of “main loop” which is often found in OpenGL programs where the rendering code can be run.

Thank you very much in advantage
Thomas

ROOT Version: 6.12/04:
Platform, compiler: Ubuntu 17.10, gcc7.2.0

OpenGL can be used inside ROOT even to render 2d Graphics if you set the resource OpenGL.CanvasPreferGL: to 1 in $ROOTSYS/etc/system.rootrc . Gl can also be invoke to render 3D plots. The geometry example are also base on GL ($ROOTSYS/tutorials/geom).

Thank you. What I was searching for however is still a more lightweight solution. What I would like to write more or less is the following code (which does not work like this, but to give a better impression about my goal):

gStyle->SetCanvasPreferGL(true);
TCanvas* canvas = new TCanvas("main", "simulation", 600, 600);
canvas->SetSupportGL(true);
canvas->cd();
canvas->Update();

glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f); 
glBegin(GL_QUADS); 
glVertex3f(-1.0f, -1.0f, 0.0f); 
glVertex3f(-1.0f, 1.0f, 0.0f); 
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glFlush(); 

canvas->Update();

So I’d just create some Canvas supporting OpenGL, write my OpenGL code which should be rendered on the Canvas and then update the Canvas.

Is something like this possible maybe not using TCanvas, but other classes?

Ah … I see you want to call directly GL in a root macro. That’s not possible.

Well, it does not neccesarily need to be in a macro, but yes: It would have made development easier if it can be done in a macro.

But I also can create a TCanvas like this in compiled code, and it would be fine if I could find a place to do something like this within my own class…

I guess you can have a look in the ROOT code where we use the gl functions. grapf3d/eve is one place and graf3d/gl another.

Hi,

What are you actually trying to do? Do you want to display both root graphics and your gui in the same canvas? Or are you just looking for a way to get a GL drawable?

\m

Your explanation “looking for a way to get a GL drawable” summarizes my matter much better than all my explanations above. Thanks.

So, yes, what I am actually searching for is a way to get a GL drawable using the ROOT infrastructure for OpenGL (initialization, context creation) and not my own infrastructure (e.g. glfw3). Additionally I also need the possibility to capture keyboard/mouse input for the drawable to be able to react to user input.

However I don’t need ROOT graphics in my canvas.

Do you see a way to achieve this?

I think you want a TGLWidget then … subclass it and put it into TGMainFrame. There are event handling functions in TGLWidget already. Take a look how this is used in TGLSAViewver and TGLEmbeddedViewer (or some such).

Note that you are boldly going where few have gone before :wink: And ask if you get in trouble.

Matevz

Thank you. I’m going to try this and if I succeed I will write it into this discussion.

Well, finally I got some OpenGL code executed within ROOT’s OpenGL context. I will paste a simple example which can be run in the ROOT shell, and which shows one possibility to get access to a OpenGL drawable within ROOT, so anyone interested in this functionallity does not have to search all this again from zero.

#include "TGLIncludes.h"
const TGWindow* rootWindow = gClient->GetRoot();
TGMainFrame* mainFrame = new TGMainFrame(rootWindow, 400, 400);
TGLWidget* widget = TGLWidget::Create(mainFrame, kFALSE, kTRUE, 0, 400, 400);
mainFrame->AddFrame(widget, new TGLayoutHints(kLHintsTop | kLHintsCenterX, 0, 0, 0, 0));
widget->MakeCurrent();
mainFrame->MapSubwindows();
mainFrame->MapWindow();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(0.0, 400.0, 0.0, 400.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPointSize(10);
glLineWidth(2.5);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
	glVertex3f(10.0, 10.0, 0.0);
	glVertex3f(200.0, 200.0, 0.0);
glEnd();
widget->SwapBuffers();

HI Thomas,

Any luck getting this into Dear ImGui?

Cheers

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.