17 static int init(void);
18 static void destroy(void);
19 static void start(long trans_time);
20 static void draw(void);
21 static void keypress(int key);
23 static struct screen scr = {
32 static float cam_theta = -29, cam_phi = 35;
33 static float cam_dist = 10;
35 static const char *car_fname[2] = {"data/ldiablo.obj", 0};
36 static const char *cartex_fname[2] = {"data/ldiablo.png", 0};
37 static struct g3d_mesh mesh_car[2];
38 static struct pimage tex_car[2];
40 #define BGCOL_SIZE 128
41 #define BGOFFS_SIZE 1024
42 static uint16_t bgcol[BGCOL_SIZE];
43 static uint16_t bgcol_mir[BGCOL_SIZE];
44 static int bgoffs[BGOFFS_SIZE];
45 static const int colzen[] = {98, 64, 192};
46 static const int colhor[] = {128, 80, 64};
47 static const int colmnt[] = {16, 9, 24};
48 static uint16_t mountcol, mountcol_mir;
50 static int shading = G3D_TEX_GOURAUD;
51 static int do_clip = 1;
54 struct screen *rtxonoff_screen(void)
64 mountcol = PACK_RGB16(colmnt[0], colmnt[1], colmnt[2]);
65 mountcol_mir = PACK_RGB16(colmnt[0] / 2, colmnt[1] / 2, colmnt[2] / 2);
67 for(i=0; i<BGCOL_SIZE; i++) {
68 int32_t t = (i << 8) / BGCOL_SIZE;
69 col[0] = colhor[0] + ((colzen[0] - colhor[0]) * t >> 8);
70 col[1] = colhor[1] + ((colzen[1] - colhor[1]) * t >> 8);
71 col[2] = colhor[2] + ((colzen[2] - colhor[2]) * t >> 8);
72 bgcol[i] = PACK_RGB16(col[0], col[1], col[2]);
73 bgcol_mir[i] = PACK_RGB16(col[0] / 2, col[1] / 2, col[2] / 2);
76 for(i=0; i<BGOFFS_SIZE; i++) {
77 float x = 8.0f * (float)i / (float)BGOFFS_SIZE;
79 bgoffs[i] = pfbm1(x, 8.0f, 5) * 32 + 16;
82 for(i=0; i<sizeof car_fname / sizeof car_fname[0]; i++) {
84 if(!(tex_car[i].pixels = img_load_pixels(cartex_fname[i],
85 &tex_car[i].width, &tex_car[i].height, IMG_FMT_RGB24))) {
86 fprintf(stderr, "failed to load car texture: %s\n", cartex_fname[i]);
89 convimg_rgb24_rgb16(tex_car[i].pixels, (unsigned char*)tex_car[i].pixels,
90 tex_car[i].width, tex_car[i].height);
93 if(load_mesh(&mesh_car[i], car_fname[i]) == -1) {
101 static void destroy(void)
106 free(mesh_car[i].varr);
107 free(mesh_car[i].iarr);
112 static void start(long trans_time)
114 g3d_matrix_mode(G3D_PROJECTION);
116 g3d_perspective(VFOV, 1.3333333, 0.5, 100.0);
118 g3d_enable(G3D_CULL_FACE);
119 g3d_enable(G3D_LIGHTING);
120 g3d_enable(G3D_LIGHT0);
123 static void update(void)
125 mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
127 cam_theta = fmod(cam_theta, 360.0f);
128 if(cam_theta < 0) cam_theta += 360.0f;
130 if(cam_phi < 0) cam_phi = 0;
133 static void backdrop(void)
135 static const int colzen[] = {98, 64, 192};
136 static const int colhor[] = {128, 80, 64};
137 int i, j, hory, start[3], end[3], col[3];
138 uint16_t *fbptr, pcol;
139 int cidx, offs = -10;
142 startidx = cround64(cam_theta * (float)BGOFFS_SIZE) / 360;
144 hory = (fb_height - 2 * fb_height * cround64(cam_phi) / VFOV) / 2;
145 if(hory > fb_height) hory = fb_height;
148 fbptr = fb_pixels + (hory - 1) * fb_width;
151 while(fbptr >= fb_pixels) {
152 pcol = bgcol[cidx < 0 ? 0 : (cidx >= BGCOL_SIZE ? BGCOL_SIZE - 1 : cidx)];
153 for(j=0; j<fb_width; j++) {
154 if(cidx < bgoffs[(startidx + j) & (BGOFFS_SIZE - 1)]) {
169 fbptr = fb_pixels + hory * fb_width;
170 for(i=hory; i<fb_height; i++) {
171 pcol = bgcol_mir[cidx < 0 ? 0 : (cidx >= BGCOL_SIZE ? BGCOL_SIZE - 1 : cidx)];
172 for(j=0; j<fb_width; j++) {
173 if(cidx < bgoffs[(startidx + j) & (BGOFFS_SIZE - 1)]) {
174 *fbptr++ = mountcol_mir;
183 static void draw(void)
187 g3d_framebuffer_addr(fb_pixels);
191 g3d_matrix_mode(G3D_MODELVIEW);
193 g3d_translate(0, 0, -cam_dist);
194 g3d_rotate(cam_phi, 1, 0, 0);
195 g3d_rotate(cam_theta, 0, 1, 0);
197 g3d_polygon_mode(shading);
198 g3d_set_texture(tex_car[0].width, tex_car[0].height, tex_car[0].pixels);
199 zsort_mesh(&mesh_car[0]);
201 g3d_light_color(0, 0.3, 0.3, 0.3);
204 g3d_front_face(G3D_CW);
205 draw_mesh(&mesh_car[0]);
206 g3d_front_face(G3D_CCW);
209 g3d_light_color(0, 1, 1, 1);
210 draw_mesh(&mesh_car[0]);
212 draw_mouse_pointer(fb_pixels);
214 swap_buffers(fb_pixels);
217 static void keypress(int key)
219 static int lighting = 1;
220 static int clipping = 1;
224 shading = (shading + 1) % 5;
225 g3d_polygon_mode(shading);
229 lighting = !lighting;
231 g3d_enable(G3D_LIGHTING);
233 g3d_disable(G3D_LIGHTING);
238 clipping = !clipping;
240 g3d_enable(G3D_CLIP_FRUSTUM);
242 g3d_disable(G3D_CLIP_FRUSTUM);