I'm using OpenGL and I've defined a texture in a framebuffer object with the following lines of code :
glGenFramebuffers(1, &ssaoFBO);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
glActiveTexture(GL_TEXTURE27);
glGenTextures(1, &ssaoTexture);
glBindTexture(GL_TEXTURE_2D, ssaoTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WG, WG, 0, GL_RGBA,
GL_UNSIGNED_BYTE,NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
ssaoTexture, 0);
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_NONE);
In the end I want to apply anti-aliasing to my texture. In order to do that it would be very helpful if I had the pixel data in an array.
How can I read the texture and place its data in an array? I think the function glGetBufferSubData
might be helpful but I can't find a tutorial with a full example to use it properly.
Also, when I do edit the array, how can I put the new data in my texture?
Update:
If anyone else is having issues, this is how it worked for me :
std::vector<GLubyte> pixels(1024* 1024* 4);
glActiveTexture(GL_TEXTURE27);
glBindTexture(GL_TEXTURE_2D, ssaoTexture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
// Now pixels vector contains the pixel data
//...
//Pixel editing goes here...
//...
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WG, WG, 0, GL_RGBA, GL_UNSIGNED_BYTE,
&pixels[0]); //Sending the updated pixels to the texture
You've 2 possibilities. The texture is attached to a framebuffer. Either read the pixels from the framebuffer or read the texture image from the texture.
The pixels of the framebuffer can be read by glReadPixels
. Bind the framebuffer for reading and read the pixels:
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, width, height, format, type, pixels);
The texture image can be read by glGetTexImage
. Bind the texture and read the data:
glBindTexture(GL_TEXTURE_2D, ssaoTexture);
glGetTexImage(GL_TEXTURE_2D, 0, format, type, pixels);
In both cases format
and type
define the pixel format of the target data.
e.g. If you want to store the pixels to an buffer with 4 color channels which 1 byte for each channel then format = GL_RGBA
and type = GL_UNSIGNED_BYTE
.
The size of the target buffer has to be widht * height * 4
.
e.g.
#include <vector>
int width = ...;
int height = ...;
std::vector<GLbyte> pixels(width * height * 4); // 4 because of RGBA * 1 byte
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
or
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
Note, if the size in bytes of 1 row of the image, is not dividable by 4, then the GL_PACK_ALIGNMENT
parameter has to be set, to adapt the alignment requirements for the start of each pixel row.
e.g. for an tightly packed GL_RGB
image:
int width = ...;
int height = ...;
std::vector<GLbyte> pixels(width * height * 3); // 3 because of RGB * 1 byte
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());