mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-10 06:41:37 +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)
|
||||
{
|
||||
Vec3 low(M_INFINITY, M_INFINITY, M_INFINITY);
|
||||
|
@ -477,28 +405,7 @@ void LightmapBuilder::FinishSurface(Surface *surface)
|
|||
else
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
int width = surface->lightmapDims[0];
|
||||
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();
|
||||
uint16_t *currentTexture = AllocTextureRoom(surface, &x, &y);
|
||||
|
||||
// calculate texture coordinates
|
||||
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)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
|
@ -1033,3 +968,56 @@ void LightmapBuilder::AddLightmapLump(FWadWriter &wadFile)
|
|||
wadFile.StartWritingLump("LIGHTMAP");
|
||||
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
|
||||
{
|
||||
public:
|
||||
LightmapTexture(int width, int height)
|
||||
{
|
||||
mPixels.resize(width * height * 3);
|
||||
}
|
||||
LightmapTexture(int width, int height);
|
||||
|
||||
bool MakeRoomForBlock(const int width, const int height, int *x, int *y);
|
||||
|
||||
uint16_t *Pixels() { return mPixels.data(); }
|
||||
|
||||
private:
|
||||
int textureWidth;
|
||||
int textureHeight;
|
||||
std::vector<uint16_t> mPixels;
|
||||
std::vector<int> allocBlocks;
|
||||
};
|
||||
|
||||
class TraceTask
|
||||
|
@ -89,8 +91,6 @@ public:
|
|||
void AddLightmapLump(FWadWriter &wadFile);
|
||||
|
||||
private:
|
||||
void NewTexture();
|
||||
bool MakeRoomForBlock(const int width, const int height, int *x, int *y, int *num);
|
||||
BBox GetBoundsFromSurface(const Surface *surface);
|
||||
Vec3 LightTexelSample(const Vec3 &origin, Surface *surface);
|
||||
bool EmitFromCeiling(const Surface *surface, const Vec3 &origin, const Vec3 &normal, Vec3 &color);
|
||||
|
@ -107,6 +107,8 @@ private:
|
|||
|
||||
void CreateSurfaceLights();
|
||||
|
||||
uint16_t *AllocTextureRoom(Surface *surface, int *x, int *y);
|
||||
|
||||
FLevel *map;
|
||||
int samples = 16;
|
||||
int textureWidth = 128;
|
||||
|
@ -116,8 +118,6 @@ private:
|
|||
std::vector<std::unique_ptr<SurfaceLight>> surfaceLights;
|
||||
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
||||
std::vector<TraceTask> traceTasks;
|
||||
std::vector<std::vector<int>> allocBlocks;
|
||||
int numTextures = 0;
|
||||
int extraSamples = 2;
|
||||
int tracedTexels = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue