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.addCommandBuffer(cmdbuffer.get());
|
||||||
submit.execute(device.get(), device->graphicsQueue, submitFence.get());
|
submit.execute(device.get(), device->graphicsQueue, submitFence.get());
|
||||||
|
|
||||||
vkWaitForFences(device->device, 1, &submitFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
VkResult result = vkWaitForFences(device->device, 1, &submitFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||||
vkResetFences(device->device, 1, &submitFence->fence);
|
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();
|
cmdbuffer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,9 +246,15 @@ BBox LevelMesh::GetBoundsFromSurface(const Surface* surface)
|
||||||
|
|
||||||
void LevelMesh::CreateTextures()
|
void LevelMesh::CreateTextures()
|
||||||
{
|
{
|
||||||
|
std::vector<Surface*> sortedSurfaces;
|
||||||
|
sortedSurfaces.reserve(surfaces.size());
|
||||||
for (auto& surf : surfaces)
|
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;
|
color *= 0.5f;
|
||||||
|
|
||||||
// get texture offset
|
// 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
|
// convert RGB to bytes
|
||||||
currentTexture[offs + x * 3 + 0] = floatToHalf(colorSamples[y * sampleWidth + x].x);
|
currentTexture[offs + x * 3 + 0] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].x, -65000.0f, 65000.0f));
|
||||||
currentTexture[offs + x * 3 + 1] = floatToHalf(colorSamples[y * sampleWidth + x].y);
|
currentTexture[offs + x * 3 + 1] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].y, -65000.0f, 65000.0f));
|
||||||
currentTexture[offs + x * 3 + 2] = floatToHalf(colorSamples[y * sampleWidth + x].z);
|
currentTexture[offs + x * 3 + 2] = floatToHalf(clamp(colorSamples[y * sampleWidth + x].z, -65000.0f, 65000.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -343,12 +349,12 @@ void LevelMesh::FinishSurface(Surface* surface)
|
||||||
for (int j = 0; j < sampleWidth; j++)
|
for (int j = 0; j < sampleWidth; j++)
|
||||||
{
|
{
|
||||||
// get texture offset
|
// 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
|
// convert RGB to bytes
|
||||||
currentTexture[offs + j * 3 + 0] = floatToHalf(colorSamples[i * sampleWidth + j].x);
|
currentTexture[offs + j * 3 + 0] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].x, -65000.0f, 65000.0f));
|
||||||
currentTexture[offs + j * 3 + 1] = floatToHalf(colorSamples[i * sampleWidth + j].y);
|
currentTexture[offs + j * 3 + 1] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].y, -65000.0f, 65000.0f));
|
||||||
currentTexture[offs + j * 3 + 2] = floatToHalf(colorSamples[i * sampleWidth + j].z);
|
currentTexture[offs + j * 3 + 2] = floatToHalf(clamp(colorSamples[i * sampleWidth + j].z, -65000.0f, 65000.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "framework/tarray.h"
|
#include "framework/tarray.h"
|
||||||
|
#include "framework/halffloat.h"
|
||||||
#include "lightmap/collision.h"
|
#include "lightmap/collision.h"
|
||||||
|
|
||||||
struct MapSubsectorEx;
|
struct MapSubsectorEx;
|
||||||
|
@ -79,54 +80,40 @@ class LightmapTexture
|
||||||
public:
|
public:
|
||||||
LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
||||||
{
|
{
|
||||||
mPixels.resize(width * height * 3);
|
#ifdef _DEBUG
|
||||||
allocBlocks.resize(width);
|
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)
|
bool MakeRoomForBlock(const int width, const int height, int* x, int* y)
|
||||||
{
|
{
|
||||||
int bestRow1 = textureHeight;
|
int startY = 0;
|
||||||
|
int startX = 0;
|
||||||
for (int i = 0; i <= textureWidth - width; i++)
|
for (int i = 0; i < textureHeight; i++)
|
||||||
{
|
{
|
||||||
int bestRow2 = 0;
|
startX = std::max(startX, allocBlocks[i]);
|
||||||
|
int available = textureWidth - startX;
|
||||||
int j;
|
if (available < width)
|
||||||
for (j = 0; j < width; j++)
|
|
||||||
{
|
{
|
||||||
if (allocBlocks[i + j] >= bestRow1)
|
startY = i + 1;
|
||||||
|
startX = 0;
|
||||||
|
}
|
||||||
|
else if (i - startY + 1 == height)
|
||||||
{
|
{
|
||||||
break;
|
for (int yy = 0; yy < height; yy++)
|
||||||
}
|
|
||||||
|
|
||||||
if (allocBlocks[i + j] > bestRow2)
|
|
||||||
{
|
{
|
||||||
bestRow2 = allocBlocks[i + j];
|
allocBlocks[startY + yy] = startX + width;
|
||||||
}
|
}
|
||||||
}
|
*x = startX;
|
||||||
|
*y = startY;
|
||||||
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int Width() const { return textureWidth; }
|
int Width() const { return textureWidth; }
|
||||||
int Height() const { return textureHeight; }
|
int Height() const { return textureHeight; }
|
||||||
|
|
Loading…
Reference in a new issue