Alexander
Alexander

Reputation: 3057

How do draw to a texture in OpenGL

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?

Upvotes: 4

Views: 13242

Answers (6)

user34619
user34619

Reputation: 256

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.

Upvotes: 4

Jon Wayne Parrott
Jon Wayne Parrott

Reputation: 1341

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!

Upvotes: 2

shoosh
shoosh

Reputation: 78914

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

Upvotes: 2

greyfade
greyfade

Reputation: 25647

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.

Upvotes: 2

UncleZeiv
UncleZeiv

Reputation: 18488

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!

Upvotes: 5

thekidder
thekidder

Reputation: 3574

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

Upvotes: 0

Related Questions