13 void draw_field(int xcells, int ycells);
14 void draw_tile(int col, int row, int xcells, int ycells);
15 void set_view_matrix(int eye, float ipd);
16 void set_proj_matrix(int eye, float ipd);
17 void reshape(int x, int y);
18 void keyb(unsigned char key, int x, int y);
19 void save_tiles(void);
20 int save_tile(const char *fname, unsigned char *pixptr, int xsz, int ysz, int pitch);
22 static int win_width = 320;
23 static int win_height = 640;
24 static int grid_cols = 10;
25 static int grid_rows = 20;
28 static float eye_dist = 1.3;
30 int main(int argc, char **argv)
32 glutInit(&argc, argv);
33 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
34 glutInitWindowSize(win_width, win_height);
35 glutCreateWindow("tilegen");
37 glutDisplayFunc(disp);
38 glutReshapeFunc(reshape);
39 glutKeyboardFunc(keyb);
41 glClearColor(0.05, 0.05, 0.05, 1);
42 glEnable(GL_CULL_FACE);
43 glShadeModel(GL_FLAT);
51 glClear(GL_COLOR_BUFFER_BIT);
53 glColorMask(1, 0, 0, 0);
55 set_proj_matrix(-1, eye_dist);
56 set_view_matrix(-1, eye_dist);
57 glTranslatef(0, 0, -1);
59 draw_field(grid_cols, grid_rows);
61 glColorMask(0, 1, 1, 0);
63 set_proj_matrix(1, eye_dist);
64 set_view_matrix(1, eye_dist);
65 glTranslatef(0, 0, -1);
67 draw_field(grid_cols, grid_rows);
69 glColorMask(1, 1, 1, 1);
72 assert(glGetError() == GL_NO_ERROR);
75 void draw_field(int xcells, int ycells)
79 for(i=0; i<ycells; i++) {
80 for(j=0; j<xcells; j++) {
81 draw_tile(j, i, xcells, ycells);
89 static struct vec3 tileverts[] = {
90 {-1, -1, 0}, {1, -1, 0}, {1, 1, 0}, {-1, 1, 0},
91 {-1 + DX, -1 + DX, DZ}, {1 - DX, -1 + DX, DZ},
92 {1 - DX, 1 - DX, DZ}, {-1 + DX, 1 - DX, DZ}
94 static struct vec3 tilecol[] = {
95 {0.5, 0.5, 0.5}, /* left */
96 {0.2, 0.2, 0.2}, /* bottom */
97 {0.5, 0.5, 0.5}, /* right */
98 {0.8, 0.8, 0.8}, /* top */
99 {0.65, 0.65, 0.65}, /* front */
100 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}
102 static uint16_t tileidx[] = { /* 3 +---------+ 2 */
103 4, 7, 3, 0, /* |\ 7 6 /| */
104 5, 4, 0, 1, /* | +-----+ | */
105 6, 5, 1, 2, /* | | | | */
106 7, 6, 2, 3, /* | +-----+ | */
107 5, 6, 7, 4 /* |/ 4 5 \| */
108 }; /* 0 +---------+ 1 */
110 void draw_tile(int col, int row, int xcells, int ycells)
112 int ncells = xcells > ycells ? xcells : ycells;
113 float cellsz = 2.0 / ncells;
116 glTranslatef((col - xcells / 2.0 + 0.5) * cellsz, (row - ycells / 2.0 + 0.5) * cellsz, 0);
117 glScalef(cellsz * 0.5, cellsz * 0.5, cellsz * 0.5);
119 glEnableClientState(GL_VERTEX_ARRAY);
120 glEnableClientState(GL_COLOR_ARRAY);
121 glVertexPointer(3, GL_FLOAT, 0, tileverts);
122 glColorPointer(3, GL_FLOAT, 0, tilecol);
123 glDrawElements(GL_QUADS, 20, GL_UNSIGNED_SHORT, tileidx);
124 glDisableClientState(GL_VERTEX_ARRAY);
125 glDisableClientState(GL_COLOR_ARRAY);
130 void set_view_matrix(int eye, float ipd)
132 const float offs[] = {0.5, 0.0, -0.5};
134 glMatrixMode(GL_MODELVIEW);
136 glTranslatef(offs[eye + 1] * ipd, 0, 0);
139 void set_proj_matrix(int eye, float ipd)
141 const float offs[] = {1.0, 0.0, -1.0};
144 float right = aspect * vpsz;
146 float shift = offs[eye + 1] * ipd * 0.25; /* 0.25 -> 0.5 * znear */
148 glMatrixMode(GL_PROJECTION);
150 glFrustum(-right + shift, right + shift, -top, top, 0.5, 500.0);
153 void reshape(int x, int y)
157 aspect = (float)win_width / (float)win_height;
158 glViewport(0, 0, x, y);
161 void keyb(unsigned char key, int x, int y)
179 if(win_height > 160) {
180 glutReshapeWindow(win_width / 4, win_height / 4);
182 glutReshapeWindow(win_width * 4, win_height * 4);
190 void save_tiles(void)
192 unsigned char *pixels, *tilepix;
193 int i, j, tilesz = win_height / grid_rows;
196 if(!(pixels = malloc(win_width * win_height * 3))) {
197 fprintf(stderr, "failed to allocate pixel buffer\n");
200 glReadPixels(0, 0, win_width, win_height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
202 for(i=0; i<grid_rows; i++) {
203 for(j=0; j<grid_cols; j++) {
204 tilepix = pixels + (i * win_width + j) * tilesz * 3;
206 sprintf(fname, "tile-%02d%02d.ppm", j, i);
207 save_tile(fname, tilepix, tilesz, tilesz, win_width * 3);
212 int save_tile(const char *fname, unsigned char *pixptr, int xsz, int ysz, int pitch)
217 printf("saving tile: %s\n", fname);
219 if(!(fp = fopen(fname, "wb"))) {
220 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
224 pixptr += ysz * pitch;
225 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
226 for(i=0; i<ysz; i++) {
228 for(j=0; j<xsz; j++) {
229 int r = pixptr[j * 3];
230 int g = pixptr[j * 3 + 1];
231 int b = pixptr[j * 3 + 2];