PDA

View Full Version : Completely disable filtering



openglnub
12-16-2009, 03:15 PM
I have a texture I read in which I do not want filtered. The reason is that it represents very discrete data about a real-world scenario, and I need the edge between colors to be abrupt. When reading in the texture, my code includes:


glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

However, when I look at my image it is still very roughly filtered. The filter is only in one axis direction; the other is not filtered. The difference is very stark between using GL_LINEAR and GL_NEAREST, but GL_NEAREST still applies some filter which I can't seem to turn off.

I am very new at opengl coding, so excuse my lack of useful terminology.

openglnub
12-16-2009, 03:38 PM
If this helps, this is what I'm seeing...

http://imgur.com/ZOHWH.png

Dark Photon
12-16-2009, 08:20 PM
How sure are you this filtering isn't in the source texture data?

I.e. read back and print your texel values.

Ilian Dinev
12-16-2009, 11:05 PM
gluBuild2DMipmaps pre-scales (and thus blurs) the image if it's NPOT. How do you upload the texture data to the gpu?

ZbuffeR
12-17-2009, 02:10 AM
If this helps, this is what I'm seeing...
For me, there is no filtering at all on the picture.
What do you want to see instead ?

openglnub
12-17-2009, 08:43 AM
Thank you for the replies. I'm away for part of today, but when I get back I'll take a closer look at how I read in the texture. The source (a ppm image) has only three color values, blue, pink, and white. The blending is what I want to avoid. I believe I fill the texture with the values, cell by cell, of the ppm, as I recall.

openglnub
12-17-2009, 12:36 PM
What I'd like to see...

http://imgur.com/rdhS6.jpg

Note that there's another blue rectangle drawn in the picture above, so that's a known discrepancy. Also the zoom levels are a bit different.

I use OpenCV to read in the image (cvLoadImage) to get an IplImage structure. Then (after flipping the image for some coordinate frame problems) I make the following OpenGL calls. Note that channels, width, and height are filled from the OpenCV image structure.



glBindTexture(GL_TEXTURE_2D, textureId);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

if( channels == 3)
{
gluBuild2DMipmaps(GL_TEXTURE_2D, channels, width, height, GL_RGB, GL_UNSIGNED_BYTE, newData);
}
else if( channels == 4)
{
gluBuild2DMipmaps(GL_TEXTURE_2D, channels, width, height, GL_RGBA, GL_UNSIGNED_BYTE, newData);
}

ZbuffeR
12-17-2009, 01:14 PM
Indeed, Ilian Dinev was right : you should not use gluBuild2dMipmaps if you want to keep your source data intact. And there no point in building mipmaps if GL_TEXTURE_MIN_FILTER is GL_NEAREST.

It sounds like your image is not power-of-two.
If your hardware supports it, you can use it directly with glTexImage2D :
http://www.opengl.org/wiki/NPOT_Textures
Otherwise, you will have to pad the image data up to the nearest power of two in both width and height, and adapt texture coordinates accordingly.

openglnub
12-17-2009, 02:03 PM
So, if I replace my mipmaps code with a call to glTexImage2D to define the textures, it may work? And if not, I can simply pad to a power-of-2 size?

When I try this, I no longer see my texture. The computer I'm using is fairly new, but is there any way if I can see whether or not it's capable of displaying NPOT textures?

Replaced mipmap lines with:


if( channels == 3 )
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, newData);
}
else if( channels == 4 )
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, newData);
}

ZbuffeR
12-17-2009, 02:31 PM
The internalFormat should be GL_RGB(A)8 instead of just GL_RGB(A), but the problem is more likely to be caused by no NPOT support.


First you should do a check with a 256*256 texture, so that NPOT problems are ruled out.
If that does not work, then your problem lies elsewhere...

If it works, then you probably don't have NPOT support.
To check if the GL_ARB_texture_non_power_of_two extension is available on your hardware, here is a tutorial about the concept and practice of extensions in OpenGL :
http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/extensions.php
I recommend using GLEW or Glee to make things easier.

openglnub
12-18-2009, 08:43 AM
Thanks. I took a look at GLEW, and it turns out my video card does not support GL_ARB_texture_non_power_of_two. I'm also having a problem where my textures are getting VERY big when I pad to the next power of two, so I guess I'll cut them and lose data...oh well.

ZbuffeR
12-18-2009, 09:08 AM
Just to clarify, power-of-two does not mean square.
Example for a source image of 129*480, the POT sizes to be used would be 256*512, roughly twice the data.
The worse case is "only" 4 times more texture data.

And your video card is ?

mark ds
12-18-2009, 09:23 AM
Does your card support GL_ARB_texture_rectangle or GL_EXT_texture_rectangle? This would be ideal if I understand you correctly.

openglnub
12-18-2009, 09:29 AM
If I run glxinfo and check, I do see GL_ARB_texture_rectangle but not GL_EXT_texture_rectangle. With these extensions, how do I actually go about using them with GLEW? Do I just make my glTexImage2D call with a different target value (i.e. GL_ARB_texture_rectangle instead of GL_TEXTURE_2D)?

And my video card is Quadro FX 350M, so I believe it supports OpenGL 2.1. The textures I'm generating need to be either 3 or 4 channel, and around 4500x6200. They could possibly be bigger.

EDIT: When I use GL_ARB_texture_rectangle, it seems to generate the textures but they do not show up on my screen. I read somewhere that NPOT textures are indexed from 0 to tex-size, not 0 to 1. Is this true?

mark ds
12-18-2009, 10:14 AM
All the info is here

http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt

Quote:

Overview

OpenGL texturing is limited to images with power-of-two dimensions
and an optional 1-texel border. The ARB_texture_rectangle extension
adds a new texture target that supports 2D textures without requiring
power-of-two dimensions.

Non-power-of-two sized (NPOTS) textures are useful for storing video
images that do not have power-of-two sized (POTS). Re-sampling
artifacts are avoided and less texture memory may be required by
using non-power-of-two sized textures. Non-power-of-two sized
textures are also useful for shadow maps and window-space texturing.

However, non-power-of-two sized textures have limitations that
do not apply to power-of-two sized textures. NPOTS textures may
not use mipmap filtering; POTS textures support both mipmapped
and non-mipmapped filtering. NPOTS textures support only the
GL_CLAMP, GL_CLAMP_TO_EDGE, and GL_CLAMP_TO_BORDER wrap modes;
POTS textures support GL_CLAMP_TO_EDGE, GL_REPEAT, GL_CLAMP,
GL_MIRRORED_REPEAT, and GL_CLAMP_TO_BORDER (and GL_MIRROR_CLAMP_ATI
and GL_MIRROR_CLAMP_TO_EDGE_ATI if ATI_texture_mirror_once is
supported) . NPOTS textures do not support an optional 1-texel
border; POTS textures do support an optional 1-texel border.

NPOTS textures are accessed by dimension-dependent (aka
non-normalized) texture coordinates. So instead of thinking of
the texture image lying in a [0..1]x[0..1] range, the NPOTS texture
image lies in a [0..w]x[0..h] range.

This extension adds a new texture target and related state (proxy,
binding, max texture size).

mark ds
12-18-2009, 10:20 AM
Btw - these two resources may be of some help

http://www.opengl.org/sdk/docs/man/

http://www.opengl.org/registry/

openglnub
12-18-2009, 10:39 AM
I was just reading over that, and it does answer some questions. I guess I'm just confused about implementation, since it's still not showing anything.

In my texture generation, I do a check:


if(glewIsSupported("GL_ARB_texture_rectangle"))
{
#ifdef GL_TEXTURE_RECTANGLE_ARB
cout << "NPOT available. Using GL_ARB_texture_rectangle." << endl;
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
if( channels == 3)
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, newData);
}
else if( channels == 4)
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, newData);
}
#endif
}


Then, when drawing, I index the texture from 0 to width and 0 to size. However, nothing is drawn. The output shows that it successfully enters this function.

Is there something else I need to do to use GL_ARB extensions?
This fails with my test 256x256 texture as well, so I'm not sure what's wrong.

EDIT: I don't know if this matters, but "glewIsSupported("GL_ARB_non_power_of_two")" fails. Also, using GL_TEXTURE_RECTANGLE_ARB in the glBindTexture function call produces a lot of "Error: Invalid Value" when drawing.

mark ds
12-18-2009, 11:19 AM
if(glewIsSupported("GL_ARB_texture_rectangle"))
{
#ifdef GL_TEXTURE_RECTANGLE_ARB

cout << "NPOT available. Using GL_ARB_texture_rectangle." << endl;

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

if( channels == 3)
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, newData);
}
else if( channels == 4)
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, newData);
}

#endif
}


Try the above for a start (assuming that your source data is RGB/RGBA and not BGR/BGRA).

How are you drawing the texture_rectangle? Are you using [0-width] rather than [0-1] when specifying each vertex?

openglnub
12-18-2009, 11:23 AM
OK, I figured it out. I was still using the old glEnable code where I actually draw. This needed to also be GL_TEXTURE_RECTANGLE_ARB, not GL_TEXTURE_2D.

mark ds
12-18-2009, 11:27 AM
I don't know if this matters, but "glewIsSupported("GL_ARB_non_power_of_two")" fails...

It should be glewIsSupported("GL_ARB_texture_non_power_of_two")

Are you using the latest drivers?

openglnub
12-18-2009, 11:56 AM
Ok, so GL_ARB_texture_non_power_of_two is supported. Do I use GL_TEXTURE_RECTANGLE_ARB, or is there another texture format I should be using? It fails for my 257x257 image, locking up the program, but not for my 6213x4855 image (??). The bigger images don't display at all. If my video card supports these NPOT textures, why won't they display?

mark ds
12-18-2009, 12:15 PM
Use glGet with GL_MAX_TEXTURE_SIZE to determine whether or not your implementation will hold a 6213 x 4855 image - I'd guess you're probably limited to 4096 x 4096.

openglnub
12-18-2009, 02:33 PM
You're right, max texture size is 4096. I'm at a loss as to the best solution here...I guess it's to create smaller POT textures.

mark ds
12-18-2009, 03:17 PM
Seeing as you support GL_ARB_texture_non_power_of_two, I'd suggest you just use that with GL_NEAREST (and no mipmapping) and create 4 textures (the maths is easy to do this automatically) -

4096x4096 2177x4096
4096x759 2177x759

Don't forget to clamp to edge.