PDA

View Full Version : Loading and reading a floating point texture



AvCol
01-26-2011, 09:43 PM
Hi all.

I am currently using a lookup table to make some integral go faster in my application. To do this I load up a .csv file containing floating point values and then attempt to create a floating point texture using that like so.



int numCSVs = 0;
float* texData = harvesterPtr->loadCSV("tableF.csv", numCSVs);
int texDim = sqrt(float(numCSVs));

glGenTextures(1, &textureF);
glBindTexture(GL_TEXTURE_2D, textureF);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, texDim, texDim, 0, GL_RED, GL_FLOAT, texData);


The CSV contains a block of 512 * 512 values and on inspection "texData" contains the right values in a single array sized 262144. Moreover, texDim evaluates to 512 as expected.

In my shader this texture is declared as:


uniform sampler2D textureF;

and to set it in my application I use



glUseProgram(direct);
glUniform1i(glGetUniformLocation(direct, "textureF"), 4);


during the draw loop I have



glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, textureF);


When I simply output texture vals using



radiance.rgb = vec3(texture(textureF, texCoords).s, texture(textureF, texCoords).s, texture(textureF, texCoords).s);


While drawing a full screen quad, it seems to just read 0 values. Other textures are displayed just fine.

Am I forgetting something glaringly obvious? The csv table values aren't clamped to 0 to 1, would this have something to do with it?

Help would be greatly appreciated

mobeen
01-26-2011, 10:47 PM
Try this add this


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

after you bind your texture but befre u call glTexImage2D
and output in shader like this


float red = texture(textureF,texCoords).r;
radiance.rgb = vec3(red);

AvCol
01-26-2011, 10:54 PM
Thank you!

It was the filter!

Why does a filter need to be set? I had always assumed the default filter was GL_NEAREST and that not setting a filter assumed that.

I have set up textures in the past (the ones attached to my FBO) with no filter without any trouble. The only difference between those and the one mentioned here is the pointer to the data in the FBO textures is always NULL.

Why does openGL mandate setting a filter when the data pointer is not NULL?

Once again thank you for your help mobeen.

mobeen
01-26-2011, 11:02 PM
Well the filtering is implementation dependent read this (http://www.opengl.org/registry/specs/SGIS/texture_filter4.txt) . You cannot be sure whether the default texture filter will be linear or nearest. Therefore, it's always better to explicitly give it.

Alfonse Reinheart
01-27-2011, 02:11 AM
radiance.rgb = vec3(texture(textureF, texCoords).s, texture(textureF, texCoords).s, texture(textureF, texCoords).s);

Don't do this. Every time you call "texture(textureF, texCoords)," you're accessing the texture. There's no need to do it 3 times just to get one value.

All you need to do is this:


radiance.rgb = texture(textureF, texCoords).rrr

You really should read the GLSL specification to see how the language works. It has many vector features which are not commonly available in C/C++, but are crucial for good performance in GLSL.


Why does openGL mandate setting a filter when the data pointer is not NULL?

It doesn't. You need to set the filtering parameters in order to get the filtering that you want rather than the default.


Well the filtering is implementation dependent read this .

No it's not. That spec is for an extension, one that isn't widely implemented. Except for the specific nature of how anisotropic filtering is done, the procedure for filtering is very clearly spelled out by the specification.


You cannot be sure whether the default texture filter will be linear or nearest.

Um, yes you can. The spec is quite clear on this. The default mag filtering is GL_LINEAR, and the default min filtering is (for some reason) GL_NEAREST_MIPMAP_LINEAR (except for textures that can't have mipmaps, in which case it is GL_LINEAR).

mobeen
01-27-2011, 02:43 AM
Thanks for the correction Alfonse but if the default min filter is linear, why it doesnt work if he does not specify?

ZbuffeR
01-27-2011, 05:10 AM
The default min filter is GL_NEAREST_MIPMAP_LINEAR, so by default you have to provide texture mipmaps, otherwise, texture is invalid.

mobeen
01-27-2011, 05:34 AM
COOL. Thanks ZBUFFER.

AvCol
01-28-2011, 05:33 PM
Don't do this. Every time you call "texture(textureF, texCoords)," you're accessing the texture. There's no need to do it 3 times just to get one value.

All you need to do is this:

Thanks for the .rrr tip and also the initializer tip from mobeen. I know that texture reads are slow. See I usually store texture lookups in a temp variable, but this was just debugging "lets output this as a color to see whats going on" code. That texture is a lookup texture for the airlight model so obviously I'd never attempt to display it otherwise.



The default mag filtering is GL_LINEAR, and the default min filtering is (for some reason) GL_NEAREST_MIPMAP_LINEAR (except for textures that can't have mipmaps, in which case it is GL_LINEAR).




The default min filter is GL_NEAREST_MIPMAP_LINEAR, so by default you have to provide texture mipmaps, otherwise, texture is invalid.


Thats weird. I set up my frame buffer attachment textures like so:

glBindTexture(GL_TEXTURE_2D, gNormal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, wWidth, wHeight, 0, GL_RGB, GL_FLOAT, NULL);

glBindTexture(GL_TEXTURE_2D, gAlbedo);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wWidth, wHeight, 0, GL_RGBA, GL_FLOAT, NULL);

glBindTexture(GL_TEXTURE_2D, gMaterial);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wWidth, wHeight, 0, GL_RGBA, GL_FLOAT, NULL);

With no calls to change the tex paramaters away from the default and no call to genMipmaps, an they work fine. Yet any texture that does not take a null data pointer requires me to do either of the two.