xerebus: average samples in shader
[erebus2020] / xerebus / src / main.c
1 #include <stdio.h>
2 #include "opengl.h"
3 #include "miniglut.h"
4 #include "erebus.h"
5 #include "sdr.h"
6
7 static void display(void);
8 static void reshape(int x, int y);
9 static void keyb(unsigned char key, int x, int y);
10 static void mouse(int bn, int st, int x, int y);
11 static void motion(int x, int y);
12
13 static int win_width, win_height;
14 static float win_aspect;
15 static int reshape_pending;
16
17 static struct erb_rend *erb;
18
19 static int mouse_x, mouse_y;
20 static int drag_x, drag_y;
21 static int drag;
22
23 static float disp_gamma = 2.2f;
24
25 static unsigned int fbtex;
26 static unsigned int sdr;
27
28 static const char *vs_src =
29         "void main()\n"
30         "{\n"
31         "       gl_Position = ftransform();\n"
32         "       gl_TexCoord[0] = gl_MultiTexCoord0;\n"
33         "}\n";
34
35 static const char *ps_src =
36         "uniform sampler2D tex;\n"
37         "uniform float inv_gamma;\n"
38         "\n"
39         "void main()\n"
40         "{\n"
41         "       vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n"
42         "       gl_FragColor.rgb = pow(texel.xyz / texel.w, vec3(inv_gamma));\n"
43         "       gl_FragColor.a = 1.0;\n"
44         "}\n";
45
46
47 int main(int argc, char **argv)
48 {
49         unsigned int vs, ps;
50
51         glutInit(&argc, argv);
52         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
53         glutInitWindowSize(1280, 800);
54         glutCreateWindow("X erebus");
55
56         glutDisplayFunc(display);
57         glutReshapeFunc(reshape);
58         glutKeyboardFunc(keyb);
59         glutMouseFunc(mouse);
60         glutMotionFunc(motion);
61
62         if(!(vs = create_vertex_shader(vs_src))) {
63                 return 1;
64         }
65         if(!(ps = create_pixel_shader(ps_src))) {
66                 return 1;
67         }
68         if(!(sdr = create_program_link(vs, ps, 0))) {
69                 return 1;
70         }
71         set_uniform_float(sdr, "inv_gamma", 1.0f / disp_gamma);
72
73         if(!(erb = erb_create())) {
74                 return 1;
75         }
76         reshape_pending = 1;
77
78         glGenTextures(1, &fbtex);
79         glBindTexture(GL_TEXTURE_2D, fbtex);
80         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
82
83         glutMainLoop();
84         erb_destroy(erb);
85         return 0;
86 }
87
88 static void display(void)
89 {
90         if(reshape_pending) {
91                 reshape_pending = 0;
92
93                 erb_allocframe(erb, win_width, win_height);
94                 erb_begin(erb);
95
96                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, win_width, win_height, 0,
97                                 GL_RGBA, GL_FLOAT, erb_getframe(erb));
98         } else {
99                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win_width, win_height,
100                                 GL_RGBA, GL_FLOAT, erb_getframe(erb));
101         }
102         /* TODO: continue with getting notified when a block is done rendering */
103
104
105         glClear(GL_COLOR_BUFFER_BIT);
106
107         glUseProgram(sdr);
108
109         glBegin(GL_QUADS);
110         glColor3f(1, 1, 1);
111         glTexCoord2f(0, 0);
112         glVertex2f(0, 0);
113         glTexCoord2f(1, 0);
114         glVertex2f(win_width, 0);
115         glTexCoord2f(1, 1);
116         glVertex2f(win_width, win_height);
117         glTexCoord2f(0, 1);
118         glVertex2f(0, win_height);
119         glEnd();
120
121         if(drag) {
122                 glUseProgram(0);
123
124                 glEnable(GL_LOGIC_OP);
125                 glLogicOp(GL_XOR);
126
127                 glBegin(GL_LINE_LOOP);
128                 glColor3f(1, 1, 1);
129                 glVertex2f(drag_x, drag_y);
130                 glVertex2f(mouse_x, drag_y);
131                 glVertex2f(mouse_x, mouse_y);
132                 glVertex2f(drag_x, mouse_y);
133                 glEnd();
134
135                 glDisable(GL_LOGIC_OP);
136         }
137
138         glutSwapBuffers();
139 }
140
141 static void reshape(int x, int y)
142 {
143         win_width = x;
144         win_height = y;
145         win_aspect = (float)x / (float)y;
146
147         glViewport(0, 0, x, y);
148
149         glMatrixMode(GL_PROJECTION);
150         glLoadIdentity();
151         glOrtho(0, x, y, 0, -1, 1);
152
153         reshape_pending = 1;
154         glutPostRedisplay();
155 }
156
157 static void keyb(unsigned char key, int x, int y)
158 {
159         if(key == 27) {
160                 glutExit();
161         }
162         glutPostRedisplay();
163 }
164
165 static void mouse(int bn, int st, int x, int y)
166 {
167         int rect[4];
168
169         mouse_x = x;
170         mouse_y = y;
171
172         if(bn == 0) {
173                 if(st == GLUT_DOWN) {
174                         drag = 1;
175                         drag_x = x;
176                         drag_y = y;
177                 } else {
178                         drag = 0;
179
180                         rect[0] = x < drag_x ? x : drag_x;
181                         rect[1] = y < drag_y ? y : drag_y;
182                         rect[2] = abs(x - drag_x);
183                         rect[3] = abs(y - drag_y);
184
185                         erb_queue_block(erb, rect[0], rect[1], rect[2], rect[3]);
186                         printf("rect: %d,%d %dx%d\n", rect[0], rect[1], rect[2], rect[3]);
187                 }
188
189                 glutPostRedisplay();
190         }
191 }
192
193 static void motion(int x, int y)
194 {
195         mouse_x = x;
196         mouse_y = y;
197
198         glutPostRedisplay();
199 }