views:

1989

answers:

6

Now that my OpenGL application is getting larger and more complex, I am noticing that it's also getting a little slow on very low-end systems such as Netbooks. In Java, I am able to get around this by drawing to a BufferedImage then drawing that to the screen and updating the cached render every one in a while. How would I go about doing this in OpenGL with C++?

I found a few guides but they seem to only work on newer hardware/specific Nvidia cards. Since the cached rendering operations will only be updated every once in a while, i can sacrifice speed for compatability.

glBegin(GL_QUADS);
       setColor(DARK_BLUE); 
       glVertex2f(0, 0);                  //TL
       glVertex2f(appWidth, 0);           //TR
       setColor(LIGHT_BLUE);
       glVertex2f(appWidth, appHeight);   //BR
       glVertex2f(0, appHeight);          //BR
glEnd();

This is something that I am especially concerned about. A gradient that takes up the entire screen is being re-drawn many times per second. How can I cache it to a texture then just draw that texture to increase performance?

Also, a trick I use in Java is to render it to a 1 X height texture then scale that to width x height to increase the performance and lower memory usage. Is there such a trick with openGL?

A: 

Look into FBOs - framebuffer objects. It's an extension that lets you render to arbitrary rendertargets, including textures. This extension should be available on most recent hardware. This is a fairly good primer on FBOs: OpenGL Frame Buffer Object 101

thekidder
The whole point of the question is that he can't use FBOs because he wants the lowest possible hardware denominator.
shoosh
+4  A: 

If you don't want to use Framebuffer Objects for compatibility reasons (but they are pretty widely available), you don't want to use the legacy (and non portable) Pbuffers either. That leaves you with the simple possibility of reading the contents of the framebuffer with glReadPixels and creating a new texture with that data using glTexImage2D.

Let me add that I don't really think that in your case you are going to gain much. Drawing a texture onscreen requires at least texel access per pixel, that's not really a huge saving if the alternative is just interpolating a color as you are doing now!

UncleZeiv
+2  A: 

Consider using a display list rather than a texture. Texture reads (especially for large ones) are a good deal slower than 8 or 9 function calls.

greyfade
So would a display list that draws a full screen gradient be faster than just caching the result and drawing that over and over?
Alexander
It's something you'll want to benchmark yourself, but, yes, I believe so. See Sorren's answer for the rationale.
greyfade
+2  A: 

Before doing any optimization you should make sure you fully understand the bottlenecks. You'll probably be surprised at the result.

shoosh
+3  A: 

I sincerely doubt drawing from a texture is less work than drawing a gradient.

In drawing a gradient:

  • Color is interpolated at every pixel

In drawing a texture:

  • Texture coordinate is interpolated at every pixel
  • Color is still interpolated at every pixel
  • Texture lookup for every pixel
  • Multiply lookup color with current color

Not that either of these are slow, but drawing untextured polygons is pretty much as fast as it gets.

+1  A: 

Hey there, thought I'd give you some insight in to this.

There's essentially two ways to do it.

Frame Buffer Objects (FBOs) for more modern hardware, and the back buffer for a fall back.

The article from one of the previous posters is a good article to follow on it, and there's plent of tutorials on google for FBOs.

In my 2d Engine (Phoenix), we decided we would go with just the back buffer method. Our class was fairly simple and you can view the header and source here:

http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL/PhRenderTexture.h http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL/PhRenderTexture.cpp

Hope that helps!

Jon Wayne Parrott