]> icculus.org git repositories - divverent/nexuiz.git/blob - misc/spherefunc2skybox.c
make a sample mandelbrot function
[divverent/nexuiz.git] / misc / spherefunc2skybox.c
1 #include <stdio.h>
2 #include <err.h>
3 #include <stdint.h>
4 #include <math.h>
5 #include <string.h>
6
7 typedef void (*mapfunc_t) (double x_in, double y_in, double *x_out, double *y_out, double *z_out);
8 typedef void (*colorfunc_t) (double x, double y, double z, double *r, double *g, double *b);
9
10 void color_test(double x, double y, double z, double *r, double *g, double *b)
11 {
12         // put in a nice function here
13         *r = 0.5 + 0.5 * x;
14         *g = 0.5 + 0.5 * y;
15         *b = 0.5 + 0.5 * z;
16 }
17
18 #define MAXITER 4096
19 double mandelbrot(double zx, double zy, double cx, double cy)
20 {
21         double tmp;
22         int i;
23
24         for(i = 1; i < MAXITER; ++i)
25         {
26                 tmp = zx;
27                 zx = zx * zx - zy * zy + cx;
28                 zy = 2 * tmp * zy + cy;
29                 if(zx * zx + zy * zy > 4)
30                         break;
31         }
32
33         return ((i - 1.0) * MAXITER) / (i * (MAXITER - 1.0));
34         // i.e. 0 for i=1, 1 for i=maxiter
35 }
36
37 void color_mandelbrot(double x, double y, double z, double *r, double *g, double *b)
38 {
39         double iterations = mandelbrot(0, z*0.5, x - 1, y);
40         *r = pow(iterations, 100);
41         *g = pow(iterations,  25);
42         *b = pow(iterations,  10);
43 }
44
45 void map_back(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
46 {
47         *x_out = 2 * x_in - 1;
48         *y_out = +1;
49         *z_out = 1 - 2 * y_in;
50 }
51
52 void map_right(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
53 {
54         *x_out = +1;
55         *y_out = 1 - 2 * x_in;
56         *z_out = 1 - 2 * y_in;
57 }
58
59 void map_front(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
60 {
61         *x_out = 1 - 2 * x_in;
62         *y_out = -1;
63         *z_out = 1 - 2 * y_in;
64 }
65
66 void map_left(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
67 {
68         *x_out = -1;
69         *y_out = 2 * x_in - 1;
70         *z_out = 1 - 2 * y_in;
71 }
72
73 void map_up(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
74 {
75         *x_out = 2 * y_in - 1;
76         *y_out = 1 - 2 * x_in;
77         *z_out = +1;
78 }
79
80 void map_down(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
81 {
82         *x_out = 1 - 2 * y_in;
83         *y_out = 1 - 2 * x_in;
84         *z_out = -1;
85 }
86
87 #define WIDTH 512
88 #define HEIGHT 512
89
90 void writepic(colorfunc_t f, mapfunc_t m, const char *fn)
91 {
92         int x, y;
93         uint8_t tga[18];
94
95         FILE *file = fopen(fn, "wb");
96         if(!file)
97                 err(1, "fopen %s", fn);
98
99         memset(tga, 0, sizeof(tga));
100         tga[2] = 2;          // uncompressed type
101         tga[12] = (WIDTH >> 0) & 0xFF;
102         tga[13] = (WIDTH >> 8) & 0xFF;
103         tga[14] = (HEIGHT >> 0) & 0xFF;
104         tga[15] = (HEIGHT >> 8) & 0xFF;
105         tga[16] = 24;        // pixel size
106
107         fwrite(&tga, sizeof(tga), 1, file);
108         for(y = HEIGHT-1; y >= 0; --y)
109                 for(x = 0; x < WIDTH; ++x)
110                 {
111                         uint8_t rgb[3];
112                         double rr, gg, bb;
113                         double xx, yy;
114                         double xxx, yyy, zzz;
115                         double r;
116                         xx = (x + 0.5) / WIDTH;
117                         yy = (y + 0.5) / HEIGHT;
118                         m(xx, yy, &xxx, &yyy, &zzz);
119                         r = sqrt(xxx*xxx + yyy*yyy + zzz*zzz);
120                         xxx /= r;
121                         yyy /= r;
122                         zzz /= r;
123                         f(xxx, yyy, zzz, &rr, &gg, &bb);
124                         rgb[2] = floor(0.5 + rr * 255);
125                         rgb[1] = floor(0.5 + gg * 255);
126                         rgb[0] = floor(0.5 + bb * 255);
127                         fwrite(rgb, sizeof(rgb), 1, file);
128                 }
129         
130         fclose(file);
131 }
132
133 void map_all(const char *fn, colorfunc_t f)
134 {
135         char buf[1024];
136         snprintf(buf, sizeof(buf), "%s_bk.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_back, buf);
137         snprintf(buf, sizeof(buf), "%s_ft.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_front, buf);
138         snprintf(buf, sizeof(buf), "%s_rt.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_right, buf);
139         snprintf(buf, sizeof(buf), "%s_lf.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_left, buf);
140         snprintf(buf, sizeof(buf), "%s_up.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_up, buf);
141         snprintf(buf, sizeof(buf), "%s_dn.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_down, buf);
142 }
143
144 int main(int argc, char **argv)
145 {
146         if(argc != 2)
147                 errx(1, "file name argument missing");
148         map_all(argv[1], color_mandelbrot);
149         return 0;
150 }