85b31282382b0d7bdfa0e51682fe021b469b741b
[dosdemo] / src / polytest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include "screen.h"
6 #include "demo.h"
7 #include "3dgfx.h"
8 #include "gfxutil.h"
9 #include "polyfill.h"   /* just for struct pimage */
10 #include "cfgopt.h"
11 #include "mesh.h"
12
13 static int init(void);
14 static void destroy(void);
15 static void start(long trans_time);
16 static void draw(void);
17 static void draw_lowres_raster(void);
18 static int gen_texture(struct pimage *img, int xsz, int ysz);
19
20 static struct screen scr = {
21         "polytest",
22         init,
23         destroy,
24         start, 0,
25         draw
26 };
27
28 static float cam_theta, cam_phi = 25;
29 static float cam_dist = 3;
30 static struct g3d_mesh cube, torus;
31
32 static struct pimage tex;
33
34 #define LOWRES_SCALE    10
35 static uint16_t *lowres_pixels;
36 static int lowres_width, lowres_height;
37
38 struct screen *polytest_screen(void)
39 {
40         return &scr;
41 }
42
43 static int init(void)
44 {
45         int i;
46
47         gen_cube_mesh(&cube, 1.0, 0);
48         gen_torus_mesh(&torus, 1.0, 0.25, 24, 12);
49         /* scale texcoords */
50         for(i=0; i<torus.vcount; i++) {
51                 torus.varr[i].u *= 4.0;
52                 torus.varr[i].v *= 2.0;
53         }
54
55         gen_texture(&tex, 128, 128);
56
57 #ifdef DEBUG_POLYFILL
58         lowres_width = fb_width / LOWRES_SCALE;
59         lowres_height = fb_height / LOWRES_SCALE;
60         lowres_pixels = malloc(lowres_width * lowres_height * 2);
61         scr.draw = draw_debug;
62 #endif
63
64         return 0;
65 }
66
67 static void destroy(void)
68 {
69         free(lowres_pixels);
70         free(cube.varr);
71         free(torus.varr);
72         free(torus.iarr);
73 }
74
75 static void start(long trans_time)
76 {
77         g3d_matrix_mode(G3D_PROJECTION);
78         g3d_load_identity();
79         g3d_perspective(50.0, 1.3333333, 0.5, 100.0);
80
81         g3d_enable(G3D_CULL_FACE);
82         g3d_enable(G3D_LIGHTING);
83         g3d_enable(G3D_LIGHT0);
84
85         g3d_polygon_mode(G3D_TEX_GOURAUD);
86 }
87
88 static void update(void)
89 {
90         mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
91 }
92
93
94 static void draw(void)
95 {
96         update();
97
98         memset(fb_pixels, 0, fb_width * fb_height * 2);
99
100         g3d_matrix_mode(G3D_MODELVIEW);
101         g3d_load_identity();
102         g3d_translate(0, 0, -cam_dist);
103         if(opt.sball) {
104                 g3d_mult_matrix(sball_matrix);
105         } else {
106                 g3d_rotate(cam_phi, 1, 0, 0);
107                 g3d_rotate(cam_theta, 0, 1, 0);
108         }
109
110         g3d_light_pos(0, -10, 10, 20);
111
112         zsort_mesh(&torus);
113
114         g3d_mtl_diffuse(0.4, 0.7, 1.0);
115         g3d_set_texture(tex.width, tex.height, tex.pixels);
116
117         draw_mesh(&torus);
118
119         /*draw_mesh(&cube);*/
120         swap_buffers(fb_pixels);
121 }
122
123 static void draw_debug(void)
124 {
125         update();
126
127         memset(lowres_pixels, 0, lowres_width * lowres_height * 2);
128
129         g3d_matrix_mode(G3D_MODELVIEW);
130         g3d_load_identity();
131         g3d_translate(0, 0, -cam_dist);
132         g3d_rotate(cam_phi, 1, 0, 0);
133         g3d_rotate(cam_theta, 0, 1, 0);
134
135         g3d_framebuffer(lowres_width, lowres_height, lowres_pixels);
136         /*zsort(&torus);*/
137         draw_mesh(&cube);
138
139         draw_lowres_raster();
140
141
142         g3d_framebuffer(fb_width, fb_height, fb_pixels);
143
144         g3d_polygon_mode(G3D_WIRE);
145         draw_mesh(&cube);
146         g3d_polygon_mode(G3D_FLAT);
147
148         swap_buffers(fb_pixels);
149 }
150
151
152 static void draw_huge_pixel(uint16_t *dest, int dest_width, uint16_t color)
153 {
154         int i, j;
155         uint16_t grid_color = PACK_RGB16(127, 127, 127);
156
157         for(i=0; i<LOWRES_SCALE; i++) {
158                 for(j=0; j<LOWRES_SCALE; j++) {
159                         dest[j] = i == 0 || j == 0 ? grid_color : color;
160                 }
161                 dest += dest_width;
162         }
163 }
164
165 static void draw_lowres_raster(void)
166 {
167         int i, j;
168         uint16_t *sptr = lowres_pixels;
169         uint16_t *dptr = fb_pixels;
170
171         for(i=0; i<lowres_height; i++) {
172                 for(j=0; j<lowres_width; j++) {
173                         draw_huge_pixel(dptr, fb_width, *sptr++);
174                         dptr += LOWRES_SCALE;
175                 }
176                 dptr += fb_width * LOWRES_SCALE - fb_width;
177         }
178 }
179
180 static int gen_texture(struct pimage *img, int xsz, int ysz)
181 {
182         int i, j;
183         uint16_t *pix;
184
185         if(!(img->pixels = malloc(xsz * ysz * sizeof *pix))) {
186                 return -1;
187         }
188         pix = img->pixels;
189
190         for(i=0; i<ysz; i++) {
191                 for(j=0; j<xsz; j++) {
192                         int val = i ^ j;
193
194                         *pix++ = PACK_RGB16(val, val, val);
195                 }
196         }
197
198         img->width = xsz;
199         img->height = ysz;
200         return 0;
201 }