PDA

View Full Version : HELP: Can't upload tex3D to GPU !



charmingzuo
12-19-2009, 04:49 AM
Hi, buddies,

I have encountered a strange problem when I am trying to uploading a 3D texture to GPU. The test code is simple as following ,


// code snippets
// enable GLSL program
glUseProgram(glslProgram);
// enable texture x
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, xTexID);
//The following is only for Debugging the texture
float* outData = new float[imgCube];
fill(outData, outData+imgCube, 0.0);
glGetTexImage(GL_TEXTURE_3D, 0, GL_LUMINANCE, GL_FLOAT, outData);
cout <<"Debug: TextureX" <<endl;
copy(outData, outData+imgCube, ostream_iterator<float>(cout, " "));
cout <<endl;
delete outData;
// End debugging
glUniform1i(xParam, 0); // texunit 0


In order to test whether I have successfully created the 3D texture, I specially inserted the test code to fetch data from the tex3D handle "xTexID", and it printed out exactly what I have set. But when it is transfered to the fragment shader by "glUniform1i(...)", the corresponding tex variable in the shader contains only 2 or 3 diffren data which fill the tex by repeating. The following is my test shader,


//shader.frag
#extension GL_ARB_texture_rectangle : enable
uniform sampler3D textureX;

void main(void)
{
vec2 coord2D = gl_TexCoord[0].st;
vec3 coord3D = vec3(coord2D, 0);
vec4 tmpColor = texture3D(textureX, coord3D);
gl_FragColor = tmpColor;
}


My OS system is WinXP SP2 (32bits), OpenGL 3.2 & GLSL1.5. By using of the similar code, when I test the transition using 2D texture, it works well. By for 3D case above, I can't locate where the crux is.

Any indications would be appreciated.
Thank you in advance,

Charmingzuo

charmingzuo
12-19-2009, 04:58 AM
BTW, the size of the tex3D is simple, only for test, width*height*depth = 16*16*2 . Acturally, it is said that the type GL_TEXTURE_3D can handle data with size both power and non-power of 2.

Alfonse Reinheart
12-19-2009, 10:47 AM
glGetTexImage(GL_TEXTURE_3D, 0, GL_LUMINANCE, GL_FLOAT, outData);

This function downloads data from the texture to your memory. Hence the word "Get" in the title.

The function to upload data from your memory to the texture is glTexImage3D.

charmingzuo
12-19-2009, 05:38 PM
glGetTexImage(GL_TEXTURE_3D, 0, GL_LUMINANCE, GL_FLOAT, outData);

This function downloads data from the texture to your memory. Hence the word "Get" in the title.

The function to upload data from your memory to the texture is glTexImage3D.

Alfonse, Thank you for your reply.
Sorry I didn't make the post simple and clear.
In my original post, I use a indent code with comment line to
indicate the Debugging ONLY ("//The following is only for
Debugging the texture" and "//End..."). Therefore, the function
glGetTexImage is only to get the data from the tex3D to
validate the data. And this debugging tell me tex3D contains
exactly what I set and what I want. I took for granted that after glUniform1i...
operation, the "textureX" in the shader should be the same (exept some
precision error) as xTexID outside the shader. But I am definitely wrong.
When step into the shader by debugging using glslDevil, the tex3D in the shader
is as the same as the glReadPixels... results. So, I think the
created 3D texture didn't successfully transfered into the
shader. But, I don't know why.

here are some details,


// code snippets...
//Create Tex3D
glGenTextures(1, texID);
glBindTexture(GL_TEXTURE_3D, *texID);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE32F_ARB, w, h, d, 0,
GL_LUMINANCE, GL_FLOAT, dataX);

// ......
// Export from FBO after rendering
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, imgW, imgH, GL_LUMINANCE,GL_FLOAT, data);
// .......


The size of the tex3D is simple, only for test, width*height*depth = 8*8*2 = imgCube.
Acturally, it is said that the type GL_TEXTURE_3D can handle data with size
both power and non-power of 2.

The tex3D "xTexID" is initialized by an array, dataX,


for (int i=0; i<imgCube; i++)
{
dataX[i] = i+0.321;
}


But when it is trasfered out from the shader, it becomes some duplicate data
series, as


36.321 39.321 39.321 39.321 39.321 39.321 39.321 39.321 60.321 63.321 63.321
63.321 63.321 63.321 63.321 63.321 60.321 63.321 63.321 63.321 63.321 63.321
63.321 63.321 60.321 63.321 63.321 63.321 63.321 63.321 63.321 63.321 60.321
63.321 63.321 63.321 63.321 63.321 63.321 63.321 60.321 63.321 63.321 63.321
63.321 63.321 63.321 63.321 60.321 63.321 63.321 63.321 63.321 63.321 63.321
63.321 60.321 63.321 63.321 63.321 63.321 63.321 63.321 63.321


All the data format of the texture are in GL_LUMINANCE style.

Going crazy...

charmingzuo
12-20-2009, 05:53 AM
It seems that this forum can't support attached files for the post,
so if you guys have any interest in solving this problem, please drop me
a note and I will send the whole project to you. (This project is only
for testing tex3D, so it is very samll and clear.)

Ilian Dinev
12-20-2009, 06:17 AM
Use Drop-box :)
https://www.dropbox.com/

charmingzuo
12-25-2009, 07:41 PM
Hi, guys,

I got it solved!
Since the tex3D in OpenGL/GLSL only support uniform coordinate,
the draw method can only be:


glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex2f(imgW, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex2f(imgW, imgH);
glTexCoord2f(0.0, 1.0);
glVertex2f(0.0, imgH);
glEnd();


Thanks,
Nicozuo