getting a crash while using glReadPixels to map texture in memory - opengl

I'm trying to use glReadPixels to map a texture in memory to be able to use openGL's immutable storage feature.
I'm using deferred shading so I prepare my G-Buffers as following:
glGenFramebuffers(1, &_gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _gBuffer);
glGenTextures(1, &_pos3dTex);
glBindTexture(GL_TEXTURE_2D, _pos3dTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
GLuint layout = glGetFragDataLocation(_progID, "positionTexture");
...
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + layout, GL_TEXTURE_2D, _pos3dTex, 0);
...
unsigned int attachments[1] = { GL_COLOR_ATTACHMENT0 + layout };
glDrawBuffers(1, attachments);
glGenRenderbuffers(1, &_rboDepth);
glBindRenderbuffer(GL_RENDERBUFFER, _rboDepth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _rboDepth);
And then I want to map my texture in memory so I can use immutable storage:
//Bind Data
glGenBuffers(1, &_pos3dPbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, _pos3dPbo);
//w*h*4 (Channels)*4(size of float)
glBufferData(GL_PIXEL_PACK_BUFFER,width*height*4* 4, 0, GL_STREAM_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, _gBuffer);
glReadBuffer(GL_COLOR_ATTACHMENT0 + layout);
glPixelStorei(GL_PACK_ALIGNMENT, 4);//4 channels
glReadPixels(0, 0, width, height, GL_RGBA,GL_FLOAT,NULL);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
//Reading
glBindBuffer(GL_PIXEL_PACK_BUFFER, _pos3dPbo);
void* outPos3d = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
//Releasing
glBindBuffer(GL_PIXEL_PACK_BUFFER, _pos3dPbo);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
I'm getting an "Access Violation" just after the glReadPixels function.
What Am I doing wrong plz?

You are unbinding your GL_PIXEL_PACK_BUFFER before the glReadPixels, so the NULL pointer will be interpreted relative to your client memory address space, and trying to copy the data to there will almost certainly result in a crash.

Related

Write to OpenGL multiple renderbuffer failed

Not sure what is the problem, it failed to read the pixels when writing to multiple renderbuffer. Here is the code:
setup code:
// gen framebuffer object
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// gen renderbuffer 0
glGenRenderbuffers(1, &rbo_color0);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_color0);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo_color0);
// gen renderbuffer 1
glGenRenderbuffers(1, &rbo_color1);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_color1);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RED_INTEGER, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo_color1);
// gen depth buffer
glGenRenderbuffers(1, &rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
render and read pixel code:
// setup shader and uniforms...
// bind framebuffer and clear color/depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glEnable(GL_DEPTH_TEST);
glClearColor(0.f, 0.f, 0.f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const GLuint buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, buffers);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, (void*)0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, data);
glReadBuffer(GL_COLOR_ATTACHMENT1);
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_INT, (int*)(data) + 4);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
I used layout qualifier in the shader for the outputs, shouldn't be any problems there. So I think probably there is something wrong the the buffer setup or render code.
I've succeed in reading the pixels when there is only one renderbuffer(rbo_color0). The main difference is:
no generation code for renderbuffer1;
use glDrawBuffer(rbo_color0) when rendering;
the format of rbo_color0 is GL_RGBA(double checked the format setting in corresponding glRenderbufferStorage/glReadBuffer calls, no problem here);
no read pixel call for rbo_color1.
Any helps?
GL_RED_INTEGER is not a proper internal format, as it can be used for the 2nd parameter of glRenderbufferStorage.
A proper enumerator constant for the internal format would be GL_R32I.
See OpenGL 4.6 API Compatibility Profile Specification; 8.26. TEXTURE IMAGE LOADS AND STORES; page 334
If you would check for OpenGL erros (glGetError), then you would get an INVALID_ENUM error.
Change the render buffer storage specification, to solve the issue:
glRenderbufferStorage(GL_RENDERBUFFER, GL_R32I, w, h);
Note, you should check the framebuffer completeness by glCheckFramebufferStatus:
GLenum fb_status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if ( fb_status != GL_FRAMEBUFFER_COMPLETE )
{
// error handling
}

How to render anti-aliased image to a texture (and then write to PNG)?

I'd like to use the "render to texture" paradigm to write a .png screenshot of my OpenGL 3D rendering. I have it working without multi-sampling, but I'm struggling to get an anti-aliased image.
First of all, is this possible?
Second, what is the right combination of API calls?
(meta third question, how can I better debug this? glCheckFramebufferStatus is clearly not enough).
Here's what I'm working with:
// https://stackoverflow.com/questions/7402504/multisampled-render-to-texture-in-ios
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
GLuint resolved_framebuffer, resolvedColorRenderbuffer;
glGenFramebuffers(1, &resolved_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, resolved_framebuffer);
glGenRenderbuffers(1, &resolvedColorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, resolvedColorRenderbuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
GLuint colorRenderbuffer, depthRenderbuffer;
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );
glClearColor(background_color(0), background_color(1), background_color(2), 0.f);
glClear(GL_COLOR_BUFFER_BIT);// | GL_DEPTH_BUFFER_BIT);
draw_scene();
glBindFramebuffer( GL_READ_FRAMEBUFFER, framebuffer );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, resolved_framebuffer );
// https://forum.juce.com/t/ios-8-getting-the-demo-building/13570/20
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// ^--- this is throwing `GL_INVALID_OPERATION`
GLubyte* pixels = (GLubyte*)calloc(width*height*4,sizeof(GLubyte));
glReadPixels(0, 0,width, height,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
writePNG(pixels);
Currently I'm getting a blank image and glBlitFramebuffer is throwing GL_INVALID_OPERATION. Apparently this error can correspond to many things, and I'm not sure which is applying. My buffers seem "good" according to glCheckFramebufferStatus.
This question has been asked in similar forms before:
Cannot render to texture with multisampling
Multisampled render to texture in ios
But none of the answers have lead to a complete working example. I would love to find/create a minimal example of this.
The tutorial at https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing basically had what I needed. The working solution is:
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// create a multisampled color attachment texture
unsigned int textureColorBufferMultiSampled;
glGenTextures(1, &textureColorBufferMultiSampled);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, width, height, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0);
// create a (also multisampled) renderbuffer object for depth and stencil attachments
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// configure second post-processing framebuffer
unsigned int intermediateFBO;
glGenFramebuffers(1, &intermediateFBO);
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
// create a color attachment texture
unsigned int screenTexture;
glGenTextures(1, &screenTexture);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
draw_scene();
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
GLubyte* pixels = (GLubyte*)calloc(width*height*4,sizeof(GLubyte));
glReadPixels(0, 0,width, height,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
writePNG(pixels);
It seems there're at least two errors in the code in the original question:
The framebuffer should have a multisample texture attached, not a renderbuffer (glFramebufferTexture2D(... GL_TEXTURE_2D_MULTISAMPLE instead of glRenderbufferStorageMultisample)
Must call glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); after blitting and before glReadPixels

OpenGL MSAA in 2 different ways. What are the differences?

I have been looking for OpenGL Multi Sample Anti Aliasing tutorials and I found many but I'll take 2.
They use a different way to do this. I have tested both ways and both work for my project so I can use any of them.
I use this to render my game engine scene to a texture.
This is the 1st way:
Create the FBO with MSAA
// create a texture object
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// create a MSAA framebuffer object
// NOTE: All attachment images must have the same # of samples.
// Ohterwise, the framebuffer status will not be completed.
glGenFramebuffers(1, &fboMsaaId);
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
// create a MSAA renderbuffer object to store color info
glGenRenderbuffers(1, &rboColorId);
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_RGB8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// create a MSAA renderbuffer object to store depth info
// NOTE: A depth renderable image should be attached the FBO for depth test.
// If we don't attach a depth renderable image to the FBO, then
// the rendering output will be corrupted because of missing depth test.
// If you also need stencil test for your rendering, then you must
// attach additional image to the stencil attachement point, too.
glGenRenderbuffers(1, &rboDepthId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// attach msaa RBOs to FBO attachment points
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);
// create a normal (no MSAA) FBO to hold a render-to-texture
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// attach a texture to FBO color attachement point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
// attach a rbo to FBO depth attachement point
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
//## disable color buffer if you don't attach any color buffer image,
//## for example, rendering the depth buffer only to a texture.
//## Otherwise, glCheckFramebufferStatus will not be complete.
//glDrawBuffer(GL_NONE);
//glReadBuffer(GL_NONE);
// check FBO status
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And when I need to draw the scene
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glViewport(0, 0, width, height);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawScene();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMsaaId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glBlitFramebuffer(0, 0, width, height, // src rect
0, 0, width, height, // dst rect
GL_COLOR_BUFFER_BIT, // buffer mask
GL_LINEAR); // scale filter
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight());
The 2nd way:
Create the FBO with MSAA
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// create a multisampled color attachment texture
unsigned int textureColorBufferMultiSampled;
glGenTextures(1, &textureColorBufferMultiSampled);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0);
// create a (also multisampled) renderbuffer object for depth and stencil attachments
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// configure second post-processing framebuffer
unsigned int intermediateFBO;
glGenFramebuffers(1, &intermediateFBO);
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
// create a color attachment texture
unsigned int screenTexture;
glGenTextures(1, &screenTexture);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And when I need to draw the scene:
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glViewport(0, 0, width, height);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawScene();
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO);
glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight());
Summarizing:
1st way: Create FBO, create RBO for color and RBO for depth and use glRenderbufferStorageMultisample(...) to specify the MSAA level. Then create other FBO with texture for color and RBO for depth.
2nd way: Create FBO, create Texture for color and RBO for depth and using glTexImage2DMultisample(...) for MSAA level in the texture. Then create other FBO and a texture.
What are the differences on using one way or other? Is one better than the other?
MSAA setup in your example is actually the same in both cases. The only difference between the two methods you depicted is - different FBO attachment type. In general, you will want to attach a texture and not render buffer when you later need to use the information from that FBO for further render passes. In such a case you would plug previous render pass FBO's texture attachment into texture unit, and sample from it in the next pass shader program. Shadow mapping is one of such cases.

OpenGL Mutlisampling Multiple Render Target FBO's

I am trying Deferred Shading and I am having troubles trying to MultiSample a Multiple Render Target. It Seems as if I am only copying over one anti-Aliased Texture instead of 3 (Diffuse,Position,Normals). Only the Diffuse are copied.
This is the Anti Alias FBO creation for my Geometry Pass:
IntBuffer drawBuffs = BufferUtils.createIntBuffer(3);
private void CreateFBOAntiAlias() {
AntiAliasFrameBuffer = glGenFramebuffers();
GL30.glBindFramebuffer(GL_FRAMEBUFFER, AntiAliasFrameBuffer);
textureColorMultiSampled = generateMultiSampleTexture(4);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL32.GL_TEXTURE_2D_MULTISAMPLE, textureColorMultiSampled,
0);
texturePositionMultiSampled = generateMultiSampleTexture(4);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
GL32.GL_TEXTURE_2D_MULTISAMPLE, texturePositionMultiSampled ,
0);
textureNormalMultiSampled = generateMultiSampleTexture(4);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
GL32.GL_TEXTURE_2D_MULTISAMPLE, textureNormalMultiSampled ,
0);
drawBuffs.put(0, GL30.GL_COLOR_ATTACHMENT0);
drawBuffs.put(1, GL30.GL_COLOR_ATTACHMENT1);
drawBuffs.put(2, GL30.GL_COLOR_ATTACHMENT2);
GL20.glDrawBuffers(drawBuffs);
AntiAliasRenderBufferObject = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, AntiAliasRenderBufferObject);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4,
GL_DEPTH24_STENCIL8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, AntiAliasRenderBufferObject);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
System.err
.println("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
} else {
System.err.println("FrameBuffer AntiAliasFBO success");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
private int generateMultiSampleTexture(int samples) {
int texture;
texture = GL11.glGenTextures();
GL11.glBindTexture(GL32.GL_TEXTURE_2D_MULTISAMPLE, texture);
GL32.glTexImage2DMultisample(GL32.GL_TEXTURE_2D_MULTISAMPLE, samples,
GL11.GL_RGBA8, width, height, true);
GL11.glBindTexture(GL32.GL_TEXTURE_2D_MULTISAMPLE, 0);
return texture;
}
This is the creation for my Target FBO:
public void CreateFBO() {
fbo_handle = glGenFramebuffers();
diffuse_handle = GL11.glGenTextures();
position_handle = GL11.glGenTextures();
normal_handle = GL11.glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
//////////////////DIFFUSE////////////////////////////////////
GL11.glBindTexture(GL11.GL_TEXTURE_2D, diffuse_handle);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height,0,
GL11.GL_RGBA, GL11.GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL11.GL_TEXTURE_2D, diffuse_handle, 0);
/////////////////POSITION////////////////////////////////////
GL11.glBindTexture(GL11.GL_TEXTURE_2D, position_handle);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0,
GL11.GL_RGBA, GL11.GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
GL11.GL_TEXTURE_2D, position_handle, 0);
///////////////NORMALS/////////////////////////////////////////
GL11.glBindTexture(GL11.GL_TEXTURE_2D, normal_handle);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0,
GL11.GL_RGBA, GL11.GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
GL11.GL_TEXTURE_2D, normal_handle, 0);
//////////////////////////////////////////////////////////////////
drawBuffs.put(0, GL30.GL_COLOR_ATTACHMENT0);
drawBuffs.put(1, GL30.GL_COLOR_ATTACHMENT1);
drawBuffs.put(2, GL30.GL_COLOR_ATTACHMENT2);
GL20.glDrawBuffers(drawBuffs);
rbo_depth_buffer_handle = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth_buffer_handle);
glRenderbufferStorage(GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT32,
width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, rbo_depth_buffer_handle);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
System.err.println("Framebuffer configuration error");
} else {
System.err.println("Deferred configuration Success");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
I bind my AA FBO during the Geometry pass, unbind it and perform a Blit from the AA FBO to my Target FBO and Render the Fullscreen Quad with undesire results.
public void blit() {
GL11.glEnable(GL13.GL_MULTISAMPLE);
glBindFramebuffer(GL_READ_FRAMEBUFFER, AntiAliasFrameBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_handle);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Edit: I've tried blitting from a normal MRT fbo to another normal MRT FBO without the Multi-Sampling calls and again it seems i'm copying over just ONE texture. Rhe root of my problem is incorrectly blitting an MRT to another MRT.
Whew, ok My main problem was my blitting was incorrect. The blitting Method should be
public void blit() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, AntiAliasFrameBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_handle);
GL11.glReadBuffer(GL_COLOR_ATTACHMENT0);
GL11.glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST);
GL11.glReadBuffer(GL_COLOR_ATTACHMENT1);
GL11.glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST);
GL11.glReadBuffer(GL_COLOR_ATTACHMENT2);
GL11.glDrawBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
the general setup for my AA FBO/FBO is correct, and all textures are copied over successfully and with major improvement over Aliasing.

Copy FBO to file

I been trying to copy my FBO to file
My FBO looks like this:
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorAttachment0, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthAttachment);
and my copy to file code looks like this:
glReadBuffer(GL_COLOR_ATTACHMENT0);
unsigned char* pixels3 = new unsigned char[(int)WIDTH * (int)HEIGHT * 4];
glReadPixels(0, 0, 800, 800, GL_RGBA, GL_UNSIGNED_BYTE, pixels3);
stbi_write_png("capture3.png", WIDTH, HEIGHT, 4, pixels3, WIDTH * 4);
But the image it write out is always black.