X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=misc%2Ftools%2Fspherefunc2skybox.c;h=201cefb955c5446652816170cb0f56b83f355df1;hb=611be7dbdb01ee7206e1e52dba0c54596c76a92f;hp=3e3e7a5ad007bed931add27f01fcdee1233521d3;hpb=e5832bf2ecac60a672a29c85cd8dec341a215e1c;p=xonotic%2Fxonotic.git diff --git a/misc/tools/spherefunc2skybox.c b/misc/tools/spherefunc2skybox.c index 3e3e7a5a..201cefb9 100644 --- a/misc/tools/spherefunc2skybox.c +++ b/misc/tools/spherefunc2skybox.c @@ -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; }