removed clang-format and clang_complete files from the repo
[dosdemo] / src / scr / raytrace.c
1 #include <stdio.h>
2 #include <math.h>
3 #include "demo.h"
4 #include "screen.h"
5 #include "gfxutil.h"
6 #include "util.h"
7 #include "cgmath/cgmath.h"
8 #include "rt.h"
9
10 static int init(void);
11 static void destroy(void);
12 static void start(long trans_time);
13 static void draw(void);
14
15 static struct screen scr = {
16         "raytrace",
17         init,
18         destroy,
19         start,
20         0,
21         draw
22 };
23
24 struct tile {
25         int x, y;
26         uint16_t *fbptr;
27 };
28
29 #define TILESZ          16
30 #define NUM_TILES       ((320 / TILESZ) * (240 / TILESZ))
31
32 static cgm_vec3 raydir[240][320];
33 static struct tile tiles[NUM_TILES];
34 static struct rtscene scn;
35
36 struct screen *raytrace_screen(void)
37 {
38         return &scr;
39 }
40
41 static int init(void)
42 {
43         int i, j, k;
44         float z = 1.0f / tan(cgm_deg_to_rad(25.0f));
45         struct tile *tptr = tiles;
46
47         for(i=0; i<240; i++) {
48                 cgm_vec3 *vptr = raydir[i];
49                 float y = 1.0f - (float)i / 120.0f;
50                 for(j=0; j<320; j++) {
51                         vptr->x = ((float)j / 160.0f - 1.0f) * 1.333333f;
52                         vptr->y = y;
53                         vptr->z = z;
54                         vptr++;
55
56                         if(((j & (TILESZ-1)) | (i & (TILESZ-1))) == 0) {
57                                 tptr->x = j;
58                                 tptr->y = i;
59                                 tptr->fbptr = fb_pixels + i * 320 + j;
60                                 tptr++;
61                         }
62                 }
63         }
64
65         rt_init(&scn);
66
67         rt_color(1, 0, 0);
68         rt_specular(0.8f, 0.8f, 0.8f);
69         rt_shininess(30.0f);
70         rt_add_sphere(&scn, 0, 0, 0, 1);        /* x,y,z, rad */
71
72         rt_color(0.4, 0.4, 0.4);
73         rt_specular(0, 0, 0);
74         rt_shininess(1);
75         rt_add_plane(&scn, 0, 1, 0, -1);                /* nx,ny,nz, dist */
76
77         rt_color(1, 1, 1);
78         rt_add_light(&scn, -8, 15, -10);
79         return 0;
80 }
81
82 static void destroy(void)
83 {
84         rt_destroy(&scn);
85 }
86
87 static void start(long start_time)
88 {
89 }
90
91 static uint16_t INLINE rend_pixel(int x, int y)
92 {
93         int r, g, b;
94         cgm_ray ray;
95         cgm_vec3 col;
96
97         ray.dir = raydir[y][x];
98         cgm_vcons(&ray.origin, 0, 0, -5);
99
100         if(ray_trace(&ray, &scn, 0, &col)) {
101                 r = cround64(col.x * 255.0f);
102                 g = cround64(col.y * 255.0f);
103                 b = cround64(col.z * 255.0f);
104                 if(r > 255) r = 255;
105                 if(g > 255) g = 255;
106                 if(b > 255) b = 255;
107                 return PACK_RGB16(r, g, b);
108         }
109         return 0;
110 }
111
112 #define CMPMASK         0xe79c
113 static void rend_tile(uint16_t *fbptr, int x0, int y0, int tsz, int valid)
114 {
115         uint16_t *cptr[4];
116         uint16_t cpix[4], tmp;
117         uint32_t pp0, pp1, pp2, pp3, *fb32;
118         int i, x1, y1, offs;
119
120         fb32 = (uint32_t*)fbptr;
121
122         if(tsz <= 2) {
123                 switch(valid) {
124                 case 0:
125                         fbptr[1] = fbptr[320] = fbptr[321] = *fbptr;
126                         break;
127                 case 1:
128                         fbptr[0] = fbptr[320] = fbptr[321] = fbptr[1];
129                         break;
130                 case 2:
131                         fbptr[0] = fbptr[1] = fbptr[321] = fbptr[320];
132                         break;
133                 case 3:
134                         fbptr[0] = fbptr[1] = fbptr[320] = fbptr[321];
135                         break;
136                 default:
137                         printf("valid = %d\n", valid);
138                         fbptr[0] = fbptr[1] = fbptr[320] = fbptr[321] = 0xff00;
139                 }
140                 return;
141         }
142
143         offs = tsz - 1;
144         x1 = x0 + offs;
145         y1 = y0 + offs;
146
147         cptr[0] = fbptr;
148         cptr[1] = fbptr + tsz - 1;
149         cptr[2] = fbptr + (offs << 8) + (offs << 6);
150         cptr[3] = cptr[2] + tsz - 1;
151
152         cpix[0] = valid == 0 ? *cptr[0] : rend_pixel(x0, y0);
153         cpix[1] = valid == 1 ? *cptr[1] : rend_pixel(x1, y0);
154         cpix[2] = valid == 2 ? *cptr[2] : rend_pixel(x0, y1);
155         cpix[3] = valid == 3 ? *cptr[3] : rend_pixel(x1, y1);
156
157         tmp = cpix[0] & CMPMASK;
158         if((cpix[1] & CMPMASK) != tmp) goto subdiv;
159         if((cpix[2] & CMPMASK) != tmp) goto subdiv;
160         if((cpix[3] & CMPMASK) != tmp) goto subdiv;
161
162         pp0 = cpix[0] | ((uint32_t)cpix[0] << 16);
163         pp1 = cpix[1] | ((uint32_t)cpix[1] << 16);
164         pp2 = cpix[2] | ((uint32_t)cpix[2] << 16);
165         pp3 = cpix[3] | ((uint32_t)cpix[3] << 16);
166
167         switch(tsz) {
168         case 2:
169 #ifdef SUBDBG
170                 pp0 = 0x18ff;
171 #endif
172                 fb32[0] = fb32[160] = pp0;
173                 break;
174         case 4:
175 #ifdef SUBDBG
176                 pp0 = pp1 = pp2 = pp3 = 0x03800380;
177 #endif
178                 fb32[0] = fb32[160] = pp0;
179                 fb32[1] = fb32[161] = pp1;
180                 fb32[320] = fb32[480] = pp2;
181                 fb32[321] = fb32[481] = pp3;
182                 break;
183         case 8:
184 #ifdef SUBDBG
185                 pp1 = pp0 = pp2 = pp3 = 0xe00fe00f;
186 #endif
187                 fb32[0] = fb32[1] = pp0; fb32[2] = fb32[3] = pp1;
188                 fb32[160] = fb32[161] = pp0; fb32[162] = fb32[163] = pp1;
189                 fb32[320] = fb32[321] = pp0; fb32[322] = fb32[323] = pp1;
190                 fb32[480] = fb32[481] = pp0; fb32[482] = fb32[483] = pp1;
191                 fb32[640] = fb32[641] = pp2; fb32[642] = fb32[643] = pp3;
192                 fb32[800] = fb32[801] = pp2; fb32[802] = fb32[803] = pp3;
193                 fb32[960] = fb32[961] = pp2; fb32[962] = fb32[963] = pp3;
194                 fb32[1120] = fb32[1121] = pp2; fb32[1122] = fb32[1123] = pp3;
195                 break;
196
197         case 16:
198 #ifdef SUBDBG
199                 pp0 = 0xff00ff00;
200 #endif
201                 for(i=0; i<4; i++) {
202                         memset16(fbptr, pp0, 16); fbptr += 320;
203                         memset16(fbptr, pp0, 16); fbptr += 320;
204                         memset16(fbptr, pp0, 16); fbptr += 320;
205                         memset16(fbptr, pp0, 16); fbptr += 320;
206                 }
207                 break;
208         }
209         return;
210
211 subdiv:
212         *cptr[0] = cpix[0];
213         *cptr[1] = cpix[1];
214         *cptr[2] = cpix[2];
215         *cptr[3] = cpix[3];
216
217         tsz >>= 1;
218         rend_tile(fbptr, x0, y0, tsz, 0);
219         rend_tile(fbptr + tsz, x0 + tsz, y0, tsz, 1);
220         fbptr += (tsz << 8) + (tsz << 6);
221         y0 += tsz;
222         rend_tile(fbptr, x0, y0, tsz, 2);
223         rend_tile(fbptr + tsz, x0 + tsz, y0, tsz, 3);
224 }
225
226 static void draw(void)
227 {
228         int i, j, xbound, ybound;
229         uint16_t *fbptr;
230         struct tile *tile;
231
232         tile = tiles;
233         for(i=0; i<NUM_TILES; i++) {
234                 rend_tile(tile->fbptr, tile->x, tile->y, TILESZ, -1);
235                 tile++;
236         }
237
238         swap_buffers(0);
239 }