- moved fbtex to post.c, made it a ping-pong buffer, added fbos for it.
[demo_prior] / src / post.c
1 #include <assert.h>
2 #include "opengl.h"
3 #include "texture.h"
4 #include "post.h"
5 #include "demo.h"
6 #include "opt.h"
7
8 static unsigned int fbtex_gltexid[2];
9 static unsigned int fbo[2], rbuf_depth[2];
10 struct texture fbtex[2];
11 int fbtex_cur;
12
13 int post_init(void)
14 {
15         int i;
16
17         glGenTextures(2, fbtex_gltexid);
18         glGenRenderbuffers(2, rbuf_depth);
19
20         for(i=0; i<2; i++) {
21                 fbtex[i].id = fbtex_gltexid[i];
22                 fbtex[i].width = 0;
23                 fbtex[i].height = 0;
24                 fbtex[i].pixels = 0;
25
26                 glBindTexture(GL_TEXTURE_2D, fbtex[i].id);
27                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
28                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
29         }
30         return 0;
31 }
32
33 void post_cleanup(void)
34 {
35         if(fbtex_gltexid[0]) {
36                 glDeleteTextures(2, fbtex_gltexid);
37         }
38         if(rbuf_depth[0]) {
39                 glDeleteRenderbuffers(2, rbuf_depth);
40         }
41         if(fbo[0]) {
42                 glDeleteFramebuffers(2, fbo);
43         }
44 }
45
46 void post_reshape(int x, int y)
47 {
48         int i, ifmt;
49
50         if(x != fbtex[0].width || y != fbtex[0].height) {
51                 ifmt = opt.srgb ? GL_SRGB_ALPHA : GL_RGBA;
52
53                 for(i=0; i<2; i++) {
54                         glBindTexture(GL_TEXTURE_2D, fbtex[i].id);
55                         glTexImage2D(GL_TEXTURE_2D, 0, ifmt, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
56                         fbtex[i].width = x;
57                         fbtex[i].height = y;
58
59                         glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth[i]);
60                         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, x, y);
61                 }
62
63                 if(!fbo[0]) {
64                         glGenFramebuffers(2, fbo);
65                         for(i=0; i<2; i++) {
66                                 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
67                                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbtex_gltexid[i], 0);
68                                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth[i]);
69                         }
70                         glBindFramebuffer(GL_FRAMEBUFFER, 0);
71                 }
72         }
73 }
74
75 void overlay(unsigned int tex, float aspect, float alpha)
76 {
77         float xscale = aspect / win_aspect;
78
79         glMatrixMode(GL_MODELVIEW);
80         glPushMatrix();
81         glLoadIdentity();
82         glMatrixMode(GL_PROJECTION);
83         glPushMatrix();
84         glLoadIdentity();
85         glScalef(xscale, 1.0, 1.0);
86
87         glPushAttrib(GL_ENABLE_BIT);
88         glDisable(GL_DEPTH_TEST);
89         glDisable(GL_LIGHTING);
90         glEnable(GL_BLEND);
91         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
92         glEnable(GL_TEXTURE_2D);
93
94         glBindTexture(GL_TEXTURE_2D, tex);
95
96         glBegin(GL_QUADS);
97         glColor4f(1, 1, 1, alpha);
98         glTexCoord2f(0, 1);
99         glVertex2f(-1, -1);
100         glTexCoord2f(1, 1);
101         glVertex2f(1, -1);
102         glTexCoord2f(1, 0);
103         glVertex2f(1, 1);
104         glTexCoord2f(0, 0);
105         glVertex2f(-1, 1);
106         glEnd();
107
108         glPopAttrib();
109
110         glPopMatrix();
111         glMatrixMode(GL_MODELVIEW);
112         glPopMatrix();
113 }
114
115 void overlay_tex(struct texture *tex, float alpha)
116 {
117         overlay(tex->id, (float)tex->width / tex->height, alpha);
118 }