Fixed 2D linear upscale to compile on Linux, added a test for it.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1484 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
7c094ee220
commit
1118ae3033
@ -61,14 +61,36 @@ void Debug3DNoise(NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_Size
|
|||||||
f2.Write(buf, a_SizeX);
|
f2.Write(buf, a_SizeX);
|
||||||
} // for y
|
} // for y
|
||||||
} // if (XZ file open)
|
} // 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):
|
// Perform an automatic test of upscaling upon program start (use breakpoints to debug):
|
||||||
|
|
||||||
@ -78,6 +100,7 @@ public:
|
|||||||
Test(void)
|
Test(void)
|
||||||
{
|
{
|
||||||
DoTest1();
|
DoTest1();
|
||||||
|
DoTest2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,11 +111,26 @@ public:
|
|||||||
{
|
{
|
||||||
In[i] = (float)(i % 5);
|
In[i] = (float)(i % 5);
|
||||||
}
|
}
|
||||||
Debug3DNoise(In, 3, 3, 3, "Upscale in");
|
Debug3DNoise(In, 3, 3, 3, "Upscale3D in");
|
||||||
float Out[17 * 33 * 35];
|
float Out[17 * 33 * 35];
|
||||||
LinearUpscale3DArray(In, 3, 3, 3, Out, 8, 16, 17);
|
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;
|
} gTest;
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
|
@ -88,49 +88,59 @@ template<typename TYPE> void LinearUpscale2DArray(
|
|||||||
int a_UpscaleX, int a_UpscaleY ///< Upscale factor for each direction
|
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_Src != NULL);
|
||||||
ASSERT(a_Dst != NULL);
|
ASSERT(a_Dst != NULL);
|
||||||
ASSERT(a_SrcSizeX > 0);
|
ASSERT(a_SrcSizeX > 0);
|
||||||
ASSERT(a_SrcSizeY > 0);
|
ASSERT(a_SrcSizeY > 0);
|
||||||
ASSERT(a_UpscaleX > 0);
|
ASSERT(a_UpscaleX > 0);
|
||||||
ASSERT(a_UpscaleY > 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:
|
// Pre-calculate the upscaling ratios:
|
||||||
int idx = 0;
|
TYPE RatioX[MAX_UPSCALE_X];
|
||||||
for (int y = 0; y < a_SrcSizeY; y++)
|
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;
|
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;
|
int DstX = x * a_UpscaleX;
|
||||||
TYPE StartValue = a_Src[idx]; // [x, y]
|
TYPE LoXLoY = a_Src[idx];
|
||||||
TYPE EndValue = a_Src[idx + a_SrcSizeX]; // [x, y + 1]
|
TYPE LoXHiY = a_Src[idx + a_SrcSizeX];
|
||||||
TYPE Diff = EndValue - StartValue;
|
TYPE HiXLoY = a_Src[idx + 1];
|
||||||
|
TYPE HiXHiY = a_Src[idx + 1 + a_SrcSizeX];
|
||||||
for (int CellY = 0; CellY <= a_UpscaleY; CellY++)
|
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 CellY
|
||||||
} // for x
|
} // for x
|
||||||
} // for y
|
} // 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ void cCubicNoise::Generate2D(
|
|||||||
m_NumSingleY++;
|
m_NumSingleY++;
|
||||||
}
|
}
|
||||||
m_NumCalls++;
|
m_NumCalls++;
|
||||||
#endif _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
// Calculate query values using Cell:
|
// Calculate query values using Cell:
|
||||||
int FromY = 0;
|
int FromY = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user