5th texture displays fine in window, on FBO not

Hello,

I am relatively new to openGl and GPGPU. I am trying to implement an algorithm which needs input for 5 or more texture images to calculate the result.

I have this small problem. I use 5 textures for my input in a GPGPU computation. If i render the each texture using the shader like gl_gl_FragColor=(texture5,1) it shows just fine.

But if i use fbo i get a -1#INF. I though that the problem using more than 4 textures on a FBO was if you used attachmentpoints not binding the with uniform variables like this:

glActiveTexture(GL_TEXTURE4);
glBindTexture( GL_TEXTURE_2D, texture5 );
texLoc = glGetUniformLocation(ShaderProgram, “tex5”);
glUniform1i(texLoc, 4);

Anyone can shed some light? It would be really appreciated.
Thanks in advance

“gl_gl_FragColor=(texture5,1)”

That doesn’t look like valid GLSL syntax to me…
Did you validate your FBO before rendering to it?

Yes. I check if it works ok every step, and it says it is complete. Sorry i was not good at copy paste with that part:p… I have : gl_FragColor = vec4 (texture5,1); where avg is the float value i need back.

The weird is that on screen its ok, but on fbo it gives me that value back. SO it should work. I ll recheck the whole process of creating and binding the fbo.

What kind of graphics card are you using? Maybe the card only has 4 texture units and this problem doesn’t show up if you draw them one by one. Can you post the fragment shader, FBO setup and rendering call?

I use 7600GT. But if i draw it on screen it works ok…why it wouldnt work if it was drawn on fbo? The code is:

Fragment shader (i deleted most of the stuff and just left it to return the texture5, i checked and the problem again is there)

uniform sampler2D tex;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D tex4;
uniform sampler2D tex5;

uniform float Threshold;
uniform float WashInStart;
uniform float WashInPoints;

varying vec2  TexCoord; 

void main(void)
{
    float dectimeStart=0.0180;
	float dectime=0.0120;
  	vec3 A = (0.1,0.0,0.0);
    float enchant=0.0;
    float mVal=0.0;
	float LocalWashInStart=0.0;
	float Delay=0.0;
	float EarlyStart=0.0;
	float EarlyFinish=0.0;
	float EarlyEnchancementAvg=0.0;
	
	
    vec3 textureColor1  =texture2D(tex, TexCoord).rgb;
    vec3 textureColor2 = texture2D(tex2,TexCoord).rgb;
    vec3 textureColor3 = texture2D(tex3,TexCoord).rgb;
    vec3 textureColor4 = texture2D(tex4,TexCoord).rgb;
    vec3 textureColor5 = texture2D(tex5,TexCoord).rgb;

	float tmp=textureColor5.r;
	gl_FragColor = vec4 (tmp,0.0,0.0,1.0);
    
}

The code for FBO is:
(This works for every texture except 5 :()

// Set up the viewport for 1:1 pixel to texel mapping
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, size , 0.0, size);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0, 0, size, size); 


	//FBO creation
	GLuint fbo;
	glGenFramebuffersEXT(1, &fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
	glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 
	checkGLErrors("FBO creation or Binding");
	checkFramebufferStatus();
	
	
	
	//Setup output texture
	GLuint img;
	glGenTextures(1, &img);
	glBindTexture(GL_TEXTURE_2D, img);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB,  size, size, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
	glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size,size,GL_RED,GL_FLOAT,data);

	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);
	checkFramebufferStatus();	
	checkGLErrors("Output Texture Creation");



	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  	checkGLErrors("Frame Buffer binding");
	checkFramebufferStatus();

	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 
	glPolygonMode(GL_FRONT, GL_FILL); 
	glBegin( GL_QUADS );
	    glTexCoord2f(0.0, 1.0); 
		glVertex2f(0.0, 0.0);
		glTexCoord2f(1.0, 1.0); 
		glVertex2f(size, 0.0);
		glTexCoord2f(1.0, 0.0);
		glVertex2f(size, size);
		glTexCoord2f(0.0, 0.0); 
		glVertex2f(0.0, size);
	glEnd();
	
	checkFramebufferStatus();
	checkGLErrors("Render to FBO");

	//Reading values from frameBuffer to array with flaots
	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	glReadPixels(0, 0, size, size,GL_RED,GL_FLOAT,pixels);
	


	writeFile("Output1.dat",data,size);
	printVector(data,1024*1024);
	
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	checkGLErrors("Frame Buffer unbinding");
	
	glDeleteTextures(1,&img);

	glActiveTexture(GL_TEXTURE0);	
	glBindTexture( GL_TEXTURE_2D, texture1 );

	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,size,0.0,size);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,0,size,size);

	glTranslatef(0.0,0.0,-24); // We move the object 24 points forward to fill the window
	glBegin( GL_QUADS );
	{
	  glTexCoord2f(0.0, 0.0); 
		glVertex2f(0.0, 0.0);
		glTexCoord2f(1.0, 0.0); 
		glVertex2f(size, 0.0);
		glTexCoord2f(1.0, 1.0);
		glVertex2f(size, size);
		glTexCoord2f(0.0, 1.0); 
		glVertex2f(0.0, size);
	}
	glEnd();
	


	glDeleteFramebuffersEXT(1, &fbo);
	free(data);
	glUseProgram(0);
        checkGLErrors("Render on Screen");
	exit(1);

You see something that may lead to this? I now that the code may have a lot of problems but i am new to this.:blush:

At first sight I don’t see anythingw rong with the code except for the fact that you probably meant to write

//Reading values from frameBuffer to array with flaots
[b]glReadBuffer/b;
glReadPixels(0, 0, size, size,GL_RED,GL_FLOAT,pixels);

instead of

//Reading values from frameBuffer to array with flaots
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, size, size,GL_RED,GL_FLOAT,pixels);

Are you sure you set up texture5 the same way you did the others?

I call the same function to create and setup each texture. I never undestood though why i have to use glActiveTexture(GL_TEXTURE0);
And i mean TEXTURE0 means is the 1st it was setup? And TEXTURE1 the second? And just go on?

This is the code where i bind the uniform variables-textures to shader

	
        glActiveTexture(GL_TEXTURE0);	
	glBindTexture( GL_TEXTURE_2D, texture1 );
	texLoc = glGetUniformLocation(ShaderProgram, "tex1");
	glUniform1i(texLoc, 0);

	glActiveTexture(GL_TEXTURE1);	
	glBindTexture( GL_TEXTURE_2D, texture2 );
	texLoc = glGetUniformLocation(ShaderProgram, "tex2");
	glUniform1i(texLoc, 1);

   
	glActiveTexture(GL_TEXTURE2);	
	glBindTexture( GL_TEXTURE_2D, texture3 );
	texLoc = glGetUniformLocation(ShaderProgram, "tex3");
	glUniform1i(texLoc, 2);

	glActiveTexture(GL_TEXTURE3);	
	glBindTexture( GL_TEXTURE_2D, texture4 );
	texLoc = glGetUniformLocation(ShaderProgram, "tex4");
	glUniform1i(texLoc, 3);

	glActiveTexture(GL_TEXTURE4);	
	glBindTexture( GL_TEXTURE_2D, texture5 );
	texLoc = glGetUniformLocation(ShaderProgram, "tex5");
	glUniform1i(texLoc, 4);

That code looks fine,but I see that you call

texLoc = glGetUniformLocation(ShaderProgram, “tex1”);

while there’s no “tex1” in your fragment shader…

This is weird. It was wrong but it worked just fine:$. I fixed that but my problem still remains:(

Well, from the code you posted I can’t see what’s wrong. If you can write a small glut-based app illustrating the problem than I’d be happy to take a look at it.

A question:
In this code:

glActiveTexture(GL_TEXTURE0);	
	glBindTexture( GL_TEXTURE_2D, texture1 );
	tex1Loc = glGetUniformLocation(ShaderProgram, "tex1");
	glUniform1i(tex1Loc, 0);

	glActiveTexture(GL_TEXTURE1);	
	glBindTexture( GL_TEXTURE_2D, texture2 );
	te1xLoc = glGetUniformLocation(ShaderProgram, "tex2");
	glUniform1i(tex1Loc, 1);

glUniform1i(tex1Loc, 0);
and
glUniform1i(tex1Loc, 1);
Why we use 0 and 1 at the other? I was thinking that i should i use 1 only if my textures was create with genTexture(2,nameOftexture)

Shouldnt it be at both 0?

The glActiveTexture() call selects the texture unit to activate, so the glBindTexture() calls binds the texture to the GL_TEXTURE_2D target of the active texture unit. The second parameter you pass to glUniform1i() refers to the texture unit. That’s what I remember anyway, I prefer using Cg instead of GLSL.

The glGenTextures call has nothing to do with texture units, it’s just a means to create multiple texture objects at once.

The call to create and setup textures:

glGenTextures( 1, &texture1 );
	init2DTexture("texture1",texture1,size,size,buffer);
	free(buffer);

	filename = ".//2.dcm.png";
	buffer=loadPNG(filename);
	glGenTextures( 1, &texture2 );
	init2DTexture("texture2",texture2,size,size,buffer);
	free(buffer);

	filename = ".//3.dcm.png";
	buffer=loadPNG(filename);
	glGenTextures( 1, &texture3 );
	init2DTexture("texture3",texture3,size,size,buffer);
	free(buffer);

	filename = ".//4.dcm.png";
	buffer=loadPNG(filename);
	glGenTextures( 1, &texture4 );
	init2DTexture("texture4",texture4,size,size,buffer);
	free(buffer);

	filename = ".//5.dcm.png";
	buffer=loadPNG(filename);
	glGenTextures( 1, &texture5 );
	init2DTexture("texture5",texture5,size,size,buffer);
	free(buffer);

the actual function that does this:

void init2DTexture(char *textureName,GLint texName,GLint texWidth,GLint texHeight,unsigned char *texPtr)
{
	//Binding texture
	glBindTexture(GL_TEXTURE_2D, texName);

	//Settng Parameters for texture
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	//Moving data to Texture
	//	glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F_ARB,size,size,0,GL_RGBA,GL_FLOAT,texPtr);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, texPtr);
	char errormsg[50];
	sprintf(errormsg,"Error creating or Binding texture: %s ",textureName);
	checkGLErrors(errormsg);
}

But this does nto explain why i can see it in opengl window if i render it and not in FBO.

That depends. Since you’re using a float texture in FBO there can be some other pitfalls like trying to print out float values using printf with “%d” in the regexp instead of “%f” or something else. Maybe you can try clearing the FBO color to some arbitrary clearcolor and then read back the result. If it matches, you know that both the FBO and your readback function to check the results are working before moving on.

Soz for flooding. But i discovered something weird. If i create a new texture after the 5th. And bind same data to it. I can use normally texture5 on FBO and on screen. The last one gives the same error though. But at least i can make my computations until i can think what the problem is.:stuck_out_tongue:

Thanks a lot -Nico- although i d love to find out what the real problem is.

I think you have right about the clearing of colour. IIRC when i was reading back some empty fbos i got the value -413xxx soemthing. I made some changes to internal format of textures and i suppose tha teh -1#FFF must be the empty FBO. I ll try clearing to something and see again:p

Good luck! :slight_smile: Let us know when you found it.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.