fixed incorrect checking of the existence of GLX_EXT_swap_control and friends
[demo_prior] / src / post.c
1 #include "opengl.h"
2 #include "texture.h"
3 #include "post.h"
4 #include "demo.h"
5 #include "opt.h"
6 #include "sdr.h"
7
8 static unsigned int post_fbtex_gltexid[2];
9 static unsigned int rbuf_depth[2];
10
11 unsigned int post_fbo[2];
12 struct texture post_fbtex[2];
13 int post_fbtex_cur;
14
15 unsigned int sdr_vgn;
16 int vgn_uloc_color, vgn_uloc_offs, vgn_uloc_sharp;
17
18 int post_init(void)
19 {
20         int i;
21
22         if(!(sdr_vgn = create_program_load("sdr/post.v.glsl", "sdr/vignette.p.glsl"))) {
23                 return -1;
24         }
25         glUseProgram(sdr_vgn);
26         vgn_uloc_color = get_uniform_loc(sdr_vgn, "color");
27         vgn_uloc_offs = get_uniform_loc(sdr_vgn, "offset");
28         vgn_uloc_sharp = get_uniform_loc(sdr_vgn, "sharpness");
29
30
31         glGenTextures(2, post_fbtex_gltexid);
32         glGenRenderbuffers(2, rbuf_depth);
33
34         for(i=0; i<2; i++) {
35                 post_fbtex[i].id = post_fbtex_gltexid[i];
36                 post_fbtex[i].width = 0;
37                 post_fbtex[i].height = 0;
38                 post_fbtex[i].pixels = 0;
39
40                 glBindTexture(GL_TEXTURE_2D, post_fbtex[i].id);
41                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
42                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
43         }
44         return 0;
45 }
46
47 void post_cleanup(void)
48 {
49         if(post_fbtex_gltexid[0]) {
50                 glDeleteTextures(2, post_fbtex_gltexid);
51         }
52         if(rbuf_depth[0]) {
53                 glDeleteRenderbuffers(2, rbuf_depth);
54         }
55         if(post_fbo[0]) {
56                 glDeleteFramebuffers(2, post_fbo);
57         }
58
59         if(sdr_vgn) {
60                 free_program(sdr_vgn);
61         }
62 }
63
64 void post_reshape(int x, int y)
65 {
66         int i, ifmt;
67
68         if(x != post_fbtex[0].width || y != post_fbtex[0].height) {
69                 ifmt = opt.srgb ? GL_SRGB_ALPHA : GL_RGBA;
70
71                 for(i=0; i<2; i++) {
72                         glBindTexture(GL_TEXTURE_2D, post_fbtex[i].id);
73                         glTexImage2D(GL_TEXTURE_2D, 0, ifmt, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
74                         post_fbtex[i].width = x;
75                         post_fbtex[i].height = y;
76
77                         glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth[i]);
78                         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, x, y);
79                 }
80
81                 if(!post_fbo[0]) {
82                         glGenFramebuffers(2, post_fbo);
83                         for(i=0; i<2; i++) {
84                                 glBindFramebuffer(GL_FRAMEBUFFER, post_fbo[i]);
85                                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, post_fbtex_gltexid[i], 0);
86                                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth[i]);
87                         }
88                         glBindFramebuffer(GL_FRAMEBUFFER, 0);
89                 }
90         }
91 }
92
93 void overlay(unsigned int tex, float aspect, float alpha)
94 {
95         float xscale = aspect / win_aspect;
96
97         glMatrixMode(GL_MODELVIEW);
98         glPushMatrix();
99         glLoadIdentity();
100         glMatrixMode(GL_PROJECTION);
101         glPushMatrix();
102         glLoadIdentity();
103         glScalef(xscale, 1.0, 1.0);
104
105         glPushAttrib(GL_ENABLE_BIT);
106         glDisable(GL_DEPTH_TEST);
107         glDisable(GL_LIGHTING);
108         glEnable(GL_BLEND);
109         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
110
111         if(tex) {
112                 glEnable(GL_TEXTURE_2D);
113                 glBindTexture(GL_TEXTURE_2D, tex);
114         } else {
115                 glDisable(GL_TEXTURE_2D);
116         }
117
118         glBegin(GL_QUADS);
119         glColor4f(1, 1, 1, alpha);
120         glTexCoord2f(0, 0);
121         glVertex2f(-1, -1);
122         glTexCoord2f(1, 0);
123         glVertex2f(1, -1);
124         glTexCoord2f(1, 1);
125         glVertex2f(1, 1);
126         glTexCoord2f(0, 1);
127         glVertex2f(-1, 1);
128         glEnd();
129
130         glPopAttrib();
131
132         glPopMatrix();
133         glMatrixMode(GL_MODELVIEW);
134         glPopMatrix();
135 }
136
137 void overlay_tex(struct texture *tex, float alpha)
138 {
139         unsigned int tid;
140         float aspect;
141         if(tex) {
142                 tid = tex->id;
143                 aspect = (float)tex->width / tex->height;
144         } else {
145                 tid = 0;
146                 aspect = 1.0f;
147         }
148         overlay(tid, aspect, alpha);
149 }
150
151 void vignette(float r, float g, float b, float offs, float sharp)
152 {
153         glUseProgram(sdr_vgn);
154         if(vgn_uloc_color >= 0) {
155                 glUniform3f(vgn_uloc_color, r, g, b);
156         }
157         if(vgn_uloc_offs >= 0) {
158                 glUniform1f(vgn_uloc_offs, offs);
159         }
160         if(vgn_uloc_sharp >= 0) {
161                 glUniform1f(vgn_uloc_sharp, sharp);
162         }
163         overlay(0, 1.0, 1.0);
164 }