View Full Version : creating a background image

07-14-2009, 02:43 AM
Hello OpenGL developer,

dunnow if this is actually a question for advanced programmers or not, but...hope u don't mind.
I've created my software...and I would love to put an image as a background of my rendering window.
Honestly I though to create a plane big like my window and then doing texture mapping...is that the right way?

Very kind regards.

07-14-2009, 05:16 AM

07-15-2009, 01:01 AM
I just wonder if I can both use a perspective and orthogonal projection.

07-15-2009, 01:35 AM
I was thinking of a possibility where glClearColor() can be altered so as to store the image so that when glClear(GL_COLOR_BUFFER) is called the background gets painted by the image. It would be interesting to know more about this.

This raises another question. When glClear is called , it is the main frame buffer that gets updated with the color ....right?

So is there any connection that when
glClearColor(BLACK) followed by glClear is called , then frame buffer's color frame (GL_FRONT) etc gets updated???

IMO, this way the image can be set as background easily rather than setting up a quad and then mapping...

just my opinions...I may be totally wrong...curious to know about the solution.... :)

07-15-2009, 02:08 AM
Implementing your suggestion would simply mean that the few lines to setup and textured quad and a texture would be done in the drivers.. There is very little point in implementing this as part of the drivers, and would open a whole Pandora's box of problems with which texture formats are supported, NPOT and POT and so on... when a programmer can achieve this effect even with a macro!

I don't ever see it happening, nor would anyone want it IMO.

Also AFAIK washing / clearing any buffer with one value is accelerated as it is a special case.

07-15-2009, 02:16 AM
I am against texture mapping I am not in favor of rendering a quad and then do mapping... that would be expensive for the driver as you wrote.

My point is to modify the glClear() such that it accepts image data only and lets driver decide to resize when a window is resized.

i think that can be possible by providing a separate buffer controlled by the hardware.... a wild thought!!!

07-15-2009, 02:38 AM
nope.. txture mapped quad is perfect solution.
1. textures are already in GPU memory
2. you can use shaders and other tricks.

Your suggestion about glClear with image data, could be replaced with following sequence: gentexture, bind texture, teximage2d, render quad.
But.. in your case, image data stay in sysmem and driver needs to copy image to GPU mem before draw. In case with textured quad, texture starage in GPU memory is optimized on GPU way in order to have fastest access. Some driver can split textures in smaller chunks, others maybe have some kind of virtual memory... you never know.

07-15-2009, 11:59 AM
But again the issue of NPOT and POT come to picture on resizing window.Along with this the issue of projection matrix also comes along. Then it will be extra work for gpu to change viewport settings everytime.

Regarding data in sys memory and then copying to GPU mem is a bottleneck but GPUs such as CG1050 , GT200 are capable of directly reading from sysmemory according to ZeroCopy feature in CUDA.....(Never tried it ... just heard)

What is your take on this???

07-15-2009, 12:32 PM
...and I would love to put an image as a background of my rendering window ... is that the right way?
I can suggest another, fairly simple way to put a background image in your OpenGL window. At the beginning of each rendering pass, use glDrawPixels to display the desired image on the screen. Use glRasterPos and glPixelZoom to position and size the image properly. This is easy to set up in an ortho window (with depth testing disabled).

After drawing the image, you can switch to Perspective or a different ortho coordinate system to draw the foreground elements of your scene. You can have scenes with some elements rendered in Perspective and others in Ortho - no problem.

I've put a short demo of this at the link below. It shows a teapot rendered in perspective against an image of a thunderstorm in the background. The teapot can be interactively rotated. If the window is resized, the background image and teapot renderings are adjusted according.

I'd be interested to hear from others how they think this approach would compare to using a textured quad in terms of speed?

There are two files at the link below which should be all you need to get this demo running - ASSUMING you are familiar with GLUT. If someone tries this and runs into trouble, let me know. Good luck.

Background Image Using glDrawPixels (http://www.mfwweb.com/OpenGL/Background_Image/)

07-15-2009, 12:52 PM
use glDrawPixels to display the desired image on the screen.

No, why would anyone do this, glDrawPixels is a totally obsolete thing from the time when gl was done in software, it's only merit was that it kinda worked if you constantly uploaded a unique npot image every time, but here your not, so this is probably the slowest way besides drawing every single pixel as a point (btw i once wrote some code doing just that).

Today, the single fastest way if displaying a static background image is using a texture and a full screen quad.

Though if anything needs to be added though its the ability to quickly just render a full screen quad since it's used quite often and setting up a vbo just for it is a bit overkill.

07-15-2009, 02:54 PM
Think about OpenGL & GPU as server on another planet. It ccan do a lot of things, but resurces must be on its memory. Minimize amount of data needed to sent to draw frame and result is good framerate.

glDrawPixels copy data from system memory to GPU memory EVERY TIME. glDrawPixels is almost like:
gen texture
bind texture
tex image 2d << very expensive
render screen aligned quad
delete texture

07-15-2009, 03:06 PM
Today, the single fastest way if displaying a static background image is using a texture and a full screen quad. Now I'm tempted to set up a benchmark.

I like the DrawPixels approach because it is conceptually the simplest. There is no geometry involved (the quad) and there is no texture mapping involved. In general, I think software GL is fine unless a user is very concerned with speed. Software GL is easier to understand, particularly at the novice level. So maybe this discussion should be continued in the Beginners Forum.

07-15-2009, 03:20 PM
Exactly, this is why I am not in favor of mapping. For glDrawPixels , only thing is that it has to be called everytime to refresh the screen ...something like paint().

This would eat up CPU cycles even if no extra rendering is done.

07-15-2009, 05:00 PM
>>I like the DrawPixels approach because it is conceptually the simplest

a fullscreen quad aint exactly difficult

glMatrixMode( GL_PROJECTION );
glMatrixMode( GL_MODELVIEW );

glBegin( GL_QUADS );
glTexCoord2f(0,0); glVertex2f(-1,-1);
glTexCoord2f(1,0); glVertex2f( 1,-1);
glTexCoord2f(1,1); glVertex2f( 1, 1);
glTexCoord2f(0,1); glVertex2f(-1, 1);

07-15-2009, 08:15 PM
Exactly, zed! This conversation is bizarre! ;)

07-17-2009, 12:20 PM
Now I'm tempted to set up a benchmark.
Please do, but i can already guess the results.

There is no geometry involved (the quad) and there is no texture mapping involved.
Of course there is, it's just that you won't see it since it's done internally in the driver.

07-17-2009, 03:57 PM
With glDrawPixels(..) I believe each pixel has to have certain operations performed on it
scale,bias,unpack etc (though some might be bypassed in the drivers)
in short theres more work to be done than there is with rendering a textured quad

btw If u want best speed youll draw a single triangle over the screen + not a quad

07-17-2009, 04:11 PM
Agree with zed; a fullscreen tri is optimal. You can even draw these without actual geometry -- just submit the 3 dummy verts and read from constants or define the clip space positions directly from within the shader.

07-24-2009, 10:15 PM
glDrawPixels is a useful thing for when wanting to work in windows coordinates on the 2D plane.

However to eliminate the overhead of copying from the CPU's memory to the GPU's you need to use a Pixel Buffer Object (PBO). You create the PBO, copy your pixels into it and then bind to the PBO before calling glDrawPixels. For example to create it:

glGenBuffersARB(1, &amp;namePBO);

To copy into it:

glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, bufferSizeInBytes, bufferData, GL_STREAM_DRAW_ARB);

Then when drawing:

glWindowPos3d(windowX, windowY, 0.0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels(namePBOWidth, namePBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);

...and finally when you no longer require the buffer:

glDeleteBuffersARB(1, &amp;namePBO);

07-26-2009, 02:56 PM
Today, the single fastest way if displaying a static background image is using a texture and a full screen quad.
A single oversized triangle is probably even faster (you already knew this ;-P).

Though if anything needs to be added though its the ability to quickly just render a full screen quad

Considering the fact that many apps (vast majority I'd say) need/uses billboards (both in the actual scene for faking stuff, but also for "HUD" data), would it perhaps make sense to suggest a few extra functions to not have to go ortho and... ? Perhaps "HUD" stuff could be the most obvious to target to play with, where the only thing involved is, well effectively it's just stretchblit (perhaps plain "blittable" sized quads are even more frequent) without even depth write. If that turns out OK, perhaps it could even be used for actual scenes (faking smoke etc)?