Well, usage of FBO is wide and it helps make complex effects much easier. I set FBO and draw to it, then render FBO textured quad, without any problem, even test simple screen processing color shader. But everything I render to FBO became upside down for some reason. If I render to stock screen FBO everything is normal, and I don't even perform any rotations to sprite.
FBO creation
typedef struct tex
{
dim2i size; // int width, int height
GLuint id;
} tex;
typedef struct fbo
{
GLuint frame_buffer;
tex buffer_tex;
}fbo;
void set_fbo(fbo* res, int width, int height)
{
GLint tex_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_size);
GLint render_buffer_size;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &render_buffer_size);
LOGI("Max render buffer size: %d, max texture size: %d", render_buffer_size, tex_size); //max render buffer size: 3838, max texture size: 2048
glGenFramebuffers(1, &res->frame_buffer);
GLuint depth_buffer;
glGenRenderbuffers(1, &depth_buffer);
glGenTextures(1, &res->buffer_tex.id);
res->buffer_tex.size.w = width;
res->buffer_tex.size.h = height;
glBindTexture(GL_TEXTURE_2D, res->buffer_tex.id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, res->buffer_tex.size.w, res->buffer_tex.size.h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, res->buffer_tex.size.w, res->buffer_tex.size.h);
glBindFramebuffer(GL_FRAMEBUFFER, res->frame_buffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, res->buffer_tex.id, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
LOGE("BUFFER OK");
else
LOGE("BUFFER NOT OK");
//BUFFER OK
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
FBO usage
static fbo FBO;
static decor DECOR; //shield quad
static decor SCREEN_DECOR;// FBO textured quad
void on_surface_changed(int width, int height)
{
set_fbo(&FBO, width, height);
...
}
void on_draw()
{
glBindFramebuffer(GL_FRAMEBUFFER, FBO.frame_buffer);
set_render_color(YELLOW); //glClearColor(...)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_decor(&DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
set_render_color(BLACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_decor(&SCREEN_DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ));
}
Result: Result with grayscale shader:
Render without FBO:
void on_draw_simple()
{
set_render_color(YELLOW); //glClearColor(...)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_decor(&DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ));
}
Aggregated from the comments:
This happens because OpenGL has the origin in the lower left corner, unlike most windowing systems in use, where the origin is in the upper left corner.
Simply make sure that the texture coordinates goes from 0,1 in upper left to 1,0 in lower right to draw the FBO correctly, or draw the quad with the texture flipped vertically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With