Problem:Reading back 3D Texture using FBO

Hello All,

I am working on GeForce 8800GS card.As clear in the subject, the problem is related to reading back a set of values stored inside a 3D Texture.

The texture is in RGBA format with image type as RGBA and data type as float.

Here is what I am doing:


I am taking the dimensions to be equal that ht=wd=depth
so if ht= 4 then => RGBA texel used = 1
so effective Ht = 1 = Wd = Depth => a unit cube

Main part, after initializing data of length 444 = 64 elements


setTexture(vector_set,0,texsize, texsize) ;
setTexture(mean, 1, texsize, texsize);
setTexture(result_set,2,texsize, texsize) ;


Shaders();

vector_set , mean and result_set are my three arrays.

Then inside shader:


uniform sampler3D Tex_Vec_Set;
uniform sampler3D Tex_Mean;
uniform sampler3D Tex_Result_Set;

uniform float texHeight;
uniform float texWidth ;
uniform float texDepth;

void main()
{

//for now, simple operation of reading in values from T1 and writing it to buffer 3 to result texture 
vec4 Val = vec4(0.0);
vec3 tex_1_coord = vec3(0.0);

tex_1_coord = vec3(gl_TexCoord[0]) ;

Val = texture3D(Tex_Vec_Set , tex_1_coord );

//Val = vec4(tex_1_coord ,0.0);

gl_FragData[2] = Val;

}

and reading data back to check


for (i = 0; i < texsize; i++) // Browse the slices of my 3d texture.
{ 
   glFramebufferTexture3DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_3D, tex[2], 0, i);
			
    glReadBuffer(buffers[2]);

// Read the slice.
    glReadPixels(0, 0, texsize, texsize, GL_RGBA,  GL_FLOAT, result_set); 
}

Supplying information to my shader


texture_location = glGetUniformLocation(p,"Tex_Vec_Set");
		texture_location2 = glGetUniformLocation(p,"Tex_Mean");
		texture_location3 = glGetUniformLocation(p,"Tex_Result_Set");
		tex_height_loc = glGetUniformLocation(p,"texHeight");
		tex_width_loc = glGetUniformLocation(p,"texWidth");
		tex_depth_loc = glGetUniformLocation(p,"texDepth");

		//for generating random data for position texture
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex[0]);
	

		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex[1]);


		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex[2]);


		glDrawBuffers(3, buffers);

        glUniform1i(texture_location,  0);
		glUniform1i(texture_location2, 1); 
		glUniform1i(texture_location3, 2);  

        glUniform1f(tex_height_loc, texsize);  
		glUniform1f(tex_width_loc, texsize);  
		glUniform1f(tex_depth_loc, texsize); 
//draw each slice
for(int k = 0; k < 4 ; k++)
			drawSlice(texsize, texsize , (float)k);

Drawslice is a variant of drawQaud with depth value as third argument.

Result: I am getting all zeros instead of actual data.

I checked the texel coordinates too an they were wrong too, but why thay are wrong is not clear.

init3DTexture()


	int z = 0;

    glEnable(GL_TEXTURE_3D);
	
    glActiveTexture(TU[Tex_Unit]); //activate texture unit to which data would be associate to
  
	glBindTexture(GL_TEXTURE_3D, tex[Tex_Unit]);  //bind or lock texture unit to texture id
    
	
	//set texture parameters
	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);

    //attach data
	//glTexImage3D(GL_TEXTURE_3D, 0 , GL_RGBA_FLOAT32_ATI, texsize , texsize , Depth, 0 , GL_RGBA, GL_FLOAT, pData);
	glTexImage3D(GL_TEXTURE_3D, 0 , GL_RGBA, texsize , texsize , Depth, 0 , GL_RGBA, GL_FLOAT, pData);


//error checking handled 
//and then
 for(z=0; z < Depth; z++)  
		glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, buffers[Tex_Unit], GL_TEXTURE_3D,  tex[Tex_Unit],  0, z);

Please assist me in correcting my program.Thank you.

If you want to read a 3D texture, glGetTexSubImage3D will work just fine. You do not need to bind the FBO or bind the texture to the FBO to do this.

Working now but only for cases where I take W = H = 2.0 and Depth D can be any.

i.e irrespective of 3D texture depth but cross section should be 2*2 units ( irrespective of format)

For testing , I took only one sheet but containing 64 elements (1616 – LUMINANCE or 44 RGBA )

out of which only first 33 elements are non-zero.

My sheet is now a 4 rows by 4 columns RGBA.

Observation:
Only displaying elements of first two cells of first two rows only. i.e elements at cells marked “X” only are displayed.


-------------------------
  X  |  X    |      |
_________________________
  X  |  X    |      |
_________________________
     |      |      |
_________________________
     |      |      |
-------------------------

Checked the texture coordinates and they are only for the above marked cells only. For rest it is 0.

my fragment shader:


uniform sampler3D Tex_Vec_Set;

uniform float texHeight;
uniform float texWidth ;
uniform float texDepth;


void main()
{

//variables local to this function
vec4 Val = vec4(0.0);
vec3 tex_1_coord = vec3(0.0);

tex_1_coord = vec3(gl_TexCoord[2]) ;

tex_1_coord.z = (texDepth == 1.0)? 0.0 : (1.0/texDepth);

//Val = texture3D(Tex_Vec_Set , tex_1_coord);


Val = vec4(tex_1_coord.xyz , 0.0);
gl_FragData[0] = Val;   //output to GL_COLOR_ATTACHMENT0_EXT

}

Need help.

Solved.

Special thanks to “Alfonse Reinheart” . You are right :).

I had used glReadPixels () before as I read somewhere in some other forum that it is faster than glGetTexImage().

But my problem was even more than that and I resolved it fortunately.