Fisrst shader does not take effect

Hi, All.
following is the piece of my testing code used to handle ping-pong.
The problem is, the drawing result shows that the first shader (pingpongShaderProgram, render to FBO)did not take effect. When I remove the second shader( renderShaderProgram), the first shader took effect. could anybody please explain the reason?

setting FBO

glGenFramebuffersEXT(1, &my_fbo_tex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);

// init texture for FBO
glGenTextures( 1, & my_pp_tex);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, texW, texH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

// bind texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
                          GL_COLOR_ATTACHMENT0_EXT, 
                          GL_TEXTURE_RECTANGLE_ARB,my_pp_tex,0);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

using FBO

glUseProgramObjectARB(pingpongShaderProgram);
// render to FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);

glPushAttrib(GL_VIEWPORT_BIT);
// set projection && modelview
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, myMaxTextureSize[0], 0, myMaxTextureSize[1]);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glViewport(0, 0,myMaxTextureSize[0], myMaxTextureSize[1]);

int pptexture = glGetUniformLocationARB(pingpongShaderProgram, "ppTexture");
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, my_test_tex);


glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0   ,   0.0);
glTexCoord2f(1.0, 0.0); glVertex2f(myMaxTextureSize[0] ,   0.0);
glTexCoord2f(1.0, 1.0); glVertex2f(myMaxTextureSize[0] ,  myMaxTextureSize[1]);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0   , myMaxTextureSize[1]);
glEnd();

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();


glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


glUseProgramObjectARB(renderShaderProgram);

//
//
// use FBO texture
glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT);

// glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);


int fbtexture = glGetUniformLocationARB(renderShaderProgram , "fbtexture");
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, my_pp_tex);

pingpongShaderProgram:
"
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
"

renderShaderProgram:
"
void main(void)
{
vec4 color = vec4(0.0);
color = texture2D(fbtexture, gl_TexCoord[0].st);
gl_FragColor = color;
}
"

When use both shaders, I am expecting that finally a red image is displayed, but I got my_test_tex pattern.

tks

You are binding my_pp_tex to the GL_TEXTURE_2D target but it is of type GL_TEXTURE_RECTANGLE_ARB. Don’t forget to check for OpenGL errors and remember that the texture coordinates for GL_TEXTURE_RECTANGLE_ARB are in the range [0…w]x[0…h] instead of [0…1]x[0…1].

N.

did not get it.

I made the change by " glBindTexture(GL_TEXTURE_2D, my_pp_tex);"
but still got same result.
Also, for my program. Because I set the color to (1.0, 0.0,0.0, 1.0) in the first shader. I think that the image in my_pp_tex should be all red.
therefore the final image should be red too.
how come I got the original input image pattern?

There are some fundamental differences between GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE_ARB.

Here’s what you’re doing:

  • Activate FBO //no error
  • glBindTexture(GL_TEXTURE_2D, my_test_tex) //no error
  • Deactivate FBO //no error
  • glBindTexture(GL_TEXTURE_2D, my_pp_tex) //error!!!

my_pp_tex is not of type GL_TEXTURE_2D because you have set it up to be of type GL_TEXTURE_RECTANGLE_ARB here:


 glGenTextures( 1, & my_pp_tex);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, texW, texH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

Because glBindTexture(GL_TEXTURE_2D, my_pp_tex) fails, my_test_tex will still be bound to GL_TEXTURE_2D and not my_pp_tex. That’s why you see the original texture.

If you want to use texture rectangles, change
glBindTexture(GL_TEXTURE_2D, my_pp_tex)
to
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex)
and change the texture coordinates like I said in my previous post.

If you’re using shaders, don’t forget you need different sampler types for 2D and rectangular textures.

If you don’t want to use texture rectangles, replace all GL_TEXTURE_RECTANGLE_ARB with GL_TEXTURE_2D. If the size of my_pp_tex is not a power of two you will need to have support for GL_ARB_texture_non_power_of_two.

N.

thank you so much for detailed explanation.

Now the problem I have is:
I changed all the GL_TEXTURE_RECTANGLE_ARB to GL_TEXTURE_2D when I init the my_pp_tex. I got assertion error: " assert(status == GL_FRAMEBUFFER_COMPLETE_EXT); fails".

When I change glBindTexture(GL_TEXTURE_2D, my_pp_tex) call to
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex). nothing change.

any clue?

Are you sure you replaced all the GL_TEXTURE_RECTANGLE_ARB entries?
What’s the size of your my_pp_tex texture?
What’s the actual status value returned?

N.

testure size 512* 512 fixed
more code:

//-----------

myMaxTextureSize[1] = 512; texW = 512;
myMaxTextureSize[0] = 512; texH = 512;
unsigned char * myData = (unsigned char*) malloc(myMaxTextureSize[0] * myMaxTextureSize[1] sizeof(unsigned char));
// init texture info
for(int row = 0; row <myMaxTextureSize[1] ; row++)
{
for( int col = 0; col < myMaxTextureSize[0]; col++ )
{
int pos = row
myMaxTextureSize[0] + col;

	if( row % 16 == 0 || col % 16 == 0)
	{
	    myData[pos] = 64;
	}
	else myData[pos] = 0;
    }
}
glGenTextures(1, & my_test_tex);
glBindTexture(GL_TEXTURE_2D, my_test_tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myMaxTextureSize[0] , myMaxTextureSize[1] , 0,
	     GL_LUMINANCE, GL_UNSIGNED_BYTE, myData);
//-----------


///////////////////////////////////////////////////////////////////////////
// ping pong smoothing
///////////////////////////////////////////////////////////////////////////
// init FBO
glGenFramebuffersEXT(1, &my_fbo_tex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);

// init texture for FBO
glGenTextures( 1, & my_pp_tex);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, texW, texH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

// bind texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
                          GL_COLOR_ATTACHMENT0_EXT, 
                          GL_TEXTURE_RECTANGLE_ARB,my_pp_tex,0);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);

glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

================================================================
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glUseProgramObjectARB(pingpongShaderProgram);
glUseProgramObjectARB(0);
// render to FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo_tex);

glPushAttrib(GL_VIEWPORT_BIT);
// set projection && modelview

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, myMaxTextureSize[0], 0, myMaxTextureSize[1]);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glViewport(0, 0,myMaxTextureSize[0], myMaxTextureSize[1]);

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 
int pptexture = glGetUniformLocationARB(pingpongShaderProgram, "ppTexture");
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, my_test_tex);


glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0   ,   0.0);
glTexCoord2f(1.0, 0.0); glVertex2f(myMaxTextureSize[0] ,   0.0);
glTexCoord2f(1.0, 1.0); glVertex2f(myMaxTextureSize[0] ,  myMaxTextureSize[1]);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0   , myMaxTextureSize[1]);
glEnd();

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();


glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


glUseProgramObjectARB(shaderProgram);

//
//
// use FBO texture
glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT);

// glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);


int fbtexture = glGetUniformLocationARB(shaderProgram , "fbtexture");
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, my_pp_tex);

===============================================================

glUseProgramObjectARB(pingpongShaderProgram);
glUseProgramObjectARB(0);

Is it your intention to disable the shader with the second call?

Check if the data values are red with a readpixels call before your glPopMatrix();

And don’t forget about OpenGL error checking.


static void
 checkErrors()
{

    GLenum error;

    while ((error = glGetError()) != GL_NO_ERROR) {

        fprintf(stderr, "Error: %s
", (char *) gluErrorString(error));

    }

}

N.

sorry, my mistake to put glUseProgramObjectARB(0) on there.
have it taken out.

CheckErrors() never give me anything out.
I added
"
unsigned char result = (unsigned char) malloc(myMaxTextureSize[0] * myMaxTextureSize[1] *sizeof(unsigned char));
//
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, myMaxTextureSize[0], myMaxTextureSize[1],GL_LUMINANCE,GL_UNSIGNED_BYTE,result);
// print out results
for (int i=0; i< 512; i++)
printf("%u ",result[i]);

cout&lt;&lt; endl;

delete [] result;

"
right after glEnd() and before glPopMatrix(), the output shows that my first shader is kind of working ( I always get 255 for gl_FragColor= vec4( 1.0, 0.0, 0.0, 1.0); and I got all 192s for gl_FragColor=texture2D( ppTexture, gl_TexCoord[0].st); even I was expecting something like 192 0 0… 192 0… 192).

But my final out put always only display the input patterns no matter what i did to the first shaders.

tks

You’re trying to do too much at once. Apparently the part that’s drawing to the FBO is already wrong, so why don’t you start there and worry about the final output later.

When drawing to offscreen FBOs it’s best to check the output by drawing it to the main framebuffer instead of the FBO so that you can see the result of the offline computations.

It’s also hard for us to understand the problem with limited code. e.g. I see a call to
int pptexture = glGetUniformLocationARB(pingpongShaderProgram, “ppTexture”);
but you never actually use pptexture.

N.

sorry for the confusing. because this is only a small part of my code ( I am try to use FBO to smooth textures for better performance and smoothing result), can’t put all the code on.

The modified shader to test write to FBO is:
uniform sampler2D ppTexture;

void main()
{
vec4 color = vec4( 1.0, 1.0, 0.0, 1.0);
if( gl_TexCoord[0].s <0.2)
color = vec4( 1.0, 0.0, 0.0, 1.0);
else
color = texture2D( ppTexture, gl_TexCoord[0].st);
gl_FragColor = color;
//gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0);
}

the changes here can be seen from the output of glReadPixels results.

yes, I agree “drawing to the FBO is already wrong”, but really don’t know why?

tks

Why don’t you check your algorithm with a passthrough operation first?

void main()
{
gl_FragColor = texture2D( ppTexture, gl_TexCoord[0].st);
}

and use the shader to draw to the screen instead of the FBO for checking purposes.

Also, be careful when using luminance. You’re replicating your luminance values to the r g and b components of your texture when uploading and readpixels takes the sum of the r g and b values when retrieving the rgba data as luminance values.

N.

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