View Full Version : Share a 3D texture in four QGLWidgets

19th October 2007, 03:42
Hello. Currently I am developing a volume rendering application with 4 widgets. In my biggest QGLWidget I show the volume, and in the other 3 widgets I want to show the sagital, transversal and coronal planes of that volume, and to do that obviously I need to share my 3D texture, but I have not be able to share it yet :eek:.

If anyone can shed some light in this overwhelming task!...:)

PS: Later I will post what I've done... now I do not have the source code at hand :o.

19th October 2007, 15:51
You can store the QPixmaps or QImages for the textures as members in your class and bind them separately for each view. So for each gl widget you would use the same textures.

19th October 2007, 18:07
Sorry, but I don't see how to use a QPixmaps or QImage for the planes. Maybe I couldn't make myself understood well.

The planes I need to show are dynamic, I mean, using a spinBox I choose what slice of that plane I see, like those shown in apps to see MRI or CT, so I need to be able to access to the 3D texture from this 3 widgets, because with it I assign a slice of that 3D texture to a quad (in OpenGL).

The texture is loaded in another class (FileIO). There I read the raw data from file and right after I load it to the texture buffer with the usual stuff (glGenTexture, glBindTexture, glTexParameter, glTexImage3D...).

Do I have to share a context or something like that? If I load the texture in FileIO and I can show the volume (accessing the 3D texture) in my widgetVolume... why I can't access the texture from the others 3 widgets?

19th October 2007, 19:03
Yes, yes, sorry.
There is one QGLWidget constructor that let's you share the context with another QGLWidget.

I wonder if you can use that and chain the widgets, from the 'biggest' to the 'smallest'.

19th October 2007, 20:22
I've tried to share the contexts, but it's been unsuccessful. This is the last thing I did:

QGLContext *cx;
. . .
wVolume = new Rendering(mainWidget);
cx = new QGLContext(wVolume->context()->format());

wPlane1 = new Rendering(cx, framePlane1, wVolumen);
wPlane2 = new Rendering(cx, framePlane2, wVolumen);
. . .

Why I can access to the texture from wVolume but no from wPlane1, wPlane2, ... ? :confused:

In the thread "Texture + Multiple QGLWidgets" KShots gave me some suggest. Take a look around.

19th October 2007, 22:22
Ok, in an attempt to keep all replies in one topic, I'm going to reply to a question you asked in the other topic over here (and we'll drop the other topic entirely).

You asked if a single widget takes the "privilege" of accessing textures and other GL widgets must share that "privilege". This is not quite how it works. What happens is that each GLWidget has its own context, with its own texture memory and its own display lists. One widget cannot use another widgets textures or display lists, but each widget has access to the 3D hardware.

You get around this by sharing the texture memory and display lists by passing in a QGLWidget to your widget right after your parent gets passed in. In the example I gave in the other topic, I was assuming that all visible GL windows could be destroyed, which would then wipe out the existing texture memory and display lists... which would usually be undesirable. In my case, I used what I call a "hidden viewport" which is simply a QGLWidget that keeps the context alive by not being destroyed until you exit the application.

21st October 2007, 20:44
I do not understand, as the first QGLwidget hiddenViewPort, go to the texture and then be able to share, because in our case that is being accessed from the first to the texture is widget wVolume.

Now we have tried so you suggested in another post, but the result has been a failure :(!!

QGLWidget *hiddenViewPort = new QGLWidget(this);
wVolumen = new Rendering(centralwidget, hiddenViewPort)
Plane1 = new Rendering(frame1, hiddenViewPort)
Plane2 = new Rendering(frame2, hiddenViewPort)

In this case the texture can only be accessed from plane2. This code is located in the builder that binds to the interface and the class is called 'mainwindows'