How to render (2D) textures in off-screen pixmaps ?

Dear all,
first let me apologize in case this forum is not the appropriate place for the topic I am about to discuss,
I am somewhat inexperience in the matter and would appreciate any help to re-locate this discussion
where it has to be, also I learn(ed) OpenGL on my own, thus I might not be as accurate as you would
require me to be when asking for help, but I am more than willing to cooperate and provide more details
about my problem.
Few days ago I opened a thread to discuss some troubles I had to positioned 2D textures in my 3D window,
see here for details: Text and/or textures position in 3D world - OpenGL: Basic Coding - Khronos Forums

After receiving some help I managed to correct the problem in my visualization window.

With same program I am able to output a movie of my scene, do do this I create a pixmap,
then I render my scene off-screen in that pixmap, appending one pixmap after another I create
my movie (using ffmpeg) (or a snapshot with a single pixmap).
Everything works just fine, no problem … almost no problem … for some reason the textures
that I added to the scene (atomic labels around atoms see my previous post) do not appear
in the movie when I watch it afterwards, everything is there but these textures … I figured
that for some reason they can not be rendered off-screen and/or in my pixmap … I search the web
and the forums but I am not able to find out why and how to fix this …

Thanks in advance for you help on this matter.

S.

Hello again,
so far not any clue to solve this problem … on my own … could you help ?

S.

I think part of the reason you did not get replies is because rendering to pixmaps (I assume you are talking about WGL_pbuffer?) is not used a lot these days, framebuffer objects (FBO) are a more convenient method to render to textures - which then can be copied back to main memory if needed.

As a random guess what your problem might be: is your pixmap rendering happening on a second OpenGL context (or window)? - in that case you either need to set up the context so that they share resources (textures, buffer objects, etc.) or re-create the textures in the second context.

Hello and thank you for your answer, interesting answer I must add,
first I am not using WGL_pbuffer, and to be honest I never eared of it before reading your post,
my program is using GTK+ to generate/manage windows, and also the GtkGlext OpenGL extension.
The easiest way (I found, or at least seems to be the easiest way to do things) is to use this calls:


    GdkGLConfig * glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH);
    if (glconfig == NULL)
    {
      g_critical ("Sorry, it is not possible to configure any type of OpenGL-capable context.
");
    }
    pixmap = gdk_pixmap_new (NULL, x_res, y_res, 24);
    glpixmap = gdk_pixmap_set_gl_capability (pixmap, glconfig, NULL);
    gldrawable = gdk_pixmap_get_gl_drawable (pixmap);
    glcontext = gdk_gl_context_new (gldrawable, NULL, TRUE, GDK_GL_RGBA_TYPE);
    if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    {
      // And here you use the pixmap as rendering area/tool ... I guess the word is as an OpenGL context
    }
 

Then you are right about the fact that the pixmap rendering happens on a second OpenGL context,
and I do not understand why do the context(s) have to share resources … and even more
how can they … but the fact is that at this point in my code I only care about the second context,
which happens to be an off-screen context, furthermore I do not understand why contexts should
share texture or else if they are not directly related/linked … please teach me.

Also when I search the web for off screen rendering I found out about FBO, and tried to use that in my code
but I was unsuccessful … to say the least … I could not understand the WHAT/HOW/WHY …
using FBO I was still able to produce a ‘working’ version of the program, in the sense that it was still
possible to encode a movie, however the movie was completely filled with … nothing … it looks like partial
screenshots … at least before using the FBO I had everything but the textures I would like to render,
after using the FBO I had nothing …

Thanks already, and thanks in advance for your lights !

S.

Normally when you create a texture object it is created in the OpenGL context that is current (active) at that time. Any other OpenGL contexts that your application has (or creates later) do not know anything about that texture object [1] and you can not use it in those other contexts. If you configure the context to share resources at creation time (see shareContext parameter to wglCreateContextAttribsARB or glxCreateContexxtAttribsARB) then a texture created in one context can also be used in the others. From a quick look at the docs for gdk_gl_context_new it looks like you can use that functionality by passing in your “main” context as second argument.
If you only need the resources in the off-screen context you need to create them in that context, that means: make it the current context when you create the textures and upload their contents.

There is not enough information for me to even hazard a guess why using an FBO is not working for you.

[1] textures are not the only shareable resources, buffer objects, shader objects, and program objects are shared as well - other objects (those which mostly act as containers for other resources) are not shared, that includes vertex array objects, pipeline objects, and framebuffer objects.

The second argument to gdk_gl_context_new needs to be the original context (GdkGLContext*) in which the textures were created. This results in the two contexts sharing textures (and other large data structures such as VBOs, FBOs, display lists, etc.). They still don’t share “state”, so most of the initialisation which is performed for the original context needs to be repeated for the new context.

Thank you so much, that was exactly the problem, I was not re-creating/sharing the textures between the contexts !
Now it works perfectly ! :smiley:

Thanks again.

S.