This repository has been archived by the owner on May 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathframebuffer.c
84 lines (68 loc) · 2.67 KB
/
framebuffer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* 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);
}
}