weird behaviour for ping-ponging

Hello

I’m doing some ping ponging stuff and I am experiencing some weird behaviour with my code. I have 2 shaders which alter the texture and a third one which just displays stuff.

I have a certain number of passes in my program which i can increase and decrease (to make sure that the ping-ponging work). According to my logic, if the number of passes is 0, the color displayed should be black, for 1 pass it should be black, for 2 passes red, for 3 passes yellow, 4 passes orange, …

However, for 2 passes I’m already getting yellow.

Any help would be very greatly appreciated. Been stuck with that for some time!!!

The important part of the code is below:

//some global variables
unsigned char textureArray[4512512];

int numberIterations = 0;
GLuint tex_id[2];
GLenum attachmentpoints[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
int writeTex = 0;
int readTex = 1;
GLuint frameBuffer;
int textureDim = 512;

string shaderPath = “/Users/pascalgrosset/Utah/Research/myVolRender/pingponging/pingponging/”;

bool panSc, zoomSc, rotateSc;
float eye[3], lookat[3];

GLint buf_1, buf_2, buf_Out;

GLhandleARB glsl_program1, vertex_shader_1, fragment_shader_1;
GLhandleARB glsl_program2, vertex_shader_2, fragment_shader_2;
GLhandleARB glsl_programOut, vertex_shader_Out, fragment_shader_Out;

// main
int main(int argc, char* argv[])
{
glutInit(&argc, argv);

if (argc > 1)
numberIterations = atoi(argv[1]);

glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition( 50, 50);
glutInitWindowSize( windowWidth, windowHeight);

//createGlutMenu();
main_window = glutCreateWindow( “Computer Graphics” );
myInitDisplay(windowWidth, windowHeight);

eye[0] = 0.0;		eye[1] = 0.0;		eye[2] = 2.0;

lookat[0] = 0.0; lookat[1] = 0.0; lookat[2] = 0.0;

panSc = zoomSc = rotateSc = false;


createShaders(glsl_program1, vertex_shader_1, fragment_shader_1, (shaderPath + string("Shaders/shader.vert")).c_str(), (shaderPath + string("Shaders/fragShader1.frag")).c_str());
createShaders(glsl_program2, vertex_shader_2, fragment_shader_2, (shaderPath + string("Shaders/shader.vert")).c_str(), (shaderPath + string("Shaders/fragShader2.frag")).c_str());
createShaders(glsl_programOut, vertex_shader_Out, fragment_shader_Out, (shaderPath + string("Shaders/shader.vert")).c_str(), (shaderPath + string("Shaders/fragShaderOut.frag")).c_str());

initGL();

// Register some callbacks - basically what function is to be associated to what event

glutDisplayFunc( myDisplay );
glutReshapeFunc( myReshape );
glutIdleFunc( myGlutIdle );
glutKeyboardFunc( myKeyboard );
glutMotionFunc( myMotion );
glutMouseFunc( myMouse );

glutMainLoop();

glDeleteFramebuffersEXT(1, &frameBuffer);

return 0;
}

void myInitDisplay( int width, int height )
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background and set its Color To Black - 4 params coz of RGBA

glDepthFunc( GL_LESS ); // The Type Of Depth Test To Do
glEnable( GL_DEPTH_TEST ); // Enables Depth Testing
glShadeModel( GL_SMOOTH ); // Enables Smooth Color Shading - GL_SMOOTH or GL_FLAT

glutSetMenu( mainMenuId ); // We have a menu
glutAttachMenu( GLUT_RIGHT_BUTTON ); // Attach the menu to the right mouse button

return;
}

void initGL(){
glEnable(GL_TEXTURE_2D);

for (int i=0; i<(textureDim*textureDim); i++)
textureArray[i*4 +0] = textureArray[i*4 +1] = textureArray[i*4 +2] = textureArray[i*4 +3] = 0;

glGenTextures(2, tex_id);
for (int i=0; i<2; i++){
glBindTexture(GL_TEXTURE_2D, tex_id[i]);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//NULL means reserve texture memory, but texels are undefined
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureDim, textureDim, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureArray);
}

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

// attach two textures to FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentpoints[writeTex], GL_TEXTURE_2D, tex_id[writeTex], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentpoints[readTex], GL_TEXTURE_2D, tex_id[readTex], 0);


GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status == GL_FRAMEBUFFER_COMPLETE_EXT){
    //	cout &lt;&lt; "All Good!!!" &lt;&lt; endl;
}
else{
    cout &lt;&lt; "Error: Binding framebuffer failed" &lt;&lt; endl;
    exit(0);
}

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


initUniformVarsShading1();
initUniformVarsShading2();
initUniformVarsShadingOut();

}

void myDisplay( void )
{
for (int i=0; i<(textureDim*textureDim); i++)
textureArray[i*4 +0] = textureArray[i*4 +1] = textureArray[i*4 +2] = textureArray[i*4 +3] = 0;

writeTex = 0;    readTex = 1;

glEnable(GL_TEXTURE_2D);
for (int i=0; i&lt;2; i++){
    glBindTexture(GL_TEXTURE_2D, tex_id[i]);
    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_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureDim, textureDim, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureArray); //NULL);
}


glEnable( GL_DEPTH_TEST );

if (numberIterations == 0){
///////////////////////////
glViewport (0, 0, (GLsizei) textureDim, (GLsizei) textureDim); // set the size of our viewport (window)

    glMatrixMode( GL_PROJECTION );							// load the projection matrix; the subsequent transformations are going to affect it
    glLoadIdentity();										// initialise the projection matrix before applying the projection matrix
    
    // Specify that we are going to use a perspective projection - changing our projection matrix - NEW!!!!!
    gluPerspective(45.0f, (GLfloat)textureDim/(GLfloat)textureDim, 0.1f, 100.0f);	//FOV, aspect ratio, near clipping plane, far clipping plane
    
    glMatrixMode( GL_MODELVIEW );							// load the model view matrix - subsequent matrices are going to affect this one
    glLoadIdentity();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	
    glLoadIdentity();
    gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], 0, 1, 0);
    ///////////////////////////
    
    
    glUseProgramObjectARB(glsl_programOut); 
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
    glUniform1iARB(buf_Out, 0);
    
    glBegin(GL_POLYGON);
        glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
        glVertex3f(-0.5, -0.5, -0.5);
        
        glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
        glVertex3f( 0.5, -0.5, -0.5);
        
        glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
        glVertex3f( 0.5,  0.5, -0.5);
        
        glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
        glVertex3f(-0.5,  0.5, -0.5);
    glEnd();
    
    glUseProgramObjectARB(0);
}

else{
for (int i=0; i<numberIterations; i++){
//cout << endl << endl << "Pass " << i << " : " << endl;

        glPushAttrib(GL_ALL_ATTRIB_BITS);
        glPushMatrix();
        
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
        glDrawBuffer(attachmentpoints[writeTex]);
        
         /////////////////
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-0.5,0.5,-0.5,0.5,-0.5,0.5);
        glMatrixMode(GL_MODELVIEW);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glLoadIdentity();
        glViewport(0, 0, textureDim, textureDim);
        /////////////////////
        
        if (writeTex == 0){
            glUseProgramObjectARB(glsl_program1);
            
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
            glUniform1iARB(buf_1, 0);
        }
        else{
            glUseProgramObjectARB(glsl_program2);
            
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
            glUniform1iARB(buf_2, 0);
        }	
        
        glNormal3f(0.0, 0.0, -1.0);
        glBegin(GL_POLYGON);
            glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
            glVertex3f(-0.5, -0.5, -0.5);
            
            glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
            glVertex3f( 0.5, -0.5, -0.5);
            
            glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
            glVertex3f( 0.5,  0.5, -0.5);
            
            glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
            glVertex3f(-0.5,  0.5, -0.5);
        glEnd();
        
        glUseProgramObjectARB(0);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
        
        glPopMatrix();
        glPopAttrib();
        
        
       
        
        
        ///////////////////////////
        glViewport (0, 0, (GLsizei) textureDim, (GLsizei) textureDim);	// set the size of our viewport (window)
        
        glMatrixMode( GL_PROJECTION );							// load the projection matrix; the subsequent transformations are going to affect it
        glLoadIdentity();										// initialise the projection matrix before applying the projection matrix
        
        // Specify that we are going to use a perspective projection - changing our projection matrix - NEW!!!!!
        gluPerspective(45.0f, (GLfloat)textureDim/(GLfloat)textureDim, 0.1f, 100.0f);	//FOV, aspect ratio, near clipping plane, far clipping plane
        
        glMatrixMode( GL_MODELVIEW );							// load the model view matrix - subsequent matrices are going to affect this one
        glLoadIdentity();
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	
        glLoadIdentity();
        gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], 0, 1, 0);
        ///////////////////////////
        
        
        glUseProgramObjectARB(glsl_programOut); 
        
            glActiveTexture(GL_TEXTURE2);
            glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
            glUniform1iARB(buf_Out, 0);
            glBegin(GL_POLYGON);
                glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
                glVertex3f(-0.5, -0.5, -0.5);
                
                glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
                glVertex3f( 0.5, -0.5, -0.5);
                
                glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
                glVertex3f( 0.5,  0.5, -0.5);
                
                glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
                glVertex3f(-0.5,  0.5, -0.5);
            glEnd();
        
        glUseProgramObjectARB(0);
        
        // swap read and write indexes
        readTex = 1 - readTex;
        writeTex = 1 - writeTex;  
    } 
}

glFlush();
glutSwapBuffers();

return;
}

void initUniformVarsShading1()
{
glUseProgramObjectARB(glsl_program1);

buf_1 = glGetUniformLocationARB(glsl_program1, "tex1");    
//  glUniform1iARB(buf_1, 0);

  glUseProgramObjectARB(0);

}

void initUniformVarsShading2()
{
glUseProgramObjectARB(glsl_program2);

buf_2 = glGetUniformLocationARB(glsl_program2, "tex1");
  // glUniform1iARB(buf_2, 0);



  glUseProgramObjectARB(0);

}

void initUniformVarsShadingOut()
{
glUseProgramObjectARB(glsl_programOut);

buf_Out = glGetUniformLocationARB(glsl_programOut, "tex1");
// glUniform1iARB(buf_Out, 0);

  glUseProgramObjectARB(0);

}

//fragShader1
uniform sampler2D tex1;
varying vec4 vVertex;
void main(){
vec4 colorBuf = texture2D(tex1, gl_TexCoord[0].xy);
gl_FragData[0] = vec4(0.75,0.0,0.0, 0.25) + colorBuf;
}

//fragShader2
uniform sampler2D tex1;
varying vec4 vVertex;
void main(){
vec4 colorBuf = texture2D(tex1, gl_TexCoord[0].xy);
if (colorBuf.a < 0.5)
gl_FragData[0] = vec4(0.0,0.75,0.0, 0.25) + colorBuf;
else
gl_FragData[0] = vec4(0.0,0.0,0.4, 0.25) + colorBuf;
}

//fragShaderOut
uniform sampler2D tex1;
varying vec4 vVertex;
void main(){
vec4 color = texture2D(tex1, gl_TexCoord[0].xy);
gl_FragColor = color;
}

//shader.vert
varying vec4 vVertex;
void main(){
gl_TexCoord[0] = gl_MultiTexCoord0.xyzw;
vVertex = vec4(gl_ModelViewProjectionMatrix * gl_Vertex);
gl_Position = ftransform();
}

Change this line


glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
glUniform1iARB(buf_Out, 0);

to this


glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, tex_id[readTex]);
glUniform1iARB(buf_Out, 2);

The second parameter of glUniform1i is the active texture target where ur texture is bound. You have set the active texture target as 2 while the target passed to the shader is 0.

Another thing that I feel you should do is read from the write buffer doing this in the above call


glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, tex_id[writeTex]);
glUniform1iARB(buf_Out, 2);

See if this helps,

Well spotted thanks. I was meaning to use GL_TEXTURE0 instead of GL_TEXTURE2.

Also this is the test for a bigger project coming. That’s why I’m doing this reading from read buffer for now.

Thanks again.