0f44854001262a995cd65c664d285ead66974806
[dosrtxon] / src / parts / rtxonoff.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "demo.h"
5 #include "3dgfx.h"
6 #include "screen.h"
7 #include "cfgopt.h"
8 #include "polyfill.h"
9 #include "imago2.h"
10 #include "gfxutil.h"
11 #include "mesh.h"
12 #include "bsptree.h"
13
14 static int init(void);
15 static void destroy(void);
16 static void start(long trans_time);
17 static void draw(void);
18 static void keypress(int key);
19
20 static struct screen scr = {
21         "rtxonoff",
22         init,
23         destroy,
24         start, 0,
25         draw,
26         keypress
27 };
28
29 static float cam_theta = -29, cam_phi = 35;
30 static float cam_dist = 10;
31
32 static int use_bsp = 1;
33
34 static const char *car_fname[2] = {"data/ldiablo.obj", 0};
35 static const char *cartex_fname[2] = {"data/ldiablo.png", 0};
36 static struct g3d_mesh mesh_car[2];
37 static struct pimage tex_car[2];
38 static struct bsptree bsp_car[2];
39
40 struct screen *rtxonoff_screen(void)
41 {
42         return &scr;
43 }
44
45 static int init(void)
46 {
47         int i;
48
49         for(i=0; i<sizeof car_fname / sizeof car_fname[0]; i++) {
50                 if(cartex_fname[i]) {
51                         if(!(tex_car[i].pixels = img_load_pixels(cartex_fname[i],
52                                                         &tex_car[i].width, &tex_car[i].height, IMG_FMT_RGB24))) {
53                                 fprintf(stderr, "failed to load car texture: %s\n", cartex_fname[i]);
54                                 return -1;
55                         }
56                         convimg_rgb24_rgb16(tex_car[i].pixels, (unsigned char*)tex_car[i].pixels,
57                                         tex_car[i].width, tex_car[i].height);
58                 }
59                 if(car_fname[i]) {
60                         if(load_mesh(&mesh_car[i], car_fname[i]) == -1) {
61                                 return -1;
62                         }
63
64                         init_bsp(&bsp_car[i]);
65                         if(bsp_add_mesh(&bsp_car[i], &mesh_car[i]) == -1) {
66                                 fprintf(stderr, "failed to construct BSP tree %d\n", i);
67                                 return -1;
68                         }
69                         bsp_build(&bsp_car[i]);
70                 }
71         }
72         return 0;
73 }
74
75 static void destroy(void)
76 {
77         int i;
78
79         for(i=0; i<2; i++) {
80                 free(mesh_car[i].varr);
81                 free(mesh_car[i].iarr);
82                 destroy_bsp(&bsp_car[i]);
83         }
84 }
85
86 static void start(long trans_time)
87 {
88         g3d_matrix_mode(G3D_PROJECTION);
89         g3d_load_identity();
90         g3d_perspective(60.0, 1.3333333, 0.5, 100.0);
91
92         g3d_enable(G3D_CULL_FACE);
93         g3d_enable(G3D_LIGHTING);
94         g3d_enable(G3D_LIGHT0);
95 }
96
97 static void update(void)
98 {
99         mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
100 }
101
102 static void draw(void)
103 {
104         int i;
105         static float vdir[3];
106         float t = (float)time_msec / 16.0f;
107
108         update();
109
110         memset(fb_pixels, 0, fb_width * fb_height * 2);
111
112         g3d_matrix_mode(G3D_MODELVIEW);
113         g3d_load_identity();
114         g3d_translate(0, 0, -cam_dist);
115         g3d_rotate(cam_phi, 1, 0, 0);
116         g3d_rotate(cam_theta, 0, 1, 0);
117
118         if(use_bsp) {
119                 const float *mat = g3d_get_matrix(G3D_MODELVIEW, 0);
120                 /* transform (0, 0, -1) with transpose(mat3x3) */
121                 vdir[0] = -mat[2];
122                 vdir[1] = -mat[6];
123                 vdir[2] = -mat[10];
124         }
125
126         g3d_polygon_mode(G3D_TEX_GOURAUD);
127
128         for(i=0; i<sizeof mesh_car / sizeof mesh_car[0]; i++) {
129                 if(mesh_car[i].varr) {
130                         g3d_set_texture(tex_car[i].width, tex_car[i].height, tex_car[i].pixels);
131
132                         if(use_bsp) {
133                                 draw_bsp(&bsp_car[i], vdir[0], vdir[1], vdir[2]);
134                         } else {
135                                 zsort_mesh(&mesh_car[i]);
136                                 draw_mesh(&mesh_car[i]);
137                         }
138                 }
139         }
140
141         swap_buffers(fb_pixels);
142 }
143
144 static void keypress(int key)
145 {
146         switch(key) {
147         case 'b':
148                 use_bsp = !use_bsp;
149                 printf("drawing with %s\n", use_bsp ? "BSP tree" : "z-sorting");
150                 break;
151         }
152 }