gldesign_noise.c

Go to the documentation of this file.
00001 /* file GLDESIGN_NOISE.C   */
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 }

Generated on Sun Apr 27 14:20:11 2014 for OpenFX by  doxygen 1.5.6