PDA

View Full Version : howto: Off-screen rendering(not using or showing a window)



cutting_crew
10-16-2007, 01:00 PM
hi all. without making this post too too long i will try to explain what i am trying to do.

i am writing software for a professional camera and need to be able to manipulate the images(such as copy, scale and crop) it sends back without having(or using) a windowing context in OpenGL.

i am by no means an opengl expert so i will definitely need help with at least some code to start(maybe theres not that much) or at least my alternatives.

i would rather not use pbuffers as these are platform dependent and while i could use tests for each OS figuring out which type of system pbuffer to use i would rather use something this is both hardware accelerated and cross-platform as long as you have a compatible OpenGL video card.

basically i have 2 cameras. i have separate code for both cameras that retrieve images from each camera. the camera returns an image it takes in a byte array that i can retrieve from my class that i have written.

i would like to take both images and overlay one on top of the other, with the top image being transparent, to combine one image from the two. after this is complete i want to be able to write the image out to a .png file.

writing out the .png file is done as i am just using libpng to write it out. no problem. my problem is is that i don't or have no need to use a windowing context of any form.

i want to be able to using OpenGL calls to combine the images like i said into one image with the top image containing transparency.

the options that i know of right now is the GL_EXT_framebuffer_object but as i type this am not totally 100% knowledgable on it and still really dont have any idea of how to create a windowing/render context without showing a window.

After reading the GL_EXT_framebuffer_object definition it seems like "framebuffer-attachable images" (2D arrays of pixels that can be attached to a framebuffer) is what i need, though i could be just grabbing straws here.

can anyone help me with links, code or thoughts? thanks a lot for your help in advance!

Lindley
10-16-2007, 03:23 PM
First of all, creating an OpenGL context is not something you can do in a completely cross-platform way. There will be #ifdefs. Typically implementing versions for WGL and for GLX is good enough to guarantee compatibility with most systems.

I can't help you with precisely how you do that part. I've seen it done, but the code was nontrivial.

As to framebuffer objects, those are pretty simple once you've got a context in place. They're just a struct full of pointers: Four to color attachment points, one to a depth attachment point, and one to a stencil attachment point.

As for what you actually attach to each pointer, the two options are textures and renderbuffers. If you're going to do any sort of multi-pass algorithm, attach a texture so that you can bind the results of one render as the source for another. If not, just use a renderbuffer.

Note: For something as simple as overlaying one image on another, OpenGL may not be the best way to go. The actual overlay will go faster, yes, but that could be mitigated by the time needed to download both images to the card and the time to readback the combined image.

sqrt[-1]
10-16-2007, 05:13 PM
I agree, OpenGL is probably not a good fit for this task. It would probably go much faster if you just blended it manually on the CPU.

cutting_crew
10-16-2007, 09:20 PM
Originally posted by Lindley:
Note: For something as simple as overlaying one image on another, OpenGL may not be the best way to go. The actual overlay will go faster, yes, but that could be mitigated by the time needed to download both images to the card and the time to readback the combined image. i understand what you are saying but i am not looking to make the program runs 2 seconds faster nor am i really concerned about speed at this point. as of right now i will be only merging the two images once i have my other 2 images in memory from the two cameras. so i will only need to do this once per x amount of time anyway with x being a relatively big number(in seconds).

could i not use glut for a rendering context? this would work well for both win and linux. like i said i will not be showing any window. i just need to use the glutCreateWindowDisplay(..) or whatever it is. Like i said before i think though how do you disable the actual drawing the window?

cutting_crew
10-16-2007, 09:24 PM
Originally posted by sqrt[-1]:
I agree, OpenGL is probably not a good fit for this task. It would probably go much faster if you just blended it manually on the CPU. thanks so much for yours and Lindleys comment sqrt. the whole idea of this software is that for the program to blend the images non-manually. this is going to be for a customer and they will not want to do it manually or they might not have and probably not even likely they would have any sort of post-processing software such as photoshop.

if it is going to be fast, as lindley suggested, the time it takes to make multiple trips to the GPU and back is really of no concern to me at this point. i just want to get it working.

once i have the combined images using FBO's i already have my png writer in place to write it out as a .png file. the idea behind this is to save images in a directory so when the software is re-run the next time you can load the images saved into "thumbnails" for previewing.

Lindley
10-16-2007, 09:36 PM
Who said anything about Photoshop? "Manually" in this case just means loop over the pixels and do
C(i,j) = alpha*A(i,j) + (1-alpha)*B(i,j).

If speed isn't an issue, this really is the simplest way to go. If you use an optimizing compiler it's probably not much slower than OpenGL would be----*especially* if you're only doing it once, because the first few OpenGL calls always take abnormally long due to setup overhead.

If there's going to be perfect pixel correspondence, I don't think getting OpenGL involved is at all necessary. Now, if you were looking to overlap images in more arbitrary ways, possibly even at 3D angles to each other----then using OpenGL would make sense, because it does most of the math for you.

Oh, and you can't use GLUT if you don't want the window showing up. Plus, there's no easy way to get GLUT to go away once to call glutMainLoop() except to kill the thread that's running it. GLUT is a beginner's kludge, not something you'd see used commercially very often.

cutting_crew
10-16-2007, 09:49 PM
i gotcha, sorry i misunderstood what "manual" was. all the images will be 2D and will not be used for 3D manipulation in any way.

that algorithm does make sense and i have something similar already written out. if i do this manually as you say then what about scaling or cropping images? the images coming back from one of the cameras is 1024x768. i will need to scale this down to 640x480 to match the image coming from the other camera so there is a perfect overlay. cropping the image also might be necessary(this may or may not be a power of two).

sqrt[-1]
10-16-2007, 10:14 PM
I actually would recommend something like
http://www.imagemagick.org/

You can crop/scale/blend and do any amount of transforms:
http://www.imagemagick.org/script/magick-core.php

cutting_crew
10-16-2007, 10:35 PM
Originally posted by sqrt[-1]:
I actually would recommend something like
http://www.imagemagick.org/

You can crop/scale/blend and do any amount of transforms:
http://www.imagemagick.org/script/magick-core.php wow thanks a lot for that suggestion. i will look into it!

Ffelagund
10-16-2007, 11:42 PM
Also you can try FreeImage. If you are going to perform linear interpolation between images, this will do the work for you. This allow you to load and save images in any format (for instance png) peform many filters (bicubic, linear, etc), images resizing..., etc.
Its free and easy to use. I'm using it in my work to perform some CPU tasks over many 12 Megapixels images before sending to the GPU and I'm very satisfied with it.

cutting_crew
10-17-2007, 12:14 AM
Originally posted by Ffelagund:
Also you can try FreeImage. If you are going to perform linear interpolation between images, this will do the work for you. This allow you to load and save images in any format (for instance png) peform many filters (bicubic, linear, etc), images resizing..., etc.
Its free and easy to use. I'm using it in my work to perform some CPU tasks over many 12 Megapixels images before sending to the GPU and I'm very satisfied with it. out of curiosity what are you doing with the images in hardware that cant do with FreeImage?

Ffelagund
10-17-2007, 07:34 AM
I'm working in an photogrametric aplication that needs to perform some filters and projections (through fragment shaders) in real time, with varying parameters through the time. Because it must be done in real time and the application works with many big images we'd choosen the GPU way. I'm sorry I can't tell you more, but I'm under NDA :p