Drawing to an image rather than screen

Hey everyone,

I was just wondering if there was an easy way to draw to an image rather than drawing to the screen. I’m aware that one can render to a texture, but is this the easiest way of going about it? Wouldn’t that still cause the overhead of rendering to the screen?

I’d also like to preserve alpha components, so that the image that I draw comes out with a transparent background so I can overlay my rendering on top of another image. Has anyone done something like this before?

Thanks in advance for the help!

Yes, rendering to a texture and then reading the bytes back out to dump into a MemoryImageSource is the only way of doing this.

I noticed a function for GLCapabilities:

GLCapabilities glc = new GLCapabilities();
glc.setOffscreenRenderToTexture ( … )

Does this just allow one to use the glCopyTexImageXD function? Or does this have more interesting connections of being able to easily get an image from the framebuffer?

Any insight would be greatly appreciated!

Yes and no. Unfortunately JOGL hides all of that from you so that all you have is the GLPbuffer object. It hides all the copy image work from you. The only way to get this to work is to render to the back buffer of an on-screen drawable and do your own glReadPixels call to get the values back, or do a traditional multipass rendering strategy with glCopyTexImage() calls.

Depending on what you are trying to achieve, you could also try to do it the other way round.

Apply your image as a texture on a quad and render your 3D graphics on top of it.

I did the quad thing already, however, Unfortunately I’m going to need the reverse as well due to some functionality of a panel that I need to overlay 3d stuff on.

I’m worried though, With Mirthrandir’s approach: does the window need to be visible to do this? The idea is to disable rendering to the screen, and instead, render to a texture only.

Anyone know when exactly init function is called for the GLEventListener? Must the frame that it’s in be setVisible(true)? Or is there another way to explicitely call init(GLDrawable gLDrawable)?

Basically, it’s the problem that I originally thought I’d have. There doesn’t seem to be a way to have openGL initialize w/out showing/popping up a window… anyone know of a work around?

I’m afraid that you’re absolutely correct. OpenGL needs at least one window open so that you can create the initial canvas and get the initialisation done. Even to create a pBuffer to pull pixels from, you’ll need that initial window. Perhaps try seeing if creating a 0x0 undecorated frame with the canvas in it will help you get a pBuffer to draw to.

Similar questions to this have come up several times in the archives. See these threads:

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl;action=display;num=1076283910;start=

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl;action=display;num=1063387918;start=

I also posted some code for how I solved my particular variant of this problem here:

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl;action=display;num=1077239979;start=

Regards,
Daniel

I implemented my own routine to grab pixels from the back buffer using glReadPixles, and it seems to be working ok. However, my images always come out fliped vertically and horizontally. I’m currently doing an affine transformation to fix this issue, but it seems that I never see you guys doing it in any of your things… why is that?

Is there a faster way to do this - doing a transformation in java is very slow.

naphtha: did your code ever work for transparent images? I noticed a guy tried it below your last post and he had problems, and it didn’t seem to be resolved.

Thanks again for all the help, seems to be coming along :slight_smile:

Your images will be flipped vertically because opengl has its origin in the lower left corner of the screen while java2d has its origin on the upper left corner of the screen. You can copy the framebuffer to a texture and then render a textured quad covering the entire framebuffer to flip the image. That was the fastest way I found to flip the image.