]> git.xonotic.org Git - xonotic/xonotic.git/blobdiff - misc/tools/spherefunc2skybox.c
Merge branch 'master' of git://git.xonotic.org/xonotic/xonotic
[xonotic/xonotic.git] / misc / tools / spherefunc2skybox.c
index 3e3e7a5ad007bed931add27f01fcdee1233521d3..201cefb955c5446652816170cb0f56b83f355df1 100644 (file)
@@ -141,6 +141,110 @@ void color_mandelbrot(double x, double y, double z, double *r, double *g, double
        *b = pow(iterations, color_mandelbrot_parms[12]);
 }
 
+struct
+{
+       int n;
+       double darkness;
+       double power;
+       double density;
+       int g;
+       double gpower;
+       double gfactor;
+       double gdpower;
+}
+color_starfield_parms;
+typedef struct
+{
+       double x, y, z, e;
+       double R, G, B, A;
+} starfield_t;
+starfield_t *starfield = NULL;
+int starfield_cmp(const void *a_, const void *b_)
+{
+       const starfield_t *a = a_;
+       const starfield_t *b = b_;
+       if(a->z < b->z)
+               return -1;
+       if(a->z > b->z)
+               return +1;
+       return 0;
+}
+void color_starfield(double x, double y, double z, double *r, double *g, double *b)
+{
+       int i, j, k;
+       double f, mindot, d;
+
+       if(!starfield)
+       {
+               fprintf(stderr, "Initializing starfield...\n");
+               starfield = malloc(sizeof(*starfield) * color_starfield_parms.n);
+               for(i = 0; i < color_starfield_parms.n; ++i)
+               {
+                       double r;
+                       do
+                       {
+                               starfield[i].x = rnd() * 2 - 1;
+                               starfield[i].y = rnd() * 2 - 1;
+                               starfield[i].z = rnd() * 2 - 1;
+                               r = starfield[i].x * starfield[i].x
+                                 + starfield[i].y * starfield[i].y
+                                 + starfield[i].z * starfield[i].z;
+                       }
+                       while(r > 1);
+
+                       starfield[i].R = rnd();
+                       starfield[i].G = rnd();
+                       starfield[i].B = rnd();
+                       f = starfield[i].R * 0.299 + starfield[i].G * 0.587 + starfield[i].B * 0.114;
+                       starfield[i].R /= f;
+                       starfield[i].G /= f;
+                       starfield[i].B /= f;
+                       starfield[i].A = rnd();
+                       starfield[i].e = color_starfield_parms.density * pow(rnd(), -color_starfield_parms.power);
+               }
+               fprintf(stderr, "Gravitating starfield...\n");
+               for(k = 0; k < color_starfield_parms.g; ++k)
+               {
+                       i = rand() % color_starfield_parms.n;
+                       j = rand() % color_starfield_parms.n;
+                       f = pow(rnd(), color_starfield_parms.gpower);
+                       f = f * color_starfield_parms.gfactor;
+                       d = pow(starfield[j].x - starfield[i].x, 2)
+                         + pow(starfield[j].y - starfield[i].y, 2)
+                         + pow(starfield[j].z - starfield[i].z, 2);
+                       f *= pow(1 / (1 + d), color_starfield_parms.gdpower);
+                       starfield[i].x += f * (starfield[j].x - starfield[i].x);
+                       starfield[i].y += f * (starfield[j].y - starfield[i].y);
+                       starfield[i].z += f * (starfield[j].z - starfield[i].z);
+                       double r = starfield[i].x * starfield[i].x + starfield[i].y * starfield[i].y + starfield[i].z * starfield[i].z;
+                       r = sqrt(r);
+                       starfield[i].x /= r;
+                       starfield[i].y /= r;
+                       starfield[i].z /= r;
+               }
+               fprintf(stderr, "Sorting starfield...\n");
+               qsort(starfield, sizeof(*starfield), color_starfield_parms.n, starfield_cmp);
+               fprintf(stderr, "Done.\n");
+       }
+
+       *r = *g = *b = 0;
+       mindot = pow(1/256.0, 1.0/color_starfield_parms.density);
+       for(i = 0; i < color_starfield_parms.n; ++i)
+       {
+               double dot = x * starfield[i].x + y * starfield[i].y + z * starfield[i].z;
+               if(dot <= mindot)
+                       continue;
+               double f = pow(dot, starfield[i].e) * starfield[i].A;
+               *r += starfield[i].R * f;
+               *g += starfield[i].G * f;
+               *b += starfield[i].B * f;
+       }
+       // make fit in 0..1
+       *r = *r / (color_starfield_parms.darkness + *r);
+       *g = *g / (color_starfield_parms.darkness + *g);
+       *b = *b / (color_starfield_parms.darkness + *b);
+}
+
 void map_back(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
 {
        *x_out = 2 * x_in - 1;
@@ -187,6 +291,7 @@ void writepic(colorfunc_t f, mapfunc_t m, const char *fn, int width, int height)
 {
        int x, y;
        uint8_t tga[18];
+       int percent, p;
 
        FILE *file = fopen(fn, "wb");
        if(!file)
@@ -201,7 +306,9 @@ void writepic(colorfunc_t f, mapfunc_t m, const char *fn, int width, int height)
        tga[16] = 24;        // pixel size
 
        fwrite(&tga, sizeof(tga), 1, file);
+       percent = 0;
        for(y = height-1; y >= 0; --y)
+       {
                for(x = 0; x < width; ++x)
                {
                        uint8_t rgb[3];
@@ -222,6 +329,14 @@ void writepic(colorfunc_t f, mapfunc_t m, const char *fn, int width, int height)
                        rgb[0] = floor(rnd() + bb * 255);
                        fwrite(rgb, sizeof(rgb), 1, file);
                }
+               p = (100 * (height - y)) / height;
+               if(p != percent)
+               {
+                       percent = p;
+                       fprintf(stderr, "%d%%\r", percent);
+               }
+       }
+       fprintf(stderr, "\n");
        
        fclose(file);
 }
@@ -229,11 +344,17 @@ void writepic(colorfunc_t f, mapfunc_t m, const char *fn, int width, int height)
 void map_all(const char *fn, colorfunc_t f, int width, int height)
 {
        char buf[1024];
+       fprintf(stderr, "%s_bk.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_bk.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_back, buf, width, height);
+       fprintf(stderr, "%s_ft.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_ft.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_front, buf, width, height);
+       fprintf(stderr, "%s_rt.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_rt.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_right, buf, width, height);
+       fprintf(stderr, "%s_lf.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_lf.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_left, buf, width, height);
+       fprintf(stderr, "%s_up.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_up.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_up, buf, width, height);
+       fprintf(stderr, "%s_dn.tga\n", fn);
        snprintf(buf, sizeof(buf), "%s_dn.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_down, buf, width, height);
 }
 
@@ -260,10 +381,22 @@ int main(int argc, char **argv)
                color_mandelbrot_parms[11] = argc<=15 ?   0.5   : atof(argv[15]);
                color_mandelbrot_parms[12] = argc<=16 ?   0.2   : atof(argv[16]);
        }
+       else if(!strcmp(argv[3], "starfield"))
+       {
+               f = color_starfield;
+               color_starfield_parms.n = argc<= 4 ? 8192 : atoi(argv[4]);
+               color_starfield_parms.darkness = argc<= 5 ? 0.4 : atof(argv[5]);
+               color_starfield_parms.power = argc<= 6 ? 2.5 : atof(argv[6]);
+               color_starfield_parms.density = argc<= 7 ? 60000 : atof(argv[7]);
+               color_starfield_parms.g = argc<= 8 ? 10000000 : atoi(argv[8]);
+               color_starfield_parms.gpower = argc<= 9 ? 3 : atoi(argv[9]);
+               color_starfield_parms.gfactor = argc<= 10 ? 0.9 : atof(argv[10]);
+               color_starfield_parms.gdpower = argc<= 11 ? 15 : atof(argv[11]);
+       }
        else
        {
                f = color_test;
        }
-       map_all(argv[1], color_mandelbrot, res, res);
+       map_all(argv[1], f, res, res);
        return 0;
 }