goat3dgfx

annotate src/texgen.cc @ 13:25bf39105c82

lalal
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 27 Nov 2013 08:08:59 +0200
parents
children 7d6b667821cf
rev   line source
nuclear@0 1 #include "texgen.h"
nuclear@0 2
nuclear@0 3 static void intcolor(const Vector4 &color, int *icol);
nuclear@0 4
nuclear@0 5 Image *texgen_solid(int xsz, int ysz, const Vector4 &color)
nuclear@0 6 {
nuclear@0 7 Image *img = new Image;
nuclear@0 8 if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
nuclear@0 9 delete img;
nuclear@0 10 return 0;
nuclear@0 11 }
nuclear@0 12
nuclear@0 13 int col[4];
nuclear@0 14 intcolor(color, col);
nuclear@0 15
nuclear@0 16 unsigned char *pix = (unsigned char*)img->get_pixels();
nuclear@0 17 for(int i=0; i<xsz * ysz; i++) {
nuclear@0 18 *pix++ = col[0];
nuclear@0 19 *pix++ = col[1];
nuclear@0 20 *pix++ = col[2];
nuclear@0 21 *pix++ = col[3];
nuclear@0 22 }
nuclear@0 23 return img;
nuclear@0 24 }
nuclear@0 25
nuclear@0 26 Image *texgen_chess(int xsz, int ysz, int usub, int vsub, const Vector4 &col1, const Vector4 &col2)
nuclear@0 27 {
nuclear@0 28 Image *img = new Image;
nuclear@0 29 if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
nuclear@0 30 delete img;
nuclear@0 31 return 0;
nuclear@0 32 }
nuclear@0 33
nuclear@0 34 int c1[4], c2[4];
nuclear@0 35 intcolor(col1, c1);
nuclear@0 36 intcolor(col2, c2);
nuclear@0 37
nuclear@0 38 int udiv = xsz / usub;
nuclear@0 39 int vdiv = ysz / vsub;
nuclear@0 40
nuclear@0 41 unsigned char *pix = (unsigned char*)img->get_pixels();
nuclear@0 42 for(int i=0; i<ysz; i++) {
nuclear@0 43 for(int j=0; j<xsz; j++) {
nuclear@0 44 if(((i / vdiv) & 1) == ((j / udiv) & 1)) {
nuclear@0 45 *pix++ = c1[0];
nuclear@0 46 *pix++ = c1[1];
nuclear@0 47 *pix++ = c1[2];
nuclear@0 48 *pix++ = c1[3];
nuclear@0 49 } else {
nuclear@0 50 *pix++ = c2[0];
nuclear@0 51 *pix++ = c2[1];
nuclear@0 52 *pix++ = c2[2];
nuclear@0 53 *pix++ = c2[3];
nuclear@0 54 }
nuclear@0 55 }
nuclear@0 56 }
nuclear@0 57 return img;
nuclear@0 58 }
nuclear@0 59
nuclear@0 60
nuclear@0 61 Image *texgen(int xsz, int ysz, float usize, float vsize, Vector4 (*eval)(float, float, void*), void *cls)
nuclear@0 62 {
nuclear@0 63 Image *img = new Image;
nuclear@0 64 if(!img->create(xsz, ysz, Image::FMT_RGBA)) {
nuclear@0 65 delete img;
nuclear@0 66 return 0;
nuclear@0 67 }
nuclear@0 68
nuclear@0 69 unsigned char *pix = (unsigned char*)img->get_pixels();
nuclear@0 70 for(int i=0; i<ysz; i++) {
nuclear@0 71 for(int j=0; j<xsz; j++) {
nuclear@0 72 float x = usize * (float)j / (float)xsz;
nuclear@0 73 float y = vsize * (float)i / (float)ysz;
nuclear@0 74
nuclear@0 75 Vector4 color = eval(x, y, cls);
nuclear@0 76
nuclear@0 77 int icol[4];
nuclear@0 78 intcolor(color, icol);
nuclear@0 79
nuclear@0 80 *pix++ = icol[0];
nuclear@0 81 *pix++ = icol[1];
nuclear@0 82 *pix++ = icol[2];
nuclear@0 83 *pix++ = icol[3];
nuclear@0 84 }
nuclear@0 85 }
nuclear@0 86 return img;
nuclear@0 87 }
nuclear@0 88
nuclear@0 89
nuclear@0 90 struct NoiseArg {
nuclear@0 91 int octaves;
nuclear@0 92 Vector4 col1, col2;
nuclear@0 93 };
nuclear@0 94
nuclear@0 95 static Vector4 fbm_eval(float x, float y, void *cls)
nuclear@0 96 {
nuclear@0 97 NoiseArg *arg = (NoiseArg*)cls;
nuclear@0 98
nuclear@0 99 float noise = fbm2(x, y, arg->octaves) * 0.5 + 0.5;
nuclear@0 100 return lerp(arg->col1, arg->col2, noise);
nuclear@0 101 }
nuclear@0 102
nuclear@0 103 static Vector4 fbm_abs_eval(float x, float y, void *cls)
nuclear@0 104 {
nuclear@0 105 NoiseArg *arg = (NoiseArg*)cls;
nuclear@0 106
nuclear@0 107 float noise = turbulence2(x, y, arg->octaves) * 0.5 + 0.5;
nuclear@0 108 return lerp(arg->col1, arg->col2, noise);
nuclear@0 109 }
nuclear@0 110
nuclear@0 111
nuclear@0 112 Image *texgen_fbm(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2)
nuclear@0 113 {
nuclear@0 114 NoiseArg arg = {octaves, col1, col2};
nuclear@0 115 if(arg.octaves < 1) {
nuclear@0 116 arg.octaves = 1;
nuclear@0 117 }
nuclear@0 118
nuclear@0 119 return texgen(xsz, ysz, usize, vsize, fbm_eval, &arg);
nuclear@0 120 }
nuclear@0 121
nuclear@0 122 Image *texgen_fbm_abs(int xsz, int ysz, float usize, float vsize, int octaves, const Vector4 &col1, const Vector4 &col2)
nuclear@0 123 {
nuclear@0 124 NoiseArg arg = {octaves, col1, col2};
nuclear@0 125 if(arg.octaves < 1) {
nuclear@0 126 arg.octaves = 1;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 return texgen(xsz, ysz, usize, vsize, fbm_abs_eval, &arg);
nuclear@0 130 }
nuclear@0 131
nuclear@0 132 static inline void intcolor(const Vector4 &color, int *icol)
nuclear@0 133 {
nuclear@0 134 for(int i=0; i<4; i++) {
nuclear@0 135 icol[i] = std::max(std::min((int)(color[i] * 255.0), 255), 0);
nuclear@0 136 }
nuclear@0 137 }