PDA

View Full Version : FBO works for my unit test, but failed with my app



kewuwsi
02-15-2008, 02:23 PM
Hi, all.

attached is my piece of my code for FBO initialization. It works OK with my unit test.
The problem is: when integrate this part into my apps code, it fails at the assertion point: says "GL_FRAMEBUFFER_UNSUPPORTED_EXT",
And if I change all the GL_TEXTURE_2D to GL_TEXTURE_RECTANGLE_ARB , it doesn't complain.

seems somewhere my apps disabled some of the GL features? what could be?

can anybody gave me a clue? tks

glxinfo:
(server glx vendor string: NVIDIA Corporation
server glx version string: 1.4
client glx vendor string: NVIDIA Corporation
client glx version string: 1.4
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: Quadro FX 4500/PCI/SSE2
)

[CODE] glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

// init texture for FBO
glGenTextures( 1, & tex);
glBindTexture( GL_TEXTURE_2D, tex);
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_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

// bind texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D ,tex,0);

GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
[/B][/QUOTE]

Mark Shaxted
02-15-2008, 02:40 PM
What values are you assigning texW & texH? Also, do you have NP2 textures?

kewuwsi
02-15-2008, 02:42 PM
texW and texH is 512* 512. should be OK.
the strange things is: it works with my unit test!!!

ZbuffeR
02-15-2008, 05:35 PM
And what is your "unit test" ?

Dark Photon
02-15-2008, 07:19 PM
FBO initialization...when integrate this part into my apps code, it fails at the assertion point: says "GL_FRAMEBUFFER_UNSUPPORTED_EXT"...


glGenTextures( 1, & tex);
glBindTexture( GL_TEXTURE_2D, tex);
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_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
IIRC, you get FRAMEBUFFER_INCOMPLETE if you don't flip the texture min filter off of MIPmap. Also, if your FBO doesn't have a depth buffer, disable depth test and depth writes:



glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST
glDisable( GL_DEPTH_TEST )
glDepthMask( GL_FALSE )

Also, for clarity, use GL_RGBA8 for your texture's internal format.

kewuwsi
02-18-2008, 07:12 AM
Here is my unit test:
[CODE]
#include <iostream>
#include <cassert>
#include<GL/glew.h>
#include<GL/glut.h>
#include<GL/glext.h>

#include "textfile.h"


using namespace std;


float angle = 0.0;
int in_tex = 0;
int out_tex = 1;

int iter = 20;

// texture handle for ping pong
GLuint tex[2];

unsigned char* data;
// initial texture
GLuint init_tex;
int width = 512;
int height = 128;

// fbo handle
GLuint fbo;
GLenum att_point[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};


// shader variables
GLuint v, f, p1, p2, f2;
char *vs,*fs,*fs2;


static bool
checkFBOErrors()
{
unsigned fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT) {
std::cout << "error creating fbo, framebufferstatus is not complete:" << std::endl;
std::string error;

switch (fbo_status) {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT");break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT");break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT");break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error.assign("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT");break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: error.assign("GL_FRAMEBUFFER_UNSUPPORTED_EXT");break;
}
std::cout << "error: " << error << std::endl;
return false;
}

}
//
//
// shader program
void setShaders()
{
// v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
f2 = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);


// vs = textFileRead("toon.vert");
fs = textFileRead("toon.frag");
fs2 = textFileRead("toon2.frag");

const char * ff = fs;
const char * ff2 = fs2;
// const char * vv = vs;

// glShaderSourceARB(v, 1, &amp;vv,NULL);
glShaderSourceARB(f, 1, &amp;ff,NULL);
glShaderSourceARB(f2, 1, &amp;ff2,NULL);

// free(vs);
free(fs); free(fs2);

// glCompileShaderARB(v);
glCompileShaderARB(f);
glCompileShaderARB(f2);

p1 = glCreateProgramObjectARB();
glAttachObjectARB(p1,f);
// glAttachObjectARB(p1,v);
glLinkProgramARB(p1);

p2 = glCreateProgramObjectARB();
glAttachObjectARB(p2,f2);
// glAttachObjectARB(p2,v);
glLinkProgramARB(p2);


}

void InitGLExtensions()
{
// Init GLEW
if (glewInit() != GLEW_OK)
{
cout << "Error: Can't initialize GLEW" << endl;
exit(-1);
}
else
{
cout<<"GLEW IS INITIALIZED OK!!"<<endl;
}

if (!GLEW_EXT_framebuffer_object)
{
cout << "Error: EXT_framebuffer_object is not supported." << endl;
exit(-1);
}
else
cout<<"FRAME BUFFER OBJECT IS INITIALIZED OK!!"<<endl;

}


void initTextures()
{
// allocate texture name
glGenTextures(1, &amp;init_tex);

//
// generate test 8 bit image
//
data = (unsigned char*) malloc(width * height *sizeof(unsigned char));
// init texture info
for(int row = 0; row < height; row++)
{
for( int col = 0; col < width; col++ )
{
int pos = row*width + col;
if( row % 32==0 || col % 32==0)
{
data[pos] = 255;
}
else data[pos] = 0;
}
}
glBindTexture(GL_TEXTURE_2D, init_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/*GL_NEAREST*/ );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/* GL_NEAREST*/);
/*
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
*/
//free(data);
}


// create FBO and two textures used for Ping Pong
// attach these two textures to FBO
void InitFBO()
{
// Create FBO
glGenFramebuffersEXT(1, &amp;fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);


// Initialize ping pong texture 1, bind to fbo
glGenTextures(1, &amp;tex[0]);
glBindTexture(GL_TEXTURE_2D, tex[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);

// Attach Texture to Framebuffer Color Buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[in_tex], GL_TEXTURE_2D, tex[in_tex], 0);

checkFBOErrors();

// Initialize ping pong texture 2, bind to fbo
glGenTextures(1, &amp;tex[1]);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);

// Attach Texture to Framebuffer Color Buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[out_tex], GL_TEXTURE_2D, tex[out_tex], 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


}

void ReleaseFBO()
{
glDeleteFramebuffersEXT(1, &amp;fbo);
}


void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-width/2, width/2, -height/2, height/2);
// Set the viewport to be the entire window
//glViewport(0, 0, w, h);

// Set the correct perspective.
//gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, w, h);
/*
gluLookAt(0.0,0.0,0.0,
0.0,0.0,-1.0,
0.0f,1.0f,0.0f);
*/
}

void shaderDraw()
{
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-width/2, -height/2, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( width/2, -height/2, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( width/2, height/2, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-width/2, height/2, 0.0f);
glEnd();
}

// render to buffer
// Do ping pong once: two passes, do convolution along X direction and Y direction
void rendertoBuffer(void)
{
glUseProgramObjectARB(p1);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

//glPushAttrib(GL_VIEWPORT_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-width/2, width/2, -height/2, height/2);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);

// bind input texture and draw
glBindTexture(GL_TEXTURE_2D, init_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);

// first draw
shaderDraw();

// now we have the render buffer textures
for( int i = 0; i < iter; i++ )
{
// set the draw destination
glDrawBuffer( att_point[out_tex] );

// bind textureIN to smoo_text for shaders
glActiveTexture(GL_TEXTURE0);
int myTexture = glGetUniformLocationARB(p1, "smoo_text");
glUniform1iARB(myTexture, 0);

glBindTexture(GL_TEXTURE_2D, tex[in_tex]);
int textID = glGetUniformLocationARB(p1, "tex_id");

shaderDraw();

// swap in/out index
if( in_tex )
{
in_tex = 0;
out_tex = 1;
glUniform1iARB(textID, out_tex);
}
else
{
in_tex = 1;
out_tex = 0;
glUniform1iARB(textID, out_tex);
}
}

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

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

//cout<< __FILE__ << __LINE__ <<" IN RENDER TO BUFFER STAGE "<<endl;
glUseProgramObjectARB(0);
}

void renderScene(void)
{
//rendertoBuffer();

glUseProgramObjectARB(p2);
glClearColor(0.0f, 0.0f,0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//
// bind textureIN to smoo_text for shaders
glActiveTexture(GL_TEXTURE1);
//glEnable(GL_TEXTURE_2D);
int myTexture = glGetUniformLocationARB(p2, "imag_text");

glBindTexture(GL_TEXTURE_2D, tex[out_tex]);
glUniform1iARB( myTexture, 1);
//
// draw to screen
shaderDraw();
glDisable(GL_TEXTURE_2D);

glutSwapBuffers();
glUseProgramObjectARB(0);
//cout<<__FILE__<<" "<<__LINE__<<" IN RENDER SCENE"<<endl;
}

void processNormalKeys(unsigned char key, int x, int y) {

if (key == 27)
exit(0);
}

void updateInteration( int key, int x, int y)
{
if( key == GLUT_KEY_PAGE_UP )
{
iter ++;

}
if( key == GLUT_KEY_PAGE_DOWN &amp;&amp; iter > 0)
{
iter --;
}
cout<< __FILE__<<" "<<__LINE__<<" current iteration "<< iter<<endl;
}



int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Lighthouse 3D - GLUT Tutorial");

InitGLExtensions();
InitFBO();
initTextures();
setShaders();
rendertoBuffer();
glutReshapeFunc(changeSize);

glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);


//adding here the setting of keyboard processing
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(updateInteration);


glutMainLoop();
return 0;
}


[/B][/QUOTE]

kewuwsi
02-18-2008, 07:32 AM
here is the error msg I got with Dark Photon's suggestions:
"
error creating fbo, framebufferstatus is not complete:
error: GL_FRAMEBUFFER_UNSUPPORTED_EXT
"
with the borrowed function listed in above unit test ( replace the assertion part in my apps with checkFBOErrors() ).

?
tks

Dark Photon
02-18-2008, 07:51 AM
Here is my unit test:
If I comment out the few lines to load the shaders, then compile and run it, I get:


> tst
GLEW IS INITIALIZED OK!!
FRAME BUFFER OBJECT IS INITIALIZED OK!!
Linux, GeForce 8800GTX, 169.09 drivers

kewuwsi
02-18-2008, 07:56 AM
Yes.
That is saying my unit test is OK on my computer.

my problem is: " If I try to use FBO with GL_TEXTURE_2D in my application( large scale code ) on the same computer, It will fail and give me the error msg."


tks

-NiCo-
02-18-2008, 08:15 AM
Looks like you need to master the art of debugging :)

Start from your unit test and repeatedly add parts of your large scale code and check for errors. Takes a little effort but it always does the trick.

N.

kewuwsi
02-18-2008, 08:52 AM
http://www.opengl.org/discussion_boards/images/icons/default/tongue.gif

Tks, I will think about it. You know, the apps is really "large", I even don't know how to get started.........