mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-29 15:12:25 +00:00
- move allocBlocks to LightmapTexture
This commit is contained in:
parent
79d0b257e1
commit
d03ded7f94
2 changed files with 90 additions and 102 deletions
|
@ -54,78 +54,6 @@ LightmapBuilder::~LightmapBuilder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightmapBuilder::NewTexture()
|
|
||||||
{
|
|
||||||
numTextures++;
|
|
||||||
|
|
||||||
allocBlocks.push_back(std::vector<int>(textureWidth));
|
|
||||||
textures.push_back(std::make_unique<LightmapTexture>(textureWidth, textureHeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determines where to map a new block on to the lightmap texture
|
|
||||||
bool LightmapBuilder::MakeRoomForBlock(const int width, const int height, int *x, int *y, int *num)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
int k;
|
|
||||||
int bestRow1;
|
|
||||||
int bestRow2;
|
|
||||||
|
|
||||||
*num = -1;
|
|
||||||
|
|
||||||
if (allocBlocks.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k = 0; k < numTextures; ++k)
|
|
||||||
{
|
|
||||||
bestRow1 = textureHeight;
|
|
||||||
|
|
||||||
for (i = 0; i <= textureWidth - width; i++)
|
|
||||||
{
|
|
||||||
bestRow2 = 0;
|
|
||||||
|
|
||||||
for (j = 0; j < width; j++)
|
|
||||||
{
|
|
||||||
if (allocBlocks[k][i + j] >= bestRow1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allocBlocks[k][i + j] > bestRow2)
|
|
||||||
{
|
|
||||||
bestRow2 = allocBlocks[k][i + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// found a free block
|
|
||||||
if (j == width)
|
|
||||||
{
|
|
||||||
*x = i;
|
|
||||||
*y = bestRow1 = bestRow2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bestRow1 + height > textureHeight)
|
|
||||||
{
|
|
||||||
// no room
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < width; i++)
|
|
||||||
{
|
|
||||||
// store row offset
|
|
||||||
allocBlocks[k][*x + i] = bestRow1 + height;
|
|
||||||
}
|
|
||||||
|
|
||||||
*num = k;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BBox LightmapBuilder::GetBoundsFromSurface(const Surface *surface)
|
BBox LightmapBuilder::GetBoundsFromSurface(const Surface *surface)
|
||||||
{
|
{
|
||||||
Vec3 low(M_INFINITY, M_INFINITY, M_INFINITY);
|
Vec3 low(M_INFINITY, M_INFINITY, M_INFINITY);
|
||||||
|
@ -477,28 +405,7 @@ void LightmapBuilder::FinishSurface(Surface *surface)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
int width = surface->lightmapDims[0];
|
uint16_t *currentTexture = AllocTextureRoom(surface, &x, &y);
|
||||||
int height = surface->lightmapDims[1];
|
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
// now that we know the width and height of this block, see if we got
|
|
||||||
// room for it in the light map texture. if not, then we must allocate
|
|
||||||
// a new texture
|
|
||||||
if (!MakeRoomForBlock(width, height, &x, &y, &surface->lightmapNum))
|
|
||||||
{
|
|
||||||
// allocate a new texture for this block
|
|
||||||
NewTexture();
|
|
||||||
|
|
||||||
if (!MakeRoomForBlock(width, height, &x, &y, &surface->lightmapNum))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Lightmap allocation failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t *currentTexture = textures[surface->lightmapNum]->Pixels();
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
// calculate texture coordinates
|
// calculate texture coordinates
|
||||||
for (int i = 0; i < surface->numVerts; i++)
|
for (int i = 0; i < surface->numVerts; i++)
|
||||||
|
@ -528,6 +435,34 @@ void LightmapBuilder::FinishSurface(Surface *surface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t *LightmapBuilder::AllocTextureRoom(Surface *surface, int *x, int *y)
|
||||||
|
{
|
||||||
|
int width = surface->lightmapDims[0];
|
||||||
|
int height = surface->lightmapDims[1];
|
||||||
|
int numTextures = textures.size();
|
||||||
|
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < numTextures; ++k)
|
||||||
|
{
|
||||||
|
if (textures[k]->MakeRoomForBlock(width, height, x, y))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k == numTextures)
|
||||||
|
{
|
||||||
|
textures.push_back(std::make_unique<LightmapTexture>(textureWidth, textureHeight));
|
||||||
|
if (!textures[k]->MakeRoomForBlock(width, height, x, y))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Lightmap allocation failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->lightmapNum = k;
|
||||||
|
return textures[surface->lightmapNum]->Pixels();
|
||||||
|
}
|
||||||
|
|
||||||
static float RadicalInverse_VdC(uint32_t bits)
|
static float RadicalInverse_VdC(uint32_t bits)
|
||||||
{
|
{
|
||||||
bits = (bits << 16u) | (bits >> 16u);
|
bits = (bits << 16u) | (bits >> 16u);
|
||||||
|
@ -1033,3 +968,56 @@ void LightmapBuilder::AddLightmapLump(FWadWriter &wadFile)
|
||||||
wadFile.StartWritingLump("LIGHTMAP");
|
wadFile.StartWritingLump("LIGHTMAP");
|
||||||
zout.Write(buffer.data(), lumpFile.BufferAt() - lumpFile.Buffer());
|
zout.Write(buffer.data(), lumpFile.BufferAt() - lumpFile.Buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LightmapTexture::LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
||||||
|
{
|
||||||
|
mPixels.resize(width * height * 3);
|
||||||
|
allocBlocks.resize(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LightmapTexture::MakeRoomForBlock(const int width, const int height, int *x, int *y)
|
||||||
|
{
|
||||||
|
int bestRow1 = textureHeight;
|
||||||
|
|
||||||
|
for (int i = 0; i <= textureWidth - width; i++)
|
||||||
|
{
|
||||||
|
int bestRow2 = 0;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
if (allocBlocks[i + j] >= bestRow1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocBlocks[i + j] > bestRow2)
|
||||||
|
{
|
||||||
|
bestRow2 = allocBlocks[i + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// found a free block
|
||||||
|
if (j == width)
|
||||||
|
{
|
||||||
|
*x = i;
|
||||||
|
*y = bestRow1 = bestRow2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestRow1 + height > textureHeight)
|
||||||
|
{
|
||||||
|
// no room
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store row offset
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
allocBlocks[*x + i] = bestRow1 + height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -56,15 +56,17 @@ public:
|
||||||
class LightmapTexture
|
class LightmapTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LightmapTexture(int width, int height)
|
LightmapTexture(int width, int height);
|
||||||
{
|
|
||||||
mPixels.resize(width * height * 3);
|
bool MakeRoomForBlock(const int width, const int height, int *x, int *y);
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t *Pixels() { return mPixels.data(); }
|
uint16_t *Pixels() { return mPixels.data(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int textureWidth;
|
||||||
|
int textureHeight;
|
||||||
std::vector<uint16_t> mPixels;
|
std::vector<uint16_t> mPixels;
|
||||||
|
std::vector<int> allocBlocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TraceTask
|
class TraceTask
|
||||||
|
@ -89,8 +91,6 @@ public:
|
||||||
void AddLightmapLump(FWadWriter &wadFile);
|
void AddLightmapLump(FWadWriter &wadFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void NewTexture();
|
|
||||||
bool MakeRoomForBlock(const int width, const int height, int *x, int *y, int *num);
|
|
||||||
BBox GetBoundsFromSurface(const Surface *surface);
|
BBox GetBoundsFromSurface(const Surface *surface);
|
||||||
Vec3 LightTexelSample(const Vec3 &origin, Surface *surface);
|
Vec3 LightTexelSample(const Vec3 &origin, Surface *surface);
|
||||||
bool EmitFromCeiling(const Surface *surface, const Vec3 &origin, const Vec3 &normal, Vec3 &color);
|
bool EmitFromCeiling(const Surface *surface, const Vec3 &origin, const Vec3 &normal, Vec3 &color);
|
||||||
|
@ -107,6 +107,8 @@ private:
|
||||||
|
|
||||||
void CreateSurfaceLights();
|
void CreateSurfaceLights();
|
||||||
|
|
||||||
|
uint16_t *AllocTextureRoom(Surface *surface, int *x, int *y);
|
||||||
|
|
||||||
FLevel *map;
|
FLevel *map;
|
||||||
int samples = 16;
|
int samples = 16;
|
||||||
int textureWidth = 128;
|
int textureWidth = 128;
|
||||||
|
@ -116,8 +118,6 @@ private:
|
||||||
std::vector<std::unique_ptr<SurfaceLight>> surfaceLights;
|
std::vector<std::unique_ptr<SurfaceLight>> surfaceLights;
|
||||||
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
||||||
std::vector<TraceTask> traceTasks;
|
std::vector<TraceTask> traceTasks;
|
||||||
std::vector<std::vector<int>> allocBlocks;
|
|
||||||
int numTextures = 0;
|
|
||||||
int extraSamples = 2;
|
int extraSamples = 2;
|
||||||
int tracedTexels = 0;
|
int tracedTexels = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue