ashley's picture

Texturing

I am just wondering what is the best way to texture a quad?
I have a situation where a user can create an image of any size and I have to output this in opengl. The Quad will be the same pixel size as the Image.
Quality is the most import thing and the image must be of the same quality it was created and in the same aspect ratio.
I am very new to opengl stuff but from what I have done so far experimenting with power of 2 textures etc I can't get the quality looking good and looking like the original image.
Do I resize the texture to the next power of 2 number of the actual size?

Thanks


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nythrix's picture

I don't really specialize on OpenGL so these are more or less general tips:
1) There's a difference between what you see on screen and how does a texture look in memory. If the quad isn't screen aligned so that the texture pixels match the screen pixels filtering is applied. That always makes the image look worse.
2) I'm not sure what you mean by "quad size" since there's no direct relationship between OpenGL "space" coords and texture coords. If you just want to put the texture on screen (and automatically get the best look possible) you don't have to use any quad. This you can achieve through framebuffer blitting or GL.DrawPixels if that's not available.
3) Also see question 9.090 in this page.

ashley's picture

Thanks for the reply.
I mean that I am using 2D space and that I have specified the quad to be the same size as the image, so on screen the quad matches the same size as the image... not sure if this makes any difference.
I shall look into the GL.DrawPixels

Thanks

the Fiddler's picture

This is a relatively simple task once you become familiar with the workings of OpenGL.

Since graphics hardware cannot cope with arbitrarily large images, you will have to chop your image into tiles that fit into the size limit (GL.GetInteger(GetPName.MaxTextureSize)). Modern hardware can cope with textures of any size up to the limit but older hardware is limited to power-of-two sizes (for best compatibility restrict your tiles to power-of-two dimensions).

Each tile can then be uploaded to an OpenGL texture. For best quality, use Rgba8 as the texture internal format and disable filtering on these textures. (For very large images that don't fit into VRAM, it might be better to to arrange the OpenGL textures into a grid and update them dynamically when panning the camera.)

For rendering, first check which tiles are visible. For each visible tile, bind the relevant texture and draw a quad. Since you need pixel-perfect rendering, you should use an orthographic projection that matches the viewport size (i.e. Matrix4.CreateOrthographic(0, 0, ClientSize.Width, ClientSize.Height, -1, 1)).

GL.DrawPixels() should also work with two caveats:

  1. You need to make sure you are drawing to the backbuffer (GL.DrawBuffer(DrawBufferMode.Back)).
  2. It will be much slower for large resolutions. Instead of textures, the image data will remain in system memory and travel through the PCI-E bus every time the camera moves. For 1920x1200 this translates into ~550MB/s for smooth animation, which is quite a lot.

On the other hand, this approach is simpler and can work fine depending on your requirements.