Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
85 lines (68 sloc) 2.67 KB
/* See Copyright Notice in LICENSE.txt */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include "utlist.h"
#include "misc.h"
#define MAX_CACHED 30
typedef struct framebuffer {
GLuint fbo;
GLuint tex;
int width;
int height;
struct framebuffer *prev;
struct framebuffer *next;
} framebuffer_t;
static framebuffer_t *framebuffers = NULL;
static int num_framebuffers = 0;
static void unlink_framebuffer(framebuffer_t *framebuffer) {
DL_DELETE(framebuffers, framebuffer);
free(framebuffer);
num_framebuffers--;
}
void make_framebuffer(int width, int height, GLuint *tex, GLuint *fbo) {
framebuffer_t *framebuffer, *tmp;
DL_FOREACH_SAFE(framebuffers, framebuffer, tmp) {
// Same size?
if (framebuffer->height == height && framebuffer->width == width) {
*tex = framebuffer->tex;
*fbo = framebuffer->fbo;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->fbo);
glBindTexture(GL_TEXTURE_2D, framebuffer->tex);
unlink_framebuffer(framebuffer);
return;
}
}
glGenFramebuffers(1, fbo);
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
fprintf(stderr, INFO("new framebuffer (%dx%d): %u\n"), width, height, *fbo);
glGenTextures(1, tex);
glBindTexture(GL_TEXTURE_2D, *tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *tex, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
die("cannot initialize new framebuffer");
}
void recycle_framebuffer(int width, int height, GLuint tex, GLuint fbo) {
framebuffer_t *framebuffer = xmalloc(sizeof(framebuffer_t));
framebuffer->width = width;
framebuffer->height = height;
framebuffer->tex = tex;
framebuffer->fbo = fbo;
// fprintf(stderr, "added recyleable framebuffer %dx%d %d %d\n", framebuffer->width, framebuffer->height,
// framebuffer->tex, framebuffer->fbo);
DL_APPEND(framebuffers, framebuffer);
num_framebuffers++;
if (num_framebuffers > MAX_CACHED) {
fprintf(stderr, ERROR("too many framebuffers in use\n"));
glDeleteFramebuffers(1, &framebuffers->fbo);
glDeleteTextures(1, &framebuffers->tex);
unlink_framebuffer(framebuffers);
}
}