DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
fractalnoise.c File Reference
#include "quakedef.h"
+ Include dependency graph for fractalnoise.c:

Go to the source code of this file.

Macros

#define n(x, y)
 
#define n(x, y)
 
#define NOISE_MASK   255
 
#define NOISE_SIZE   256
 

Functions

void fractalnoise (unsigned char *noise, int size, int startgrid)
 
void fractalnoisequick (unsigned char *noise, int size, int startgrid)
 
float noise4f (float x, float y, float z, float w)
 

Macro Definition Documentation

◆ n [1/2]

#define n ( x,
y )
Value:
noisebuf[((y)&size1)*size+((x)&size1)]
vector size
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651

Referenced by _Thread_CondBroadcast(), _Thread_CondSignal(), applytransform_inverted(), buf2file(), Cbuf_Execute_Deferred(), CD_f(), CL_Beam_AddQuad(), CL_Beams_SetupBuiltinTexture(), CL_PQRcon_f(), CL_Rcon_f(), CL_SelectTraceLine(), Collision_NewBrushFromPlanes(), Com_HexDumpToConsole(), COM_Init_Commands(), COM_ToLowerString(), COM_ToUpperString(), Con_CompleteCommandLine(), convex_builder_get_planes4f(), convex_builder_get_points3f(), Crypto_BuildChallengeAppend(), Crypto_LoadFile(), EntityFrame4_CL_ReadFrame(), EntityFrame4_WriteFrame(), EntityFrame5_CL_ReadFrame(), EntityFrame5_WriteFrame(), EntityFrame_AddFrame_Client(), EntityFrame_AddFrame_Server(), EntityFrame_FetchFrame(), EntityFrameCSQC_LostAllFrames(), EntityFrameCSQC_WriteFrame(), EntityState5_DeltaBits(), EntityState_DeltaBits(), file2buf(), file2lumps(), fractalnoise(), fractalnoisequick(), FS_SysCheckGameDir(), GetUntilNul(), hmac(), hz_bitstream_read_blocks_free(), Image_CopyAlphaFromBlueBGRA(), Image_FixTransparentPixels_f(), Image_HeightmapToNormalmap_BGRA(), IN_BestWeapon_f(), loadimagepixelsbgra(), Log_Start(), lumps2file(), M_DrawTextBox(), M_Menu_Quit_f(), M_ModList_Draw(), M_ServerList_Draw(), Math_crandomf(), Math_randomf(), Math_randomrangei(), mdfour(), mdfour_tail(), mdfour_update(), Mod_BuildTextureVectorsFromNormals(), Mod_Q2BSP_LoadBrushSides(), Mod_Q3BSP_LoadBrushes(), Mod_Q3BSP_LoadBrushSides(), Mod_Q3BSP_LoadBrushSides_IG(), Mod_Q3BSP_LoadEffects(), Mod_Q3BSP_LoadFaces(), Mod_Q3BSP_LoadLeafBrushes(), Mod_Q3BSP_LoadLeafFaces(), Mod_Q3BSP_LoadLeafs(), Mod_Q3BSP_LoadModels(), Mod_Q3BSP_LoadNodes(), Mod_Skeletal_AnimateVertices_Generic(), MR_Init(), NetConn_ClientParsePacket(), PolygonD_Clip(), PolygonD_Divide(), PolygonF_Clip(), PolygonF_Divide(), Protocol_EnumForNumber(), PRVM_ED_ParseEdict(), PRVM_EDICT_NUM_ERROR(), PRVM_ValueString(), PRVM_Watchpoint(), QW_CL_ParseModelList(), QW_CL_ParseSoundList(), R_BuildLightMap(), R_Mod_DrawAddWaterPlanes(), R_NewExplosion(), R_Shadow_CullFrustumSides(), R_Shadow_LoadLightsFile(), R_Shadow_LoadWorldLights(), R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(), R_Stain(), R_Water_AddWaterPlane(), RSurf_PrepareVerticesForBatch(), SCR_CaptureVideo_Avi_BeginVideo(), SCR_CaptureVideo_RIFF_Write16(), SCR_CaptureVideo_RIFF_Write32(), sha256(), SV_MaxPlayers_f(), Sys_FindExecutableName(), u8_bytelen(), u8_bytelen_colorcodes(), u8_strnlen(), u8_strnlen_colorcodes(), VID_BuildGammaTables(), VM_buf_cvarlist(), VM_CL_pointparticles(), and VM_SV_droptofloor().

◆ n [2/2]

#define n ( x,
y )
Value:
noise[((y)&size1)*size+((x)&size1)]
string noise
Definition progsdefs.qc:209

◆ NOISE_MASK

#define NOISE_MASK   255

Definition at line 127 of file fractalnoise.c.

Referenced by noise4f().

◆ NOISE_SIZE

#define NOISE_SIZE   256

Definition at line 126 of file fractalnoise.c.

Referenced by noise4f().

Function Documentation

◆ fractalnoise()

void fractalnoise ( unsigned char * noise,
int size,
int startgrid )

Definition at line 4 of file fractalnoise.c.

5{
6 int x, y, g, g2, amplitude, min, max, size1 = size - 1, sizepower, gridpower;
7 int *noisebuf;
8#define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
9
10 for (sizepower = 0;(1 << sizepower) < size;sizepower++);
11 if (size != (1 << sizepower))
12 {
13 Con_Printf("fractalnoise: size must be power of 2\n");
14 return;
15 }
16
17 for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++);
18 if (startgrid != (1 << gridpower))
19 {
20 Con_Printf("fractalnoise: grid must be power of 2\n");
21 return;
22 }
23
24 startgrid = bound(0, startgrid, size);
25
26 amplitude = 0xFFFF; // this gets halved before use
27 noisebuf = (int *)Mem_Alloc(tempmempool, size*size*sizeof(int));
28 memset(noisebuf, 0, size*size*sizeof(int));
29
30 for (g2 = startgrid;g2;g2 >>= 1)
31 {
32 // brownian motion (at every smaller level there is random behavior)
33 amplitude >>= 1;
34 for (y = 0;y < size;y += g2)
35 for (x = 0;x < size;x += g2)
36 n(x,y) += (rand()&amplitude);
37
38 g = g2 >> 1;
39 if (g)
40 {
41 // subdivide, diamond-square algorithm (really this has little to do with squares)
42 // diamond
43 for (y = 0;y < size;y += g2)
44 for (x = 0;x < size;x += g2)
45 n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
46 // square
47 for (y = 0;y < size;y += g2)
48 for (x = 0;x < size;x += g2)
49 {
50 n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
51 n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
52 }
53 }
54 }
55 // find range of noise values
56 min = max = 0;
57 for (y = 0;y < size;y++)
58 for (x = 0;x < size;x++)
59 {
60 if (n(x,y) < min) min = n(x,y);
61 if (n(x,y) > max) max = n(x,y);
62 }
63 max -= min;
64 max++;
65 // normalize noise and copy to output
66 for (y = 0;y < size;y++)
67 for (x = 0;x < size;x++)
68 *noise++ = (unsigned char) (((n(x,y) - min) * 256) / max);
69 Mem_Free(noisebuf);
70#undef n
71}
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define n(x, y)
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define bound(min, num, max)
Definition mathlib.h:34
dp_FragColor g
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92

References bound, Con_Printf(), g, max, Mem_Alloc, Mem_Free, min, n, noise, size, tempmempool, x, and y.

Referenced by r_explosion_start(), and R_InitParticleTexture().

◆ fractalnoisequick()

void fractalnoisequick ( unsigned char * noise,
int size,
int startgrid )

Definition at line 74 of file fractalnoise.c.

75{
76 int x, y, g, g2, amplitude, size1 = size - 1, sizepower, gridpower;
77#define n(x,y) noise[((y)&size1)*size+((x)&size1)]
78
79 for (sizepower = 0;(1 << sizepower) < size;sizepower++);
80 if (size != (1 << sizepower))
81 {
82 Con_Printf("fractalnoise: size must be power of 2\n");
83 return;
84 }
85
86 for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++);
87 if (startgrid != (1 << gridpower))
88 {
89 Con_Printf("fractalnoise: grid must be power of 2\n");
90 return;
91 }
92
93 startgrid = bound(0, startgrid, size);
94
95 amplitude = 255; // this gets halved before use
96 memset(noise, 0, size*size);
97
98 for (g2 = startgrid;g2;g2 >>= 1)
99 {
100 // brownian motion (at every smaller level there is random behavior)
101 amplitude >>= 1;
102 for (y = 0;y < size;y += g2)
103 for (x = 0;x < size;x += g2)
104 n(x,y) += (rand()&amplitude);
105
106 g = g2 >> 1;
107 if (g)
108 {
109 // subdivide, diamond-square algorithm (really this has little to do with squares)
110 // diamond
111 for (y = 0;y < size;y += g2)
112 for (x = 0;x < size;x += g2)
113 n(x+g,y+g) = (unsigned char) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x,y+g2) + (int) n(x+g2,y+g2)) >> 2);
114 // square
115 for (y = 0;y < size;y += g2)
116 for (x = 0;x < size;x += g2)
117 {
118 n(x+g,y) = (unsigned char) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x+g,y-g) + (int) n(x+g,y+g)) >> 2);
119 n(x,y+g) = (unsigned char) (((int) n(x,y) + (int) n(x,y+g2) + (int) n(x-g,y+g) + (int) n(x+g,y+g)) >> 2);
120 }
121 }
122 }
123#undef n
124}

References bound, Con_Printf(), g, n, noise, size, x, and y.

Referenced by R_NewExplosion().

◆ noise4f()

float noise4f ( float x,
float y,
float z,
float w )

Definition at line 128 of file fractalnoise.c.

129{
130 int i;
131 int index[4][2];
132 float frac[4][2];
133 float v[4];
134 static float noisetable[NOISE_SIZE];
135 static int r[NOISE_SIZE];
136 // LadyHavoc: this is inspired by code I saw in Quake3, however I think my
137 // version is much cleaner and substantially faster as well
138 //
139 // the following changes were made:
140 // 1. for the permutation indexing (r[] array in this code) I substituted
141 // the ^ operator (which never overflows) for the original addition and
142 // masking code, this should not have any effect on quality.
143 // 2. removed the outermost randomization array lookup.
144 // (it really wasn't necessary, it's fine if X indexes the array
145 // directly without permutation indexing)
146 // 3. reimplemented the blending using frac[] arrays rather than a macro.
147 // (the original macro read one parameter twice - not good)
148 // 4. cleaned up the code by using 4 nested loops to make it read nicer
149 // (but then I unrolled it completely for speed, it still looks nicer).
150 if (!noisetable[0])
151 {
152 // noisetable is a random-ish series of float values in +/- 1 range
153 for (i = 0;i < NOISE_SIZE;i++)
154 noisetable[i] = (rand() / (double)RAND_MAX) * 2 - 1;
155 // r is a remapping table to make each dimension of the index have different indexing behavior
156 for (i = 0;i < NOISE_SIZE;i++)
157 r[i] = (int)(rand() * (double)NOISE_SIZE / ((double)RAND_MAX + 1)) & NOISE_MASK;
158 // that & is only needed if RAND_MAX is > the range of double, which isn't the case on most platforms
159 }
160 frac[0][1] = x - floor(x);index[0][0] = ((int)floor(x)) & NOISE_MASK;
161 frac[1][1] = y - floor(y);index[1][0] = ((int)floor(y)) & NOISE_MASK;
162 frac[2][1] = z - floor(z);index[2][0] = ((int)floor(z)) & NOISE_MASK;
163 frac[3][1] = w - floor(w);index[3][0] = ((int)floor(w)) & NOISE_MASK;
164 for (i = 0;i < 4;i++)
165 frac[i][0] = 1 - frac[i][1];
166 for (i = 0;i < 4;i++)
167 index[i][1] = (index[i][0] < NOISE_SIZE - 1) ? (index[i][0] + 1) : 0;
168#if 1
169 // short version
170 v[0] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]]);
171 v[1] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]]);
172 v[2] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]]);
173 v[3] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]]);
174 return frac[3][0] * (frac[2][0] * v[0] + frac[2][1] * v[1]) + frac[3][1] * (frac[2][0] * v[2] + frac[2][1] * v[3]);
175#elif 1
176 // longer version
177 v[ 0] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]];
178 v[ 1] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]];
179 v[ 2] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]];
180 v[ 3] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]];
181 v[ 4] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]];
182 v[ 5] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]];
183 v[ 6] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]];
184 v[ 7] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]];
185 v[ 8] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]];
186 v[ 9] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]];
187 v[10] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]];
188 v[11] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]];
189 v[12] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]];
190 v[13] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]];
191 v[14] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]];
192 v[15] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]];
193 v[16] = frac[0][0] * v[ 0] + frac[0][1] * v[ 1];
194 v[17] = frac[0][0] * v[ 2] + frac[0][1] * v[ 3];
195 v[18] = frac[0][0] * v[ 4] + frac[0][1] * v[ 5];
196 v[19] = frac[0][0] * v[ 6] + frac[0][1] * v[ 7];
197 v[20] = frac[0][0] * v[ 8] + frac[0][1] * v[ 9];
198 v[21] = frac[0][0] * v[10] + frac[0][1] * v[11];
199 v[22] = frac[0][0] * v[12] + frac[0][1] * v[13];
200 v[23] = frac[0][0] * v[14] + frac[0][1] * v[15];
201 v[24] = frac[1][0] * v[16] + frac[1][1] * v[17];
202 v[25] = frac[1][0] * v[18] + frac[1][1] * v[19];
203 v[26] = frac[1][0] * v[20] + frac[1][1] * v[21];
204 v[27] = frac[1][0] * v[22] + frac[1][1] * v[23];
205 v[28] = frac[2][0] * v[24] + frac[2][1] * v[25];
206 v[29] = frac[2][0] * v[26] + frac[2][1] * v[27];
207 return frac[3][0] * v[28] + frac[3][1] * v[29];
208#else
209 // the algorithm...
210 for (l = 0;l < 2;l++)
211 {
212 for (k = 0;k < 2;k++)
213 {
214 for (j = 0;j < 2;j++)
215 {
216 for (i = 0;i < 2;i++)
217 v[l][k][j][i] = noisetable[r[r[r[index[l][3]] ^ index[k][2]] ^ index[j][1]] ^ index[i][0]];
218 v[l][k][j][2] = frac[0][0] * v[l][k][j][0] + frac[0][1] * v[l][k][j][1];
219 }
220 v[l][k][2][2] = frac[1][0] * v[l][k][0][2] + frac[1][1] * v[l][k][1][2];
221 }
222 v[l][2][2][2] = frac[2][0] * v[l][0][2][2] + frac[2][1] * v[l][1][2][2];
223 }
224 v[2][2][2][2] = frac[3][0] * v[0][2][2][2] + frac[3][1] * v[1][2][2][2];
225#endif
226}
#define NOISE_SIZE
#define NOISE_MASK
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLubyte GLubyte GLubyte z
Definition glquake.h:782
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
const GLdouble * v
Definition glquake.h:762
GLuint index
Definition glquake.h:629
float floor(float f)
int i
dp_FragColor r

References floor(), i, index, int(), NOISE_MASK, NOISE_SIZE, r, v, w, x, y, and z.

Referenced by RSurf_PrepareVerticesForBatch().