mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 13:11:04 +00:00
Improve lightmap atlas and add some more error checks
This commit is contained in:
parent
5d0fe12221
commit
346f71e60a
3 changed files with 45 additions and 48 deletions
|
@ -280,8 +280,12 @@ void GPURaytracer::SubmitCommands()
|
|||
submit.addCommandBuffer(cmdbuffer.get());
|
||||
submit.execute(device.get(), device->graphicsQueue, submitFence.get());
|
||||
|
||||
vkWaitForFences(device->device, 1, &submitFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
vkResetFences(device->device, 1, &submitFence->fence);
|
||||
VkResult result = vkWaitForFences(device->device, 1, &submitFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkWaitForFences failed");
|
||||
result = vkResetFences(device->device, 1, &submitFence->fence);
|
||||
if (result != VK_SUCCESS)
|
||||
throw std::runtime_error("vkResetFences failed");
|
||||
cmdbuffer.reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -246,9 +246,15 @@ BBox LevelMesh::GetBoundsFromSurface(const Surface* surface)
|
|||
|
||||
void LevelMesh::CreateTextures()
|
||||
{
|
||||
std::vector<Surface*> sortedSurfaces;
|
||||
sortedSurfaces.reserve(surfaces.size());
|
||||
for (auto& surf : surfaces)
|
||||
sortedSurfaces.push_back(surf.get());
|
||||
std::sort(sortedSurfaces.begin(), sortedSurfaces.end(), [](Surface* a, Surface* b) { return a->lightmapDims[1] > b->lightmapDims[1]; });
|
||||
|
||||
for (Surface* surf : sortedSurfaces)
|
||||
{
|
||||
FinishSurface(surf.get());
|
||||
FinishSurface(surf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,12 +334,12 @@ void LevelMesh::FinishSurface(Surface* surface)
|
|||
color *= 0.5f;
|
||||
|
||||
// get texture offset
|
||||
int offs = (((textureWidth * (y + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3);
|
||||
int offs = ((textureWidth * (y + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3;
|
||||
|
||||
// convert RGB to bytes
|
||||
currentTexture[offs + x * 3 + 0] = floatToHalf(colorSamples[y * sampleWidth + x].x);
|
||||
currentTexture[offs + x * 3 + 1] = floatToHalf(colorSamples[y * sampleWidth + x].y);
|
||||
currentTexture[offs + x * 3 + 2] = floatToHalf(colorSamples[y * sampleWidth + x].z);
|
||||
currentTexture[offs + x * 3 + 0] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].x, -65000.0f, 65000.0f));
|
||||
currentTexture[offs + x * 3 + 1] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].y, -65000.0f, 65000.0f));
|
||||
currentTexture[offs + x * 3 + 2] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].z, -65000.0f, 65000.0f));
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -343,12 +349,12 @@ void LevelMesh::FinishSurface(Surface* surface)
|
|||
for (int j = 0; j < sampleWidth; j++)
|
||||
{
|
||||
// get texture offset
|
||||
int offs = (((textureWidth * (i + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3);
|
||||
int offs = ((textureWidth * (i + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3;
|
||||
|
||||
// convert RGB to bytes
|
||||
currentTexture[offs + j * 3 + 0] = floatToHalf(colorSamples[i * sampleWidth + j].x);
|
||||
currentTexture[offs + j * 3 + 1] = floatToHalf(colorSamples[i * sampleWidth + j].y);
|
||||
currentTexture[offs + j * 3 + 2] = floatToHalf(colorSamples[i * sampleWidth + j].z);
|
||||
currentTexture[offs + j * 3 + 0] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].x, -65000.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 1] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].y, -65000.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 2] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].z, -65000.0f, 65000.0f));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "framework/tarray.h"
|
||||
#include "framework/halffloat.h"
|
||||
#include "lightmap/collision.h"
|
||||
|
||||
struct MapSubsectorEx;
|
||||
|
@ -79,53 +80,39 @@ class LightmapTexture
|
|||
public:
|
||||
LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
||||
{
|
||||
mPixels.resize(width * height * 3);
|
||||
allocBlocks.resize(width);
|
||||
#ifdef _DEBUG
|
||||
mPixels.resize(width * height * 3, floatToHalf(0.5f));
|
||||
#else
|
||||
mPixels.resize(width * height * 3, 0);
|
||||
#endif
|
||||
allocBlocks.resize(height);
|
||||
}
|
||||
|
||||
bool MakeRoomForBlock(const int width, const int height, int* x, int* y)
|
||||
{
|
||||
int bestRow1 = textureHeight;
|
||||
|
||||
for (int i = 0; i <= textureWidth - width; i++)
|
||||
int startY = 0;
|
||||
int startX = 0;
|
||||
for (int i = 0; i < textureHeight; i++)
|
||||
{
|
||||
int bestRow2 = 0;
|
||||
|
||||
int j;
|
||||
for (j = 0; j < width; j++)
|
||||
startX = std::max(startX, allocBlocks[i]);
|
||||
int available = textureWidth - startX;
|
||||
if (available < width)
|
||||
{
|
||||
if (allocBlocks[i + j] >= bestRow1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (allocBlocks[i + j] > bestRow2)
|
||||
{
|
||||
bestRow2 = allocBlocks[i + j];
|
||||
}
|
||||
startY = i + 1;
|
||||
startX = 0;
|
||||
}
|
||||
|
||||
// found a free block
|
||||
if (j == width)
|
||||
else if (i - startY + 1 == height)
|
||||
{
|
||||
*x = i;
|
||||
*y = bestRow1 = bestRow2;
|
||||
for (int yy = 0; yy < height; yy++)
|
||||
{
|
||||
allocBlocks[startY + yy] = startX + width;
|
||||
}
|
||||
*x = startX;
|
||||
*y = startY;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
int Width() const { return textureWidth; }
|
||||
|
|
Loading…
Reference in a new issue