00001
00002
00003 #include <windows.h>
00004 #include <gl\gl.h>
00005 #include <gl\glu.h>
00006 #include <math.h>
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009 #include "..\gl2.h"
00010
00011 static void init3DNoiseTexture(int texSize, GLubyte* texPtr);
00012 static void make3DNoiseTexture();
00013
00014 static int Noise3DTexSize = 64;
00015 static GLubyte* Noise3DTexPtr;
00016
00017 #define MAXB 0x100
00018 #define N 0x1000
00019 #define NP 12
00020 #define NM 0xfff
00021
00022 #define s_curve(t) ( t * t * (3. - 2. * t) )
00023 #define lerp(t, a, b) ( a + t * (b - a) )
00024 #define setup(i, b0, b1, r0, r1)\
00025 t = vec[i] + N;\
00026 b0 = ((int)t) & BM;\
00027 b1 = (b0+1) & BM;\
00028 r0 = t - (int)t;\
00029 r1 = r0 - 1.;
00030 #define at2(rx, ry) ( rx * q[0] + ry * q[1] )
00031 #define at3(rx, ry, rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
00032
00033 static void initNoise();
00034
00035 static int p[MAXB + MAXB + 2];
00036 static double g3[MAXB + MAXB + 2][3];
00037 static double g2[MAXB + MAXB + 2][2];
00038 static double g1[MAXB + MAXB + 2];
00039
00040 static int start;
00041 static int B;
00042 static int BM;
00043
00044 void CreateNoise3D(void){
00045 make3DNoiseTexture();
00046 init3DNoiseTexture(Noise3DTexSize, Noise3DTexPtr);
00047 }
00048
00049 static void SetNoiseFrequency(int frequency)
00050 {
00051 start = 1;
00052 B = frequency;
00053 BM = B-1;
00054 }
00055
00056 static double noise1(double arg){
00057 int bx0, bx1;
00058 double rx0, rx1, sx, t, u, v, vec[1];
00059
00060 vec[0] = arg;
00061 if (start)
00062 {
00063 start = 0;
00064 initNoise();
00065 }
00066
00067 setup(0, bx0, bx1, rx0, rx1);
00068
00069 sx = s_curve(rx0);
00070 u = rx0 * g1[p[bx0]];
00071 v = rx1 * g1[p[bx1]];
00072
00073 return(lerp(sx, u, v));
00074 }
00075
00076 static double noise2(double vec[2]){
00077 int bx0, bx1, by0, by1, b00, b10, b01, b11;
00078 double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
00079 int i, j;
00080
00081 if (start)
00082 {
00083 start = 0;
00084 initNoise();
00085 }
00086
00087 setup(0, bx0, bx1, rx0, rx1);
00088 setup(1, by0, by1, ry0, ry1);
00089
00090 i = p[bx0];
00091 j = p[bx1];
00092
00093 b00 = p[i + by0];
00094 b10 = p[j + by0];
00095 b01 = p[i + by1];
00096 b11 = p[j + by1];
00097
00098 sx = s_curve(rx0);
00099 sy = s_curve(ry0);
00100
00101 q = g2[b00]; u = at2(rx0, ry0);
00102 q = g2[b10]; v = at2(rx1, ry0);
00103 a = lerp(sx, u, v);
00104
00105 q = g2[b01]; u = at2(rx0, ry1);
00106 q = g2[b11]; v = at2(rx1, ry1);
00107 b = lerp(sx, u, v);
00108
00109 return lerp(sy, a, b);
00110 }
00111
00112 static double noise3(double vec[3]){
00113 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
00114 double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
00115 int i, j;
00116
00117 if (start)
00118 {
00119 start = 0;
00120 initNoise();
00121 }
00122
00123 setup(0, bx0, bx1, rx0, rx1);
00124 setup(1, by0, by1, ry0, ry1);
00125 setup(2, bz0, bz1, rz0, rz1);
00126
00127 i = p[bx0];
00128 j = p[bx1];
00129
00130 b00 = p[i + by0];
00131 b10 = p[j + by0];
00132 b01 = p[i + by1];
00133 b11 = p[j + by1];
00134
00135 t = s_curve(rx0);
00136 sy = s_curve(ry0);
00137 sz = s_curve(rz0);
00138
00139 q = g3[b00 + bz0]; u = at3(rx0, ry0, rz0);
00140 q = g3[b10 + bz0]; v = at3(rx1, ry0, rz0);
00141 a = lerp(t, u, v);
00142
00143 q = g3[b01 + bz0]; u = at3(rx0, ry1, rz0);
00144 q = g3[b11 + bz0]; v = at3(rx1, ry1, rz0);
00145 b = lerp(t, u, v);
00146
00147 c = lerp(sy, a, b);
00148
00149 q = g3[b00 + bz1]; u = at3(rx0, ry0, rz1);
00150 q = g3[b10 + bz1]; v = at3(rx1, ry0, rz1);
00151 a = lerp(t, u, v);
00152
00153 q = g3[b01 + bz1]; u = at3(rx0, ry1, rz1);
00154 q = g3[b11 + bz1]; v = at3(rx1, ry1, rz1);
00155 b = lerp(t, u, v);
00156
00157 d = lerp(sy, a, b);
00158
00159 return lerp(sz, c, d);
00160 }
00161
00162 static void normalize2(double v[2]){
00163 double s;
00164
00165 s = sqrt(v[0] * v[0] + v[1] * v[1]);
00166 v[0] = v[0] / s;
00167 v[1] = v[1] / s;
00168 }
00169
00170 static void normalize3(double v[3]){
00171 double s;
00172
00173 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00174 v[0] = v[0] / s;
00175 v[1] = v[1] / s;
00176 v[2] = v[2] / s;
00177 }
00178
00179 static void initNoise(){
00180 int i, j, k;
00181
00182 srand(30757);
00183 for (i = 0; i < B; i++)
00184 {
00185 p[i] = i;
00186 g1[i] = (double)((rand() % (B + B)) - B) / B;
00187
00188 for (j = 0; j < 2; j++)
00189 g2[i][j] = (double)((rand() % (B + B)) - B) / B;
00190 normalize2(g2[i]);
00191
00192 for (j = 0; j < 3; j++)
00193 g3[i][j] = (double)((rand() % (B + B)) - B) / B;
00194 normalize3(g3[i]);
00195 }
00196
00197 while (--i)
00198 {
00199 k = p[i];
00200 p[i] = p[j = rand() % B];
00201 p[j] = k;
00202 }
00203
00204 for (i = 0; i < B + 2; i++)
00205 {
00206 p[B + i] = p[i];
00207 g1[B + i] = g1[i];
00208 for (j = 0; j < 2; j++)
00209 g2[B + i][j] = g2[i][j];
00210 for (j = 0; j < 3; j++)
00211 g3[B + i][j] = g3[i][j];
00212 }
00213 }
00214
00215
00216 static double PerlinNoise1D(double x,double alpha,double beta,int n){
00217 int i;
00218 double val,sum = 0;
00219 double p,scale = 1;
00220
00221 p = x;
00222 for (i = 0; i < n; i++)
00223 {
00224 val = noise1(p);
00225 sum += val / scale;
00226 scale *= alpha;
00227 p *= beta;
00228 }
00229 return(sum);
00230 }
00231
00232 static double PerlinNoise2D(double x, double y, double alpha, double beta, int n){
00233 int i;
00234 double val, sum = 0;
00235 double p[2], scale = 1;
00236
00237 p[0] = x;
00238 p[1] = y;
00239 for (i = 0; i < n; i++)
00240 {
00241 val = noise2(p);
00242 sum += val / scale;
00243 scale *= alpha;
00244 p[0] *= beta;
00245 p[1] *= beta;
00246 }
00247 return(sum);
00248 }
00249
00250 static double PerlinNoise3D(double x, double y, double z, double alpha, double beta, int n){
00251 int i;
00252 double val,sum = 0;
00253 double p[3],scale = 1;
00254
00255 p[0] = x;
00256 p[1] = y;
00257 p[2] = z;
00258 for (i = 0; i < n; i++)
00259 {
00260 val = noise3(p);
00261 sum += val / scale;
00262 scale *= alpha;
00263 p[0] *= beta;
00264 p[1] *= beta;
00265 p[2] *= beta;
00266 }
00267 return(sum);
00268 }
00269
00270 static void make3DNoiseTexture(){
00271 int f, i, j, k, inc;
00272 int startFrequency = 4;
00273 int numOctaves = 4;
00274 double ni[3];
00275 double inci, incj, inck;
00276 int frequency = startFrequency;
00277 GLubyte* ptr;
00278 double amp = 0.5;
00279
00280 Noise3DTexPtr = (GLubyte*) malloc(Noise3DTexSize * Noise3DTexSize * Noise3DTexSize * 4);
00281 for (f = 0, inc = 0; f < numOctaves; ++f, frequency *= 2, ++inc, amp *= 0.5)
00282 {
00283 SetNoiseFrequency(frequency);
00284 ptr = Noise3DTexPtr;
00285 ni[0] = ni[1] = ni[2] = 0;
00286
00287 inci = 1.0 / (Noise3DTexSize / frequency);
00288 for (i = 0; i < Noise3DTexSize; ++i, ni[0] += inci)
00289 {
00290 incj = 1.0 / (Noise3DTexSize / frequency);
00291 for (j = 0; j < Noise3DTexSize; ++j, ni[1] += incj)
00292 {
00293 inck = 1.0 / (Noise3DTexSize / frequency);
00294 for (k = 0; k < Noise3DTexSize; ++k, ni[2] += inck, ptr += 4)
00295 *(ptr + inc) = (GLubyte) (((noise3(ni) + 1.0) * amp) * 128.0);
00296 }
00297 }
00298 }
00299 }
00300
00301 static void init3DNoiseTexture(int texSize, GLubyte* texPtr){
00302 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00303 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00304 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
00305 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00306 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00307 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, texSize, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texPtr);
00308 free(texPtr);
00309 }