tile generator
[megadrive_tetris] / tools / tilegen / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <GL/glut.h>
4 #include <assert.h>
5
6 struct vec3 {
7         float x, y, z;
8 };
9
10 void disp(void);
11 void draw_field(int xcells, int ycells);
12 void draw_tile(int col, int row, int xcells, int ycells);
13 void set_view_matrix(int eye, float ipd);
14 void set_proj_matrix(int eye, float ipd);
15 void reshape(int x, int y);
16 void keyb(unsigned char key, int x, int y);
17
18 static int win_width = 320;
19 static int win_height = 640;
20 static float aspect;
21 static int view = 0;
22 static float eye_dist = 1.4;
23
24 int main(int argc, char **argv)
25 {
26         glutInit(&argc, argv);
27         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
28         glutInitWindowSize(win_width, win_height);
29         glutCreateWindow("tilegen");
30
31         glutDisplayFunc(disp);
32         glutReshapeFunc(reshape);
33         glutKeyboardFunc(keyb);
34
35         glClearColor(0.05, 0.05, 0.05, 1);
36         glEnable(GL_CULL_FACE);
37         glShadeModel(GL_FLAT);
38
39         glutMainLoop();
40         return 0;
41 }
42
43 void disp(void)
44 {
45         glClear(GL_COLOR_BUFFER_BIT);
46
47         glColorMask(1, 0, 0, 0);
48
49         set_proj_matrix(-1, eye_dist);
50         set_view_matrix(-1, eye_dist);
51         glTranslatef(0, 0, -1);
52
53         draw_field(10, 20);
54
55         glColorMask(0, 1, 1, 0);
56
57         set_proj_matrix(1, eye_dist);
58         set_view_matrix(1, eye_dist);
59         glTranslatef(0, 0, -1);
60
61         draw_field(10, 20);
62
63         glColorMask(1, 1, 1, 1);
64
65         glutSwapBuffers();
66         assert(glGetError() == GL_NO_ERROR);
67 }
68
69 void draw_field(int xcells, int ycells)
70 {
71         int i, j;
72
73         for(i=0; i<ycells; i++) {
74                 for(j=0; j<xcells; j++) {
75                         draw_tile(j, i, xcells, ycells);
76                 }
77         }
78
79         /*
80         glBegin(GL_LINES);
81         glColor3f(1, 0, 0);
82         glVertex2f(-100, 0);
83         glVertex2f(100, 0);
84         glColor3f(0, 1, 0);
85         glVertex2f(0, -100);
86         glVertex2f(0, 100);
87         glEnd();
88         */
89 }
90
91 #define DX      0.4
92 #define DZ      0.3
93
94 static struct vec3 tileverts[] = {
95         {-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0},
96         {-1 + DX, -1 + DX, DZ}, {1 - DX, -1 + DX, DZ},
97         {1 - DX, 1 - DX, DZ}, {-1 + DX, 1 - DX, DZ}
98 };
99 static struct vec3 tilecol[] = {
100         {0.8, 0.8, 0.8},        /* left */
101         {0.2, 0.2, 0.2},        /* bottom */
102         {0.4, 0.4, 0.4},        /* right */
103         {1.0, 1.0, 1.0},        /* top */
104         {0.7, 0.7, 0.7},        /* front */
105         {0, 0, 0}, {0, 0, 0}, {0, 0, 0}
106 };
107 static uint16_t tileidx[] = { /* 3 +---------+ 2 */
108         4, 7, 3, 0,               /*   |\ 7   6 /|   */
109         5, 4, 0, 1,               /*   | +-----+ |   */
110         6, 5, 1, 2,               /*   | |     | |   */
111         7, 6, 2, 3,               /*   | +-----+ |   */
112         5, 6, 7, 4                /*   |/ 4   5 \|   */
113 };                            /* 0 +---------+ 1 */
114
115 void draw_tile(int col, int row, int xcells, int ycells)
116 {
117         int ncells = xcells > ycells ? xcells : ycells;
118         float cellsz = 2.0 / ncells;
119
120         glPushMatrix();
121         glTranslatef((col - xcells / 2.0 + 0.5) * cellsz, (row - ycells / 2.0 + 0.5) * cellsz, 0);
122         glScalef(cellsz * 0.5, cellsz * 0.5, cellsz * 0.5);
123
124         glEnableClientState(GL_VERTEX_ARRAY);
125         glEnableClientState(GL_COLOR_ARRAY);
126         glVertexPointer(3, GL_FLOAT, 0, tileverts);
127         glColorPointer(3, GL_FLOAT, 0, tilecol);
128         glDrawElements(GL_QUADS, 20, GL_UNSIGNED_SHORT, tileidx);
129         glDisableClientState(GL_VERTEX_ARRAY);
130         glDisableClientState(GL_COLOR_ARRAY);
131
132         glPopMatrix();
133 }
134
135 void set_view_matrix(int eye, float ipd)
136 {
137         const float offs[] = {0.5, 0.0, -0.5};
138
139         glMatrixMode(GL_MODELVIEW);
140         glLoadIdentity();
141         glTranslatef(offs[eye + 1] * ipd, 0, 0);
142 }
143
144 void set_proj_matrix(int eye, float ipd)
145 {
146         const float offs[] = {1.0, 0.0, -1.0};
147         float vpsz = 0.5;
148
149         float right = aspect * vpsz;
150         float top = vpsz;
151         float shift = offs[eye + 1] * ipd * 0.25; /* 0.25 -> 0.5 * znear */
152
153         glMatrixMode(GL_PROJECTION);
154         glLoadIdentity();
155         glFrustum(-right + shift, right + shift, -top, top, 0.5, 500.0);
156 }
157
158 void reshape(int x, int y)
159 {
160         win_width = x;
161         win_height = y;
162         aspect = (float)win_width / (float)win_height;
163         glViewport(0, 0, x, y);
164 }
165
166 void keyb(unsigned char key, int x, int y)
167 {
168         switch(key) {
169         case 27:
170                 exit(0);
171
172         case '1':
173         case '2':
174         case '3':
175                 view = key - '2';
176                 glutPostRedisplay();
177                 break;
178         }
179 }