Jump to content
  • Advertisement
Sign in to follow this  
rosicky2005

Problem on FBO

This topic is 4414 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

My graphic card is nVIDIA and should support texture size of 4096*4096. But when I run the program with this size,it won't work and this code in check error function is called: case GL_FRAMEBUFFER_UNSUPPORTED_EXT: printf("Unsupported framebuffer format\n"); return false; What's the possible problem in it?

Share this post


Link to post
Share on other sites
Advertisement
You are trying to run the application in 4096x4096 (Is there a monitor supporting it !?!??!)

4096*4096 texture size means textures max size. Not the frame buffer size (context resolution)

Share this post


Link to post
Share on other sites
Quote:
Original post by Daivuk
You are trying to run the application in 4096x4096 (Is there a monitor supporting it !?!??!)

4096*4096 texture size means textures max size. Not the frame buffer size (context resolution)


So, is it mean that I can create a texture of 4096*4096 in theory, but the framebuffer can never render it in practical?

Share this post


Link to post
Share on other sites
You haven't given enuff information, it should be perfectly possible to render to the largest size texture via FBO, monitor screen resolution is irrelivent when it comes to FBOs.

Share this post


Link to post
Share on other sites
Here is my piece of code. Sorry for quite long.

// includes
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/glew.h>
#include <GL/glut.h>
using namespace std;

// useful ifdef for debugging
#ifdef _WIN32
#define PAUSE() system("pause")
#else
#define PAUSE() system("echo Press ENTER to continue; read")
#endif

// prototypes
bool checkFramebufferStatus(void);
void checkGLErrors(const char *label);
void compareResults(void);
void createTextures(void);
void createAllTextureParameters(void);
void initGLSL(void);
void initFBO(void);
void initGLEW(void);
void initGLUT(int argc, char** argv);
void performComputation(void);
void printInfoLog(GLhandleARB obj);
void printVector(const float *p, const int N);
void setupTexture(const GLuint texID);
void swap(void);
void transferFromTexture(float* data);
void transferToTexture(float* data, GLuint texID);

// mode: 0=test (POT), 1=bench (set from command line)
int mode;

// problem size, texture size, number of iterations (set from command line)
int N;
int texSize;
int numIterations;

// flags to fine-tune application and to ease debugging
bool mode_showResults = true;
bool mode_compareResults = true;

// texture identifiers
GLuint yTexID[2];
GLuint xTexID;
GLuint aTexID;

// ping pong management vars
int writeTex = 0;
int readTex = 1;
GLenum attachmentpoints[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };

// GLSL vars
GLhandleARB programObject;
GLhandleARB shaderObject;
GLint yParam, xParam,alphaParam;

// FBO identifier
GLuint fb;

// timing vars
double start, end;
double start_gpu, end_gpu;

// handle to offscreen "window", only used to properly shut down the app
GLuint glutWindowHandle;

// struct for variable parts of GL calls (texture format, float format etc)
struct struct_textureParameters {
char* name;
GLenum texTarget;
GLenum texInternalFormat;
GLenum texFormat;
char* shader_source;
} rect_nv_r_32, // texture rectangles, NV_float_buffer, R, 32 bits



// struct actually being used (set from command line)
struct_textureParameters textureParameters;

// actual data
float* dataX;
float* dataY;
float alpha;


/**
* main, just calls things in the appropriate order
*/
int main(int argc, char **argv) {

// create variables for GL
createAllTextureParameters();
textureParameters = rect_nv_r_32;


//check error printing maxtexsize

N = pow(2,22);
numIterations = 200;
printf(textureParameters.name);
printf(", N=%d, numIter=%d\n",N,numIterations);
printf("Calculation for y = y+x*alpha\n");
printf("Initial value as follows\n");
printf("dataX = 2.0;\n");
printf("dataY = i+1.0;\n");
//printf("Input an alpha value :");
//cin>>alpha;
alpha = 1.0/9.0;
PAUSE();

// calc texture dimensions
if (textureParameters.texFormat == GL_RGBA)
texSize = (int)sqrt(N/4.0);
else
texSize = (int)sqrt((double)N);

cout<<"Texture Size = "<<texSize<<endl;
// create data vectors
dataX = (float*)malloc(N*sizeof(float));
dataY = (float*)malloc(N*sizeof(float));

// and fill with some arbitrary values
for (int i=0; i<N; i++) {
dataX = 2.0;
dataY = i+1.0;
}
start_gpu = clock();


// init glut and glew
initGLUT(argc, argv);
initGLEW();
//find the maximum size of texture
int maxtexsize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize);
cout<<"Maximum texture size is "<<maxtexsize<<endl;
// init offscreen framebuffer
initFBO();

// create textures for vectors
createTextures();

// init shader runtime
initGLSL();

// and start computation
performComputation();


// compare results
compareResults();
/*
//test code checking GL error
GLenum errCode;
const GLubyte *errString;
if ((errCode = glGetError()) != GL_NO_ERROR) {
errString = gluErrorString(errCode);
fprintf (stderr, "OpenGL Error: %s\n", errString);
}
*/
// and clean up
glDeleteFramebuffersEXT(1,&fb);
free(dataX);
free(dataY);
glDeleteTextures(2,yTexID);
glDeleteTextures (1,&xTexID);
glutDestroyWindow (glutWindowHandle);

PAUSE();

return 0;
}


/**
* Sets up a floating point texture with NEAREST filtering.
* (mipmaps etc. are unsupported for floating point textures)
*/
void setupTexture (const GLuint texID) {
// make active and bind
glBindTexture(textureParameters.texTarget,texID);
// turn off filtering and wrap modes
glTexParameteri(textureParameters.texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(textureParameters.texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(textureParameters.texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(textureParameters.texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP);
// define texture with floating point format
glTexImage2D(textureParameters.texTarget,0,textureParameters.texInternalFormat,texSize,texSize,0,textureParameters.texFormat,GL_FLOAT,0);
// check if that worked
if (glGetError() != GL_NO_ERROR) {
printf("glTexImage2D():\t\t\t [FAIL]\n");
exit (ERROR_TEXTURE);
} else if (mode == 0) {
printf("glTexImage2D():\t\t\t [PASS]\n");
}
// printf("Created a %i by %i floating point texture.\n",texSize,texSize);
}

/**
* Transfers data from currently texture, and stores it in given array.
*/
void transferFromTexture(float* data) {
// version (a): texture is attached
// recommended on both NVIDIA and ATI
glReadBuffer(attachmentpoints[readTex]);
glReadPixels(0, 0, texSize, texSize,textureParameters.texFormat,GL_FLOAT,data);
// version b: texture is not neccessarily attached
// glBindTexture(textureParameters.texTarget,yTexID[readTex]);
// glGetTexImage(textureParameters.texTarget,0,textureParameters.texFormat,GL_FLOAT,data);
}

/**
* Transfers data to texture.
* Check web page for detailed explanation on the difference between ATI and NVIDIA.
*/
void transferToTexture (float* data, GLuint texID) {
// version (a): HW-accelerated on NVIDIA
glBindTexture(textureParameters.texTarget, texID);
glTexSubImage2D(textureParameters.texTarget,0,0,0,texSize,texSize,textureParameters.texFormat,GL_FLOAT,data);
// version (b): HW-accelerated on ATI
// glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureParameters.texTarget, texID, 0);
// glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
// glRasterPos2i(0,0);
// glDrawPixels(texSize,texSize,textureParameters.texFormat,GL_FLOAT,data);
// glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureParameters.texTarget, 0, 0);
}


/**
* creates textures, sets proper viewport etc.
*/
void createTextures (void) {
// create textures
// y gets two textures, alternatingly read-only and write-only,
// x is just read-only
glGenTextures (2, yTexID);
glGenTextures (1, &xTexID);
// set up textures
setupTexture (yTexID[readTex]);
transferToTexture(dataY,yTexID[readTex]);
setupTexture (yTexID[writeTex]);
transferToTexture(dataY,yTexID[writeTex]);
setupTexture (xTexID);
transferToTexture(dataX,xTexID);
// set texenv mode from modulate (the default) to replace)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// check if something went completely wrong
checkGLErrors ("createFBOandTextures()");
}
/**
* Sets up GLUT, creates "window" (better put: valid GL context, since the window is never displayed)
*/
void initGLUT(int argc, char **argv) {
glutInit ( &argc, argv );
glutWindowHandle = glutCreateWindow("SAXPY TESTS");
}

/**
* Sets up GLEW to initialise OpenGL extensions
*/

void initGLEW (void) {
int err = glewInit();
// sanity check
if (GLEW_OK != err) {
printf((char*)glewGetErrorString(err));
// PAUSE();
exit(ERROR_GLEW);
}
}

/**
* Creates framebuffer object, binds it to reroute rendering operations
* from the traditional framebuffer to the offscreen buffer
* perform 32 floating point calculations
* instead of clamping the value to the range of [0/255], [255/255]
*/
void initFBO(void) {
// create FBO (off-screen framebuffer)
glGenFramebuffersEXT(1, &fb);
// bind offscreen framebuffer (that is, skip the window-specific render target)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
// viewport for 1:1 pixel=texture mapping
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, texSize, 0.0, texSize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, texSize, texSize);
}

/**
* Sets up the Cg runtime and creates shader.
*/
void initGLSL(void) {
// create program object
programObject = glCreateProgramObjectARB();
// create shader object (fragment shader) and attach to program
shaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
glAttachObjectARB (programObject, shaderObject);
// set source to shader object
const GLcharARB* source = textureParameters.shader_source;
glShaderSourceARB(shaderObject, 1, &source, NULL);
// compile and print compilation errors (no need to do additional error
// checking, ghLinkProgramARB() will fail if compilation was wrong)
glCompileShaderARB(shaderObject);
//printInfoLog(shaderObject);
// link program object together and check for errors
glLinkProgramARB(programObject);
GLint success;
glGetObjectParameterivARB(programObject, GL_OBJECT_LINK_STATUS_ARB, &success);
if (!success) {
printf("Shader could not be linked!\n");
system("pause");
exit (ERROR_GLSL);
}


// Get location of the texture samplers for future use
yParam = glGetUniformLocationARB(programObject, "textureY");
xParam = glGetUniformLocationARB(programObject, "textureX");
alphaParam = glGetUniformLocationARB(programObject, "alpha");
}


/**
* Performs and times saxpy on the CPU, compares results
*/
void compareResults () {
// get GPU results

float* data = new float[N];
double start_tran, end_tran;
start_tran=clock();
transferFromTexture (data);
end_tran=clock();
cout<<end_tran-start_tran<<" is transformation time"<<endl;
end_gpu = clock();
double total_time = end_gpu - start_gpu;
cout<<"Total time used by GPU:"<<total_time<<endl;
if (mode_compareResults) {
// calc on CPU
start=clock();
for (int n=0; n<numIterations; n++)
for (int i=0; i<N; i++)
dataY = dataY + alpha*dataX;
end = clock();

//how much min sceond is used
double total = end - start;
cout<<"Total time used by CPU:"<<total<<endl;

// and compare results
double maxError = -1000.0;
double avgError = 0.0;
double percentError = 0.0;
double avgPercentError = 0.0;
int count = 0;
for (int i=0; i<N; i++) {
double diff = fabs(data-dataY);

if(diff == 0){
count++;

}

if (diff > maxError){
maxError = diff;
percentError = diff*100/data;
}
avgError += diff;
avgPercentError += percentError;
}
avgError /= (double)N;
avgPercentError /= (double)N;
cout<<(double)count/N<<"% of them are accrate"<<endl;
printf("Max Error: \t\t\t%f\n",maxError);
printf("Average Error: \t\t\t%f\n",avgError);
printf("Average Percentage Error: \t%f %\n",avgPercentError);
/*
if (mode_showResults) {
printf("CPU RESULTS:\n");
printVector(dataY,N);

}
*/
}
/*
if (mode_showResults) {
// print out results
printf("GPU RESULTS:\n");
printVector (data,N);
}
*/
delete [] data;
}


/**
* Performs the actual calculation.
*/
void performComputation(void) {
// glEnable(textureParameters.texTarget);

// attach two textures to FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentpoints[writeTex], textureParameters.texTarget, yTexID[writeTex], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentpoints[readTex], textureParameters.texTarget, yTexID[readTex], 0);

// check if that worked
if (!checkFramebufferStatus()) {
printf("glFramebufferTexture2DEXT():\t [FAIL]\n");
PAUSE();
exit (ERROR_FBOTEXTURE);
} else if (mode == 0) {
printf("glFramebufferTexture2DEXT():\t [PASS]\n");
}


// enable GLSL program
glUseProgramObjectARB(programObject);

// enable texture x (read-only, not changed in the computation loop)
//not yet start computation
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureParameters.texTarget,xTexID);
glUniform1iARB(xParam, 1); // texunit 1

// enable scalar alpha (same)
glUniform1fARB(alphaParam,alpha);

// Calling glFinish() is only neccessary to get accurate timings,
// and we need a high number of iterations to avoid timing noise.
glFinish();

for (int i=0; i<numIterations; i++) {
// set render destination
glDrawBuffer (attachmentpoints[writeTex]);
// enable texture y_old (read-only)
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureParameters.texTarget,yTexID[readTex]);
glUniform1iARB(yParam,0); // texunit 0
// and render multitextured viewport-sized quad
// depending on the texture target, switch between
// normalised ([0,1]^2) and unnormalised ([0,w]x[0,h])
// texture coordinates

// make quad filled to hit every pixel/texel
// (should be default but we never know)
glPolygonMode(GL_FRONT,GL_FILL);
// and render the quad
if (textureParameters.texTarget == GL_TEXTURE_2D) {
// render with normalized texcoords
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex2f(texSize, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex2f(texSize, texSize);
glTexCoord2f(0.0, 1.0);
glVertex2f(0.0, texSize);
glEnd();
} else {
// render with unnormalized texcoords
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f(texSize, 0.0);
glVertex2f(texSize, 0.0);
glTexCoord2f(texSize, texSize);
glVertex2f(texSize, texSize);
glTexCoord2f(0.0, texSize);
glVertex2f(0.0, texSize);
glEnd();
}
// swap role of the two textures (read-only source becomes
// write-only target and the other way round):
swap();
}
// done, stop timer, calc MFLOP/s if neccessary
if (mode == 1) {
glFinish();

}
// done, just do some checks if everything went smoothly.
checkFramebufferStatus();
checkGLErrors("render()");
// glDisable(textureParameters.texTarget);
}

/**
* Sets up the various structs used to handle texture targets, texture formats etc.
*/
void createAllTextureParameters(void) {

rect_nv_r_32.name = "TEXRECT - float_NV - R - 32";
rect_nv_r_32.texTarget = GL_TEXTURE_RECTANGLE_ARB;
rect_nv_r_32.texInternalFormat = GL_FLOAT_R32_NV;
rect_nv_r_32.texFormat = GL_LUMINANCE;
rect_nv_r_32.shader_source = "uniform sampler2DRect textureY;" "uniform sampler2DRect textureX;" "uniform float alpha;" "void main(void) { " "float y = texture2DRect(textureY, gl_TexCoord[0].st).x;" "float x = texture2DRect(textureX, gl_TexCoord[0].st).x;" "gl_FragColor.x = y + alpha*x;" "}";

/////////////

}

/**
* Checks for OpenGL errors.
* Extremely useful debugging function: When developing,
* make sure to call this after almost every GL call.
*/
void checkGLErrors (const char *label) {
GLenum errCode;
const GLubyte *errStr;

if ((errCode = glGetError()) != GL_NO_ERROR) {
errStr = gluErrorString(errCode);
printf("OpenGL ERROR: ");
printf((char*)errStr);
printf("(Label: ");
printf(label);
printf(")\n.");
}

}

/**
* Checks framebuffer status.
* Copied directly out of the spec, modified to deliver a return value.
*/
bool checkFramebufferStatus() {
GLenum status;
status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
return true;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
printf("Framebuffer incomplete, incomplete attachment\n");
return false;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
printf("Unsupported framebuffer format\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
printf("Framebuffer incomplete, missing attachment\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
printf("Framebuffer incomplete, attached images must have same dimensions\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
printf("Framebuffer incomplete, attached images must have same format\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
printf("Framebuffer incomplete, missing draw buffer\n");
return false;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
printf("Framebuffer incomplete, missing read buffer\n");
return false;
}
return false;
}

/**
* copied from http://www.lighthouse3d.com/opengl/glsl/index.php?oglinfo
*/
void printInfoLog(GLhandleARB obj) {
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
if (infologLength > 1) {
infoLog = (char *)malloc(infologLength);
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
printf(infoLog);
printf("\n");
free(infoLog);
}
}

/**
* Prints out given vector for debugging purposes.
*/
void printVector (const float *p, const int N) {
for (int i=0; i<N; i++)
printf("%f\n",p);

}



/**
* swaps the role of the two y-textures (read-only and write-only)
*/
void swap(void) {
if (writeTex == 0) {
writeTex = 1;
readTex = 0;
} else {
writeTex = 0;
readTex = 1;
}
}

Share this post


Link to post
Share on other sites
Even though an OpenGL implementation may be able to texture from a texture object, that does not guarentee you can render to a texture of that max size.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!