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.
Related
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.
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
I'm trying to implement deferred rendering in my engine but I'm having some problems.
It seems that there is some static in the triangles being drawn.
Here is the drawing code:
// GEOMETRY PASS
gbuffer->BindForWriting(); // glBind(GL_DRAW_FRAMEBUFFER, fbo);
window->Clear(); // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST); // Before it was glDisable(GL_DEPTH_TEST); (I was testing)
... // Render all objects (they are rendering well when not using deferred rendering)
// LIGHTING PASS
glBindFramebuffer(GL_FRAMEBUFFER, 0);
window->Clear(); // Clear buffer again (same thing above)
gbuffer->BindForReading(); // glBind(GL_READ_FRAMEBUFFER, fbo);
GLsizei HalfWidth = (GLsizei)(window->GetSize().x / 2.0f);
GLsizei HalfHeight = (GLsizei)(window->GetSize().y / 2.0f); // Get half the size of the window
gbuffer->SetReadBuffer(GBUFFER_POSITION); // glReadBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, window->GetSize().x, window->GetSize().y, 0, 0, HalfWidth, HalfHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
gbuffer->SetReadBuffer(GBUFFER_DIFFUSE); // glReadBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, window->GetSize().x, window->GetSize().y, 0, HalfHeight, HalfWidth, window->GetSize().y, GL_COLOR_BUFFER_BIT, GL_LINEAR);
gbuffer->SetReadBuffer(GBUFFER_NORMAL); // glReadBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(0, 0, window->GetSize().x, window->GetSize().y, HalfWidth, HalfHeight, window->GetSize().x, window->GetSize().y, GL_COLOR_BUFFER_BIT, GL_LINEAR);
gbuffer->SetReadBuffer(GBUFFER_TEXCOORD); // glReadBuffer(GL_COLOR_ATTACHMENT3);
glBlitFramebuffer(0, 0, window->GetSize().x, window->GetSize().y, HalfWidth, 0, window->GetSize().x, HalfHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
(upleft is diffuse, upright is normals, downleft is position and downright is texture coords)
EDIT:
New screenshot after i enabled GL_DEPTH_TEST:
EDIT 2
Here is the GBuffer setup:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glGenTextures(4, textures);
glGenTextures(1, &depthTexture);
for (int i = 0; i < 4; i++) {
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, windowSize.x, windowSize.y, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i], 0);
}
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, windowSize.x, windowSize.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
GLenum drawBuffers[] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
glDrawBuffers(4, drawBuffers);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
// PRINT ERROR TO LOG ( No errors here i've already checked)
return;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
EDIT 3 I'm following this tutorial if it helps in anything
I forgot to disable GL_BLEND before drawing the objects in the buffer.
Now it's working fine.
glDisable(GL_BLEND);
(Deferred rendering...)
glEnable(GL_BLEND);
I've searched for couple hours for a solution to my problem.
First of all. I have HD 7800 series amd GPU, newest drivers.
I'm trying to create framebuffer class which has all the framebuffer functions I will need. It seems I got renderbuffers to work, but drawing to texture is causing really weird errors.
FrameBuffer::FrameBuffer(int width, int height)
{
createFrameBuffer();
// createDepthBufferAttachment(width, height); //commented out for testing (THIS WORKS)
createTextureAttachment(width, height);
// createDepthTextureAttachment(width, height); //commented out for testing
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
std::cerr << glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\nFramebuffer failed to generate! 0\n";
}
unbindFrameBuffer();
}
FrameBuffer::~FrameBuffer()
{
if (fbo != NULL)
glDeleteFramebuffers(1, &fbo);
if (colorTexture != NULL)
glDeleteTextures(1, &colorTexture);
if (depthBuffer != NULL)
glDeleteRenderbuffers(1, &depthBuffer);
if (depthTexture != NULL)
glDeleteTextures(1, &depthTexture);
}
void FrameBuffer::createFrameBuffer(){
glGenFramebuffers(1, &fbo);
}
void FrameBuffer::createTextureAttachment(int width, int height){
glGenTextures(1, &colorTexture);
glBindTexture(GL_TEXTURE_2D, colorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, GL_RGBA, 0, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
std::cerr << glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\nFramebuffer failed to generate! 1\n";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::createDepthTextureAttachment(int width, int height){
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, width, height, GL_DEPTH_COMPONENT, 0, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
std::cerr << glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\nFramebuffer failed to generate! 2\n";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::createDepthBufferAttachment(int width, int height){
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
std::cerr << glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\nFramebuffer failed to generate! 3\n";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::bindFrameBuffer( int width, int height){
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, width, height);
}
void FrameBuffer::unbindFrameBuffer(){
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, DisplayManager::getWidth(), DisplayManager::getHeight());
}
glCheckFrameBufferStatus returns GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
at both checks. The same happens with the createDepthTextureAttachment()
Neither one seems to not work
createDepthBufferAttachment() works fine.
More info:
Yes, indeed I'm actually giving width and height to the function, they are both 1024.
I've tried changing the GL_RGBA to GL_RGB, and Tried different sizes of GL_DEPTH_COMPONENT too.
At the moment I'm intending on using only 1 texture, not all 3 functions.
I don't know if it matters but SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); is set.
I've also tried glFramebufferTexture() function instead.
Thank you in advance!
The order of arguments in your glTexImage2D() calls is wrong. Looking at the first one:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, GL_RGBA, 0, GL_UNSIGNED_BYTE, NULL);
Comparing that to the function definition:
void glTexImage2D(
GLenum target,
GLint level,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const GLvoid* data);
you can see that the 6th argument is the border width, and the 7th is the format. You have those two inverted. The call should be:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
The same thing applies to the other call.
Anytime you have problems getting your OpenGL code working, I strongly recommend to call glGetError(). It would quickly tell you that there are errors from these calls.
I'm trying to render 3D scene to multisample FBO. I creating FBO with following code FBO:
GLuint fbo, vtex, depthbuffer;
glGenTextures(1, &vtex); GLCHECK();
glBindTexture( vtarget, vtex ); GLCHECK();
glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, samples /*=4*/, GL_RGBA, width, height, false); GLCHECK();
glBindTexture(vtarget, 0); GLCHECK();
glGenRenderbuffers(1, &depthbuffer); GLCHECK();
glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); GLCHECK();
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples/*=4*/, GL_DEPTH_COMPONENT32, width, height); GLCHECK();
glBindRenderbuffer(GL_RENDERBUFFER, 0); GLCHECK();
glGenFramebuffers( 1, &fbo );GLCHECK();
glBindFramebuffer( GL_FRAMEBUFFER, fbo );GLCHECK();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); GLCHECK();
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, vtex, 0 ); GLCHECK();
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "Can't allocate frame buffer! Status: 0x%x\n", status);
assert(0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); GLCHECK();
And I get error GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE. What I'm doing wrong?
A have read this topic, FBO documentation, but it doesn't help.
I can create FBO without depth attachment. But in this case it doesn't working when I trying bilt it to the screen:
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); GLCHECK();
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); GLCHECK();
glDrawBuffer(GL_BACK); GLCHECK();
glBlitFramebuffer(0, 0, resolution.width, resolution.height, 0, 0, resolution.width, resolution.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); GLCHECK();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Help me please.
You need to specify fixed sample locations. e.g. GL_TRUE for the last parameter of glTexImage2DMultisample.
You can read about the reasons for GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE here.