foo
[dosdemo] / src / scr / infcubes.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include "demo.h"
6 #include "3dgfx.h"
7 #include "screen.h"
8 #include "cfgopt.h"
9 #include "polyfill.h"
10 #include "imago2.h"
11 #include "gfxutil.h"
12 #include "mesh.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 int gen_phong_tex(struct pimage *img, int xsz, int ysz, float sexp,
19                 float offx, float offy, int dr, int dg, int db, int sr, int sg, int sb);
20
21 static struct screen scr = {
22         "infcubes",
23         init,
24         destroy,
25         start, 0,
26         draw
27 };
28
29 static float cam_theta = -29, cam_phi = 35;
30 static float cam_dist = 6;
31 static struct pimage tex_inner, tex_outer;
32 static struct g3d_mesh mesh_cube, mesh_cube2;
33
34 struct screen *infcubes_screen(void)
35 {
36         return &scr;
37 }
38
39 #define PHONG_TEX_SZ    128
40
41 static int init(void)
42 {
43         static const float scalemat[16] = {-6, 0, 0, 0, 0, -6, 0, 0, 0, 0, -6, 0, 0, 0, 0, 1};
44         /*
45         if(!(tex_inner.pixels = img_load_pixels("data/crate.jpg", &tex_inner.width,
46                                         &tex_inner.height, IMG_FMT_RGB24))) {
47                 fprintf(stderr, "infcubes: failed to load crate texture\n");
48                 return -1;
49         }
50         convimg_rgb24_rgb16(tex_inner.pixels, (unsigned char*)tex_inner.pixels, tex_inner.width, tex_inner.height);
51         */
52         gen_phong_tex(&tex_inner, PHONG_TEX_SZ, PHONG_TEX_SZ, 5.0f, 0, 0, 10, 50, 92, 192, 192, 192);
53
54         if(!(tex_outer.pixels = img_load_pixels("data/refmap1.jpg", &tex_outer.width,
55                                         &tex_outer.height, IMG_FMT_RGB24))) {
56                 fprintf(stderr, "infcubes: failed to load outer texture\n");
57                 return -1;
58         }
59         convimg_rgb24_rgb16(tex_outer.pixels, (unsigned char*)tex_outer.pixels, tex_outer.width, tex_outer.height);
60         /*gen_phong_tex(&tex_outer, PHONG_TEX_SZ, PHONG_TEX_SZ, 5.0f, 50, 50, 50, 255, 255, 255);*/
61
62         /*
63         if(gen_cube_mesh(&mesh_cube, 1.0f, 3) == -1) {
64                 return -1;
65         }
66         */
67         if(load_mesh(&mesh_cube, "data/bevelbox.obj") == -1) {
68                 return -1;
69         }
70         if(copy_mesh(&mesh_cube2, &mesh_cube) == -1) {
71                 return -1;
72         }
73         apply_mesh_xform(&mesh_cube2, scalemat);
74         normalize_mesh_normals(&mesh_cube2);
75         return 0;
76 }
77
78 static void destroy(void)
79 {
80         img_free_pixels(tex_inner.pixels);
81 }
82
83 static void start(long trans_time)
84 {
85         g3d_matrix_mode(G3D_PROJECTION);
86         g3d_load_identity();
87         g3d_perspective(70.0, 1.3333333, 0.5, 100.0);
88
89         g3d_enable(G3D_CULL_FACE);
90         g3d_disable(G3D_LIGHTING);
91         g3d_enable(G3D_LIGHT0);
92 }
93
94 static void update(void)
95 {
96         mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
97 }
98
99 static void draw(void)
100 {
101         float t = (float)time_msec / 16.0f;
102         update();
103
104         g3d_matrix_mode(G3D_MODELVIEW);
105         g3d_load_identity();
106         g3d_translate(0, 0, -cam_dist);
107         g3d_rotate(cam_phi, 1, 0, 0);
108         g3d_rotate(cam_theta, 0, 1, 0);
109         if(opt.sball) {
110                 g3d_mult_matrix(sball_matrix);
111         }
112
113         /*memset(fb_pixels, 0, fb_width * fb_height * 2);*/
114
115         g3d_polygon_mode(G3D_FLAT);
116         g3d_enable(G3D_TEXTURE_2D);
117         g3d_enable(G3D_TEXTURE_GEN);
118
119         g3d_push_matrix();
120         g3d_rotate(t, 1, 0, 0);
121         g3d_rotate(t, 0, 1, 0);
122         g3d_set_texture(tex_outer.width, tex_outer.height, tex_outer.pixels);
123         draw_mesh(&mesh_cube2);
124         g3d_pop_matrix();
125
126         g3d_set_texture(tex_inner.width, tex_inner.height, tex_inner.pixels);
127         draw_mesh(&mesh_cube);
128         g3d_disable(G3D_TEXTURE_GEN);
129
130         swap_buffers(fb_pixels);
131 }
132
133 static int gen_phong_tex(struct pimage *img, int xsz, int ysz, float sexp,
134                 float offx, float offy, int dr, int dg, int db, int sr, int sg, int sb)
135 {
136         int i, j;
137         float u, v, du, dv;
138         uint16_t *pix;
139
140         if(!(img->pixels = malloc(xsz * ysz * sizeof *pix))) {
141                 return -1;
142         }
143         pix = img->pixels;
144
145         du = 2.0f / (float)(xsz - 1);
146         dv = 2.0f / (float)(ysz - 1);
147
148         v = -1.0f - offy;
149         for(i=0; i<ysz; i++) {
150                 u = -1.0f - offx;
151                 for(j=0; j<xsz; j++) {
152                         float d = sqrt(u * u + v * v);
153                         float val = pow(cos(d * M_PI / 2.0f), sexp);
154                         int ival = abs(val * 255.0f);
155
156                         int r = dr + ival * sr / 256;
157                         int g = dg + ival * sg / 256;
158                         int b = db + ival * sb / 256;
159
160                         if(r > 255) r = 255;
161                         if(g > 255) g = 255;
162                         if(b > 255) b = 255;
163
164                         *pix++ = PACK_RGB16(r, g, b);
165
166                         u += du;
167                 }
168                 v += dv;
169         }
170
171         img->width = xsz;
172         img->height = ysz;
173         return 0;
174 }