Framebuffer Object creation error - opengl

EDIT: SOLVED
I encountered a problem while attempting to render into a texture. I create a framebuffer object like this:
glGenTextures(1, &renderFBOtex);
glBindTexture(GL_TEXTURE_2D, renderFBOtex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &renderFBOrender);
glBindRenderbuffer(GL_RENDERBUFFER, renderFBOrender);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenFramebuffers(1, &renderFBO);
glBindFramebuffer(GL_FRAMEBUFFER, renderFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderFBOtex, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderFBOrender);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
But the return value of glCheckFrambufferStatus is always GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT.
The problem seems to be with the texture, as it is the same without the Renderbuffer attachment. Drawing into the Framebuffer itself shouldn't be a problem.
Could someone please point out what am I missing here?

Build texture mipmaps before attaching it on the color buffer.
The routine dedicated to this task is glGenerateMipmap.
Another suggestion would be to play with the texture internal format. You are not specifying a sized internal format. Since one of reason of the error is that the texture doesn't have a supported color-renderable internal format, you could give a try.

Problem was in another part of the program. It was a very stupid mistake, which led to use of wrongly initialized values for width and height of the texture. They were both set to 0, hence the incomplete attachment error.

Try this:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderFBOtex, 0);
^^^^
Technically they should make no difference, but some drivers may had this bug.

Related

C++ OpenGL - Overlay example

I've an OpenGL application (maze style) that I need to work on as soon as possible. My problem at the moment is the following:
I've 3 subwindows on my main window and they are all working fine. Aparently I should be only using one subwindow and the left side subwindows (smaller ones) should be displayed as an overlay. My actual app has the following window display:
And I would like to go for something like this:
I've searched the internet and so far I've found nothing about this subject. Is there anywhere I can read about on how to solve this?
Thank you very much.
You could render the overlays to a texture, and then render this wherever you want on the screen. Look into the gl*FrameBuffer functions. It might look something like this:
// Create a texture to render to
glGenTextures(1, &overlay_tex);
glBindTexture(GL_TEXTURE_2D, overlay_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// NULL means reserve texture memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
// Attach the texture to the framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, overlay_tex, 0);
glGenRenderbuffers(1, &depth_rb);
glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
// Render your overlay here
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Render to the backbuffer again

OpenGL - FBO and alpha blending

I was finding for answer, but I can't get answer for my problem.
I have FBO and I can't get alpha blending and multisample to work. FBO draws scene to texture and then it's drown to default framebuffer with two textured triangles. Drawing directly to default framebuffer is fine.
Here is difference between default framebuffer (top) and my FBO (bottom).
I use FBO with 2x color attachments and 1x depth attachments. (Only GL_COLOR_ATTACHMENT0 is used, second is for other function)
Depth test: Disabled
Blending: Enabled
Multisample: Enabled
Blending function: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
Any ideas? What am I doing wrong? I can't blend any transparent objects, there is no alpha. If you require more code, I can edit post.
EDIT:
This code is deeper in code structure, I hope, I extracted it properly.
Setup FBO:
glGenFramebuffers(1, &_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color0_texture_id, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, color1_texture_id, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture_id, 0);
Setup color texture:
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
Depth texture is the same except one line:
// This is probably wrong
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
EDIT:
Blending is working now, but still no multisample. How to do it?
To use multisampling when rendering to an FBO you need to allocate a multisample texture using glTexImage2DMultisample and attach that to the FBO using GL_TEXTURE_2D_MULTISAMPLE instead of GL_TEXTURE_2D.
Source: https://www.opengl.org/wiki/Multisampling#Allocating_a_Multisample_Render_Target

Attaching Framebuffer to Texture error

I am trying to implement shadow mapping with the tutorial here, however when I try to use this code to attach a Framebuffer to a texture it fails. My OpenGL context is 3.1 and I believe i have an Intel 3000 series graphics card. The code fails at 2 points. The first failure is at glFramebufferTexture2D, which gives error code 1282 (Not sure what enumeration that corresponds too). I believe this error is causing the assert assi later in the code to fail. I have tried code from similar questions but they do not seem to work in this case.
glGenFramebuffers(1, &MObject::fbo);
glGenTextures(1, &MObject::shadowMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windowWidth, windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindFramebuffer(GL_FRAMEBUFFER, MObject::fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, MObject::shadowMap, 0);
GLenum err = glGetError(); // Error code: 1282
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assi(status == GL_FRAMEBUFFER_COMPLETE, "FBO error!"); // Expression is false, abort called.
Yea so I forgot glBindTexture. I hate myself. Thank you Hectigo!

Shadow mapping. Framebuffer error 36060

I am doing this from a tutorial and i have exactly the code from the tutorial. But for some reason is not working. So i debugged and i saw that it had a 36060 error also know as GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER as far as i know and i don't really understand why. I searched for answers and everybody said about glReadBuffer(GL_NONE); But even with that i get the same error.
bool ShadowMapFBO::Init(unsigned int WindowWidth, unsigned int WindowHeight)
{
// Create the FBO
glGenFramebuffers(1, &m_fbo);
// Create the depth buffer
glGenTextures(1, &m_shadowMap);
glBindTexture(GL_TEXTURE_2D, m_shadowMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);
// Disable writes to the color buffer
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
printf("FB error, status: 0x%x\n", Status);
return false;
}
return true;
}
EDIT: seems like glReadBuffer doesn't work at all and I don't know why. I tried glGetError and i got no error
I solved the problem. Seems like I had to add glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
Seems like if you don't need it if you have a nvidia video card. I had a intel integrated video card and that's why it didn't worked.

Retrieving final scene z-buffer and color buffer

I'm working on opengl 2.1 and opengl es 2.0. I want to implement Depth-of-field effect for whole scene. I know how to do this for single model with shader, but this would require all models to have shader with same code. Is there a way to retrieve final scene depth and color buffer and store them into textures so I could use them again with DOF shader? Or is it a bad idea?
[EDIT]
Finally got it working.
The initialization code looks like this:
glGenFramebuffers(1, &frameBuffer_);
glGenTextures(1, &colorBuffer_);
glGenTextures(1, &depthBuffer_);
//glGenRenderbuffers(1, &depthBuffer_);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_);
glBindTexture(GL_TEXTURE_2D, colorBuffer_);
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, colorBuffer_, 0);
glBindTexture(GL_TEXTURE_2D, depthBuffer_);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_DEPTH24_STENCIL8,
width,
height,
0,
GL_DEPTH_STENCIL,
GL_UNSIGNED_INT_24_8,
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_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depthBuffer_, 0);
//glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_);
//glRenderbufferStorage(
// GL_RENDERBUFFER,
// GL_DEPTH_COMPONENT24,
// width,
// height);
//glFramebufferRenderbuffer(
// GL_FRAMEBUFFER,
// GL_DEPTH_ATTACHMENT,
// GL_RENDERBUFFER, depthBuffer_);
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
// Success.
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
LOGE("Frame buffer format not supported.");
break;
default:
LOGE("Framebuffer Error.");
}
And later when rendering first call:
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_);
Render scene, then call:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And now anything can be rendered here using depthBuffer_ or colorBuffer_ as OpengGL texture handles.
Use a framebuffer object. They're part of OpenGL-ES-2 and are available as (well supported) extension to OpenGL-2.1.
See
https://github.com/datenwolf/codesamples/tree/master/samples/OpenGL/minimalfbo
for a minimal working example using extensions on desktop OpenGL-2.x