summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Generating/Noise3DGenerator.cpp46
-rw-r--r--source/LinearUpscale.h64
-rw-r--r--source/Noise.cpp2
3 files changed, 80 insertions, 32 deletions
diff --git a/source/Generating/Noise3DGenerator.cpp b/source/Generating/Noise3DGenerator.cpp
index 42a0d70d9..79138aa9f 100644
--- a/source/Generating/Noise3DGenerator.cpp
+++ b/source/Generating/Noise3DGenerator.cpp
@@ -61,14 +61,36 @@ void Debug3DNoise(NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_Size
f2.Write(buf, a_SizeX);
} // for y
} // if (XZ file open)
- //*/
-
}
+void Debug2DNoise(NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase)
+{
+ const int BUF_SIZE = 512;
+ ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed
+
+ cFile f1;
+ if (f1.Open(Printf("%s (%d).grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite))
+ {
+ for (int y = 0; y < a_SizeY; y++)
+ {
+ int idx = y * a_SizeX;
+ unsigned char buf[BUF_SIZE];
+ for (int x = 0; x < a_SizeX; x++)
+ {
+ buf[x] = (unsigned char)(std::min(255, std::max(0, (int)(128 + 32 * a_Noise[idx++]))));
+ }
+ f1.Write(buf, a_SizeX);
+ } // for y
+ } // if (file open)
+}
+
+
+
+
/*
// Perform an automatic test of upscaling upon program start (use breakpoints to debug):
@@ -78,6 +100,7 @@ public:
Test(void)
{
DoTest1();
+ DoTest2();
}
@@ -88,11 +111,26 @@ public:
{
In[i] = (float)(i % 5);
}
- Debug3DNoise(In, 3, 3, 3, "Upscale in");
+ Debug3DNoise(In, 3, 3, 3, "Upscale3D in");
float Out[17 * 33 * 35];
LinearUpscale3DArray(In, 3, 3, 3, Out, 8, 16, 17);
- Debug3DNoise(Out, 17, 33, 35, "Upscale test");
+ Debug3DNoise(Out, 17, 33, 35, "Upscale3D test");
+ }
+
+
+ void DoTest2(void)
+ {
+ float In[3 * 3];
+ for (int i = 0; i < ARRAYCOUNT(In); i++)
+ {
+ In[i] = (float)(i % 5);
+ }
+ Debug2DNoise(In, 3, 3, "Upscale2D in");
+ float Out[17 * 33];
+ LinearUpscale2DArray(In, 3, 3, Out, 8, 16);
+ Debug2DNoise(Out, 17, 33, "Upscale2D test");
}
+
} gTest;
//*/
diff --git a/source/LinearUpscale.h b/source/LinearUpscale.h
index 60aa005bd..9f40b5d81 100644
--- a/source/LinearUpscale.h
+++ b/source/LinearUpscale.h
@@ -88,49 +88,59 @@ template<typename TYPE> void LinearUpscale2DArray(
int a_UpscaleX, int a_UpscaleY ///< Upscale factor for each direction
)
{
+ // For optimization reasons, we're storing the upscaling ratios in a fixed-size arrays of these sizes
+ // Feel free to enlarge them if needed, but keep in mind that they're on the stack
+ const int MAX_UPSCALE_X = 128;
+ const int MAX_UPSCALE_Y = 128;
+
ASSERT(a_Src != NULL);
ASSERT(a_Dst != NULL);
ASSERT(a_SrcSizeX > 0);
ASSERT(a_SrcSizeY > 0);
ASSERT(a_UpscaleX > 0);
ASSERT(a_UpscaleY > 0);
+ ASSERT(a_UpscaleX <= MAX_UPSCALE_X);
+ ASSERT(a_UpscaleY <= MAX_UPSCALE_Y);
- // First interpolate columns (same-Y) where the anchor points are:
- int idx = 0;
- for (int y = 0; y < a_SrcSizeY; y++)
+ // Pre-calculate the upscaling ratios:
+ TYPE RatioX[MAX_UPSCALE_X];
+ TYPE RatioY[MAX_UPSCALE_Y];
+ for (int x = 0; x <= a_UpscaleX; x++)
+ {
+ RatioX[x] = (TYPE)x / a_UpscaleX;
+ }
+ for (int y = 0; y <= a_UpscaleY; y++)
+ {
+ RatioY[y] = (TYPE)y / a_UpscaleY;
+ }
+
+ // Interpolate each XY cell:
+ int DstSizeX = (a_SrcSizeX - 1) * a_UpscaleX + 1;
+ int DstSizeY = (a_SrcSizeY - 1) * a_UpscaleY + 1;
+ for (int y = 0; y < (a_SrcSizeY - 1); y++)
{
int DstY = y * a_UpscaleY;
- for (int x = 0; x < a_SrcSizeX; x++)
+ int idx = y * a_SrcSizeX;
+ for (int x = 0; x < (a_SrcSizeX - 1); x++, idx++)
{
int DstX = x * a_UpscaleX;
- TYPE StartValue = a_Src[idx]; // [x, y]
- TYPE EndValue = a_Src[idx + a_SrcSizeX]; // [x, y + 1]
- TYPE Diff = EndValue - StartValue;
+ TYPE LoXLoY = a_Src[idx];
+ TYPE LoXHiY = a_Src[idx + a_SrcSizeX];
+ TYPE HiXLoY = a_Src[idx + 1];
+ TYPE HiXHiY = a_Src[idx + 1 + a_SrcSizeX];
for (int CellY = 0; CellY <= a_UpscaleY; CellY++)
{
- a_Dst[DstX + (DstY + CellY) * a_SizeY] = StartValue + Diff * CellY / a_AnchorStepY;
+ int DestIdx = (DstY + CellY) * DstSizeX + DstX;
+ ASSERT(DestIdx + a_UpscaleX < DstSizeX * DstSizeY);
+ TYPE LoXInY = LoXLoY + (LoXHiY - LoXLoY) * RatioY[CellY];
+ TYPE HiXInY = HiXLoY + (HiXHiY - HiXLoY) * RatioY[CellY];
+ for (int CellX = 0; CellX <= a_UpscaleX; CellX++, DestIdx++)
+ {
+ a_Dst[DestIdx] = LoXInY + (HiXInY - LoXInY) * RatioX[CellX];
+ }
} // for CellY
} // for x
} // for y
-
- // Now interpolate in rows (same-X), each row already has valid values in the anchor columns
- int DstSizeY = a_SizeY * a_UpscaleY;
- int DstSizeX = a_SizeX * a_UpscaleX;
- for (int y = 0; y < DstSizeY; y++)
- {
- int Idx = y * DstSizeX;
- for (int x = 0; x < a_SizeX; x++)
- {
- TYPE StartValue = a_Dst[Idx]; // [x, y] in the src coords
- TYPE EndValue = a_Dst[Idx + a_UpscaleX]; // [x + 1, y] in the src coords
- TYPE Diff = EndValue - StartValue;
- for (int CellX = 0; CellX <= a_UpscaleX; CellX++)
- {
- a_Dst[Idx + CellX] = StartValue + CellX * Diff / a_UpscaleX;
- } // for CellY
- Idx += a_UpscaleX;
- }
- }
}
diff --git a/source/Noise.cpp b/source/Noise.cpp
index 87b3bd4a5..333dc8333 100644
--- a/source/Noise.cpp
+++ b/source/Noise.cpp
@@ -570,7 +570,7 @@ void cCubicNoise::Generate2D(
m_NumSingleY++;
}
m_NumCalls++;
- #endif _DEBUG
+ #endif // _DEBUG
// Calculate query values using Cell:
int FromY = 0;