PDA

View Full Version : Getting long values from CPU to GPU with usampler?



Stefan Bechtold
08-19-2010, 04:49 AM
Hey everybody,

I am new registered with the forum but have been reading a lot of posting about image formats and samplers. Still I do have problems with transferring my bits from CPU to GPU and I hope I can find some help here.

My application stores some values within a texture which is defined as a long array (on CPU). Each long value represent a 32 bit value that can be

a) a color with 8 bits per channel or
b) an integer value.

(if it is an integer value the first to bits are used as flags, but this fact has nothing to do with the problem I have)

I would like to get all bytes as unsigned values between 0..255 within the GLSL shader, so that I can reconstruct the original data by multiplying the components accordingly, e.g.:


uvec4 bytes = usamper(...);
int value = (((bytes.r * 255) + bytes.g) * 255) + bytes.b) * 255 + bytes.a;


Actually I have the following setup:

Texture Data on CPU (as long array):


long *this->dummyTex = new long[4];
this->dummyTex[0] = 0xFF0000FF; //red
this->dummyTex[1] = 0x00FF00FF; //green
this->dummyTex[2] = 0x0000FFFF; //blue
this->dummyTex[3] = 0x7F7F7FFF; //gray


Loading Texture to GPU


// Create new texture ids
GLuint texture;
glGenTextures(1, &texture);

// Set texture parameters for texture 1
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// Update image data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);


Use of Sampler and texelFetch in GLSL:


#version 130
#extension GL_EXT_gpu_shader4 : enable

uniform sampler2D TextureData;
out vec4 outColor;

void main() {
outColor = texelFetch(TextureData2, ivec2(0, 0), 0)
}


This works fine, because the color is shown correctly, but the values returned by texelFetch are floating point values between 0..1. I tried GL_RGBA_INTEGER as format already, but this results in all values are set to zero.

What do I have to change to get the byte data (values between 0..255) out of the sampler correctly?

Thanks in advance for any suggestions.

bechte

Dark Photon
08-19-2010, 05:46 AM
My application stores some values within a texture which is defined as a long array (on CPU). Each long value represent a 32 bit value
long == 32-bits implies you are compiling for a 32-bit CPU target. On 64-bit CPU target, long = 64-bits.


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
I would use GL_RGBA8 as the internal format to make sure you get the format you intend (though you probably will by default).



uniform sampler2D TextureData;
out vec4 outColor;

void main() {
outColor = texelFetch(TextureData2, ivec2(0, 0), 0)
}
This works fine, because the color is shown correctly, but the values returned by texelFetch are floating point values between 0..1.
See the GLSL spec for texelFetch and gvec4. You need to use usampler2D instead of sampler2D.

Alfonse Reinheart
08-19-2010, 01:04 PM
What do I have to change to get the byte data (values between 0..255) out of the sampler correctly?

1: Create your texture using the GL_RGBA8UI image format (http://www.opengl.org/wiki/Image_Formats).

2: Use the type "usampler" in GLSL instead of "sampler".

That's all.

ScottManDeath
08-21-2010, 02:07 AM
long == 32-bits implies you are compiling for a 32-bit CPU target. On 64-bit CPU target, long = 64-bits.


On Windows 64 bit, int and long are 32 bit, long long int and the pointers are 64 bit.

http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

Stefan Bechtold
08-23-2010, 03:03 PM
Thank you very much for your answers.
It finally worked with an usampler2D and the following code:



glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data);


While I am on Windows using little endian, I read the values with the following shader code to reorder the components:



uvec4 data = texelFetch(TextureData, ivec2(x, y), 0).abgr;


Thanks again for your help!
bechte