PDA

View Full Version : Writing and reading directly to/from buffers



muffinman104
09-24-2009, 03:25 PM
I am trying to write data to the frame buffer, and then read it back. But when I read it back, the array is not populated with the data I submitted.
What am I doing wrong?

Here is my code:

... pBuff is a float * holding image data ...

//CREATE & BIND TO THE FRAME BUFFER
glGenFramebuffersEXT(1, &framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);

//CREATE PBO
int num_elements = rows * cols;
size_tex_data = sizeof(float) * num_elements;
glGenBuffers(1, &pbo_source);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_source);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, size_tex_data, pBuff, GL_DYNAMIC_COPY);

//WRITE TO BUFFER
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_source);
glRasterPos2f(0,0);
glDrawPixels( cols,rows,GL_RED,GL_FLOAT,pBuff );
glFlush();

//READ FROM BUFFER
float * retrievalBuff= new float[sideLen*sideLen];
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo_source);
glRasterPos2f(0,0);
glReadPixels(0, 0, cols, rows, GL_RED, GL_FLOAT, retrievalBuff);
glFlush();

//save to a file
mv->SaveDataAsPGM(retrievalBuff, rows, cols, "outData.pgm", false);

Thanks in advance!

Alfonse Reinheart
09-24-2009, 04:56 PM
First:

GL_DYNAMIC_COPY is exactly the wrong hint to use here. You are writing to this buffer and reading from it; the COPY usage patterns are for when you neither read nor write from/to the object.

Consider either using two buffers (one with GL_DYNAMIC_DRAW that you use for UNPACK and one with GL_DYNAMIC_READ that you use for PACK) or just picking GL_DYNAMIC_READ.

You also don't seem to be attaching an image to the FBO. So I don't know how exactly you expect this to work.

Lastly, since you're writing and reading float data, you need to make sure that the image you've formatted actually has a floating-point type. Otherwise, OpenGL will clamp and truncate the data as needed to fit within the bounds of the image format you're writing to.

muffinman104
09-25-2009, 09:56 AM
You also don't seem to be attaching an image to the FBO. So I don't know how exactly you expect this to work.


This is the part that I need to understand. Why do I need to attach an image to the FBO? Why can't I just write pixel data directly onto the buffer? Does the frame buffer require the context of an image that is bound to it in order to process incoming data? Can you paste a quick example of how I could revise my code so that it will send the data in and let me pull it back out?

I attempted to attach to the renderbuffer, and the status is returning good, but my image data still isn't showing up on the buffer. Is this what you were referring to?
Here is my revised code, which still fails to populate retrievalBuff:

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


//CREATE & BIND TO RENDERBUFFER
GLuint rboId;
glGenRenderbuffersEXT(1, &rboId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RED,cols, rows);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);


// ATTACH THE RENDERBUFFER
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rboId);

// check FBO status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
cout<<"BAD glCheckFramebufferStatus\n";
return 0;
}

//CREATE PBO
int num_elements = rows * cols;
size_tex_data = sizeof(float) * num_elements;
glGenBuffers(1, &amp;pbo_source);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_source);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, size_tex_data, pBuff, GL_DYNAMIC_READ);

//WRITE TO BUFFER
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_source);
glRasterPos2f(0,0);
glDrawPixels( cols,rows,GL_RED,GL_FLOAT,pBuff );
glFlush();

//READ FROM BUFFER
float * retrievalBuff= new float[sideLen*sideLen];
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo_source);
glRasterPos2f(0,0);
glReadPixels(0, 0, cols, rows, GL_RED, GL_FLOAT, retrievalBuff);
glFlush();

//SAVE OUT THE IMAGE DATA
mv->SaveDataAsPGM(retrievalBuff, rows, cols, "hamburger.pgm", false);

Thanks for your help.

muffinman104
10-05-2009, 01:57 PM
I figured out what my problem was. I incorrectly believed that glReadPixels() would read data from a buffer object. It does not. By replacing the glReadPixels command with: float * retrievalBuff=(float *) glMapBuffe(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); I was able to get it to work.