10/9/07

Quick NPOTs

Most cards today support Non Power of Two Textures (NPOTS). In the old days textures had to be 64x32 or 256x512 or some such but screen resolutions are typically 800x600 or 1024x768 - non power of two. I know my card (x600) supports NPOTs but I had trouble getting them to work fast so I guess others may too. I wanted to
  • render the scene to the back buffer (800x600)
  • copy into a texture (also 800x600)
  • Use the texture in a distortion shader
The third step could be anything of course. The key is I needed this in real time. The problem is although NPOTs are supported on cards, they can be incredibly slow. The trick is setting them up correctly. First here is the code to read the screen and copy it into a texture:


void grabScreen(unsigned int tnum, GLubyte *p){
createTexture(tnum,p);
glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 0,0,800,600,0);
}


So I call a function to create a texture and then copy the whole back buffer into it. Nothing surprising here, its here for completeness. The real trick comes in the createTexture() routine. Here is where you can foul up pretty easily.


void createTexture (unsigned int tnum, GLubyte *p) {
glBindTexture (GL_TEXTURE_2D, tnum);
//commenting out any of these means it runs slow as hell
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,800,600,0,GL_RGB,GL_UNSIGNED_BYTE,p);
}


You can see the whole trick is explicitly telling OpenGL that it never needs to worry about wrapping of texels across the border. Instead, explicitly clamp the edge of the texture. Its obvious why if you think about it. If the texture wrapped, a modulo maths step is required to find the right texel. For powers of two this is a mask and a shift but is far more complex for non-power of two.

So now its possible to capture the whole screen at real-time rates and use that for...next article.


4 comments:

  1. Anonymous9/10/07

    So - that's what I call a good starter ... great stuff Chris ... keep on goin' :)

    SLiPPY

    ReplyDelete
  2. Anonymous10/10/07

    Great first article Auld.

    ReplyDelete
  3. Anonymous10/10/07

    Increase the font size of the code!

    ReplyDelete
  4. Slippy and Voltage, nice to see you around. I wont be doing too much ST stuff Slippy ;-).

    Anonymous: done.

    ReplyDelete