foo
[erebus2020] / xerebus / src / main.c
1 #include <stdio.h>
2 #include "miniglut.h"
3 #include "erebus.h"
4
5 static void display(void);
6 static void reshape(int x, int y);
7 static void keyb(unsigned char key, int x, int y);
8 static void mouse(int bn, int st, int x, int y);
9 static void motion(int x, int y);
10
11 static int win_width, win_height;
12 static float win_aspect;
13 static int reshape_pending;
14
15 static struct erb_rend *erb;
16
17 static int mouse_x, mouse_y;
18 static int drag_x, drag_y;
19 static int drag;
20
21 static unsigned int fbtex;
22
23 int main(int argc, char **argv)
24 {
25         glutInit(&argc, argv);
26         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
27         glutInitWindowSize(1280, 800);
28         glutCreateWindow("X erebus");
29
30         glutDisplayFunc(display);
31         glutReshapeFunc(reshape);
32         glutKeyboardFunc(keyb);
33         glutMouseFunc(mouse);
34         glutMotionFunc(motion);
35
36         if(!(erb = erb_create())) {
37                 return 1;
38         }
39         reshape_pending = 1;
40
41         glGenTextures(1, &fbtex);
42         glBindTexture(GL_TEXTURE_2D, fbtex);
43         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
44         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
45         glEnable(GL_TEXTURE_2D);
46
47         glutMainLoop();
48         erb_destroy(erb);
49         return 0;
50 }
51
52 static void display(void)
53 {
54         if(reshape_pending) {
55                 reshape_pending = 0;
56
57                 erb_allocframe(erb, win_width, win_height);
58                 erb_begin(erb);
59
60                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, win_width, win_height, 0,
61                                 GL_RGBA, GL_FLOAT, erb_getframe(erb));
62         } else {
63                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win_width, win_height,
64                                 GL_RGBA, GL_FLOAT, erb_getframe(erb));
65         }
66         /* TODO: continue with getting notified when a block is done rendering */
67
68
69         glClear(GL_COLOR_BUFFER_BIT);
70
71         glBegin(GL_QUADS);
72         glColor3f(1, 1, 1);
73         glTexCoord2f(0, 0);
74         glVertex2f(0, 0);
75         glTexCoord2f(1, 0);
76         glVertex2f(win_width, 0);
77         glTexCoord2f(1, 1);
78         glVertex2f(win_width, win_height);
79         glTexCoord2f(0, 1);
80         glVertex2f(0, win_height);
81         glEnd();
82
83         if(drag) {
84                 glPushAttrib(GL_ENABLE_BIT);
85                 glDisable(GL_TEXTURE_2D);
86                 glEnable(GL_LOGIC_OP);
87                 glLogicOp(GL_XOR);
88
89                 glBegin(GL_LINE_LOOP);
90                 glColor3f(1, 1, 1);
91                 glVertex2f(drag_x, drag_y);
92                 glVertex2f(mouse_x, drag_y);
93                 glVertex2f(mouse_x, mouse_y);
94                 glVertex2f(drag_x, mouse_y);
95                 glEnd();
96
97                 glPopAttrib();
98         }
99
100         glutSwapBuffers();
101 }
102
103 static void reshape(int x, int y)
104 {
105         win_width = x;
106         win_height = y;
107         win_aspect = (float)x / (float)y;
108
109         glViewport(0, 0, x, y);
110
111         glMatrixMode(GL_PROJECTION);
112         glLoadIdentity();
113         glOrtho(0, x, y, 0, -1, 1);
114
115         reshape_pending = 1;
116         glutPostRedisplay();
117 }
118
119 static void keyb(unsigned char key, int x, int y)
120 {
121         if(key == 27) {
122                 glutExit();
123         }
124         glutPostRedisplay();
125 }
126
127 static void mouse(int bn, int st, int x, int y)
128 {
129         int rect[4];
130
131         mouse_x = x;
132         mouse_y = y;
133
134         if(bn == 0) {
135                 if(st == GLUT_DOWN) {
136                         drag = 1;
137                         drag_x = x;
138                         drag_y = y;
139                 } else {
140                         drag = 0;
141
142                         rect[0] = x < drag_x ? x : drag_x;
143                         rect[1] = y < drag_y ? y : drag_y;
144                         rect[2] = abs(x - drag_x);
145                         rect[3] = abs(y - drag_y);
146
147                         erb_queue_block(erb, rect[0], rect[1], rect[2], rect[3]);
148                         printf("rect: %d,%d %dx%d\n", rect[0], rect[1], rect[2], rect[3]);
149                 }
150
151                 glutPostRedisplay();
152         }
153 }
154
155 static void motion(int x, int y)
156 {
157         mouse_x = x;
158         mouse_y = y;
159
160         glutPostRedisplay();
161 }