mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
Initialize lightmap texture in SetLevelMesh
Create VkLightmap class on VulkanRenderDevice
This commit is contained in:
parent
6de6ae28e9
commit
db5c659fab
15 changed files with 125 additions and 200 deletions
|
@ -207,10 +207,14 @@ public:
|
|||
|
||||
std::unique_ptr<TriangleMeshShape> Collision;
|
||||
|
||||
std::vector<std::unique_ptr<Surface>> surfaces;
|
||||
TArray<hwrenderer::Surface> Surfaces;
|
||||
|
||||
TArray<SmoothingGroup> smoothingGroups; // TODO fill
|
||||
TArray<Portal> portals; // TODO fill
|
||||
|
||||
int LMTextureCount = 0;
|
||||
int LMTextureSize = 0;
|
||||
|
||||
FVector3 SunDirection;
|
||||
FVector3 SunColor;
|
||||
|
||||
|
|
|
@ -220,9 +220,6 @@ public:
|
|||
virtual int GetClientHeight() = 0;
|
||||
virtual void BlurScene(float amount) {}
|
||||
|
||||
virtual void GenerateLightmap(TArray<uint16_t>& LMTextureData, int LMTextureSize, hwrenderer::LevelMesh& mesh) {}
|
||||
virtual void InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData) {}
|
||||
|
||||
// Interface to hardware rendering resources
|
||||
virtual IBuffer* CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs) { return nullptr; }
|
||||
virtual IBuffer* CreateIndexBuffer() { return nullptr; }
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
|
||||
{
|
||||
useRayQuery = fb->GetDevice()->PhysicalDevice.Features.RayQuery.rayQuery;
|
||||
|
@ -95,9 +94,9 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex)
|
|||
};
|
||||
beginPass();
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
for (unsigned int i = 0; i < mesh->Surfaces.Size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* targetSurface = mesh->surfaces[i].get();
|
||||
hwrenderer::Surface* targetSurface = &mesh->Surfaces[i];
|
||||
if (targetSurface->atlasPageIndex != pageIndex)
|
||||
continue;
|
||||
|
||||
|
@ -123,8 +122,6 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex)
|
|||
int vertexCount = (int)surface->verts.Size();
|
||||
if (lights.Pos + lightCount > lights.BufferSize || vertices.Pos + vertexCount > vertices.BufferSize)
|
||||
{
|
||||
printf(".");
|
||||
|
||||
// Flush scene buffers
|
||||
FinishCommands();
|
||||
lights.Pos = 0;
|
||||
|
@ -134,8 +131,6 @@ void VkLightmap::RenderAtlasImage(size_t pageIndex)
|
|||
BeginCommands();
|
||||
beginPass();
|
||||
|
||||
printf(".");
|
||||
|
||||
if (lights.Pos + lightCount > lights.BufferSize)
|
||||
{
|
||||
throw std::runtime_error("SceneLightBuffer is too small!");
|
||||
|
@ -200,9 +195,9 @@ void VkLightmap::CreateAtlasImages()
|
|||
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
|
||||
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
for (unsigned int i = 0; i < mesh->Surfaces.Size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* surface = mesh->surfaces[i].get();
|
||||
hwrenderer::Surface* surface = &mesh->Surfaces[i];
|
||||
|
||||
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||
surface->atlasX = result.pos.x + 1;
|
||||
|
@ -309,9 +304,9 @@ void VkLightmap::DownloadAtlasImage(size_t pageIndex)
|
|||
|
||||
hvec4* pixels = (hvec4*)atlasImages[pageIndex].Transfer->Map(0, atlasImageSize * atlasImageSize * sizeof(hvec4));
|
||||
|
||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||
for (unsigned int i = 0; i < mesh->Surfaces.Size(); i++)
|
||||
{
|
||||
hwrenderer::Surface* surface = mesh->surfaces[i].get();
|
||||
hwrenderer::Surface* surface = &mesh->Surfaces[i];
|
||||
if (surface->atlasPageIndex != pageIndex)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
|
|||
|
||||
surfaceBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->surfaces.size() * sizeof(SurfaceInfo))
|
||||
.Size(Mesh->Surfaces.Size() * sizeof(SurfaceInfo))
|
||||
.DebugName("surfaceBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
|
@ -189,6 +189,35 @@ void VkTextureManager::CreateLightmap()
|
|||
SetLightmap(1, 1, data);
|
||||
}
|
||||
|
||||
void VkTextureManager::CreateLightmap(int LMTextureSize, int LMTextureCount)
|
||||
{
|
||||
int w = LMTextureSize;
|
||||
int h = LMTextureSize;
|
||||
int count = LMTextureCount;
|
||||
int pixelsize = 8;
|
||||
|
||||
Lightmap.Reset(fb);
|
||||
|
||||
Lightmap.Image = ImageBuilder()
|
||||
.Size(w, h, 1, count)
|
||||
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.DebugName("VkRenderBuffers.Lightmap")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
Lightmap.View = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D_ARRAY)
|
||||
.Image(Lightmap.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||
.DebugName("VkRenderBuffers.LightmapView")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||
|
||||
VkImageTransition()
|
||||
.AddImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, count)
|
||||
.Execute(cmdbuffer);
|
||||
}
|
||||
|
||||
void VkTextureManager::SetLightmap(int LMTextureSize, int LMTextureCount, const TArray<uint16_t>& LMTextureData)
|
||||
{
|
||||
int w = LMTextureSize;
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
|
||||
void BeginFrame();
|
||||
|
||||
void CreateLightmap(int LMTextureSize, int LMTextureCount);
|
||||
void SetLightmap(int LMTextureSize, int LMTextureCount, const TArray<uint16_t>& LMTextureData);
|
||||
|
||||
VkTextureImage* GetTexture(const PPTextureType& type, PPTexture* tex);
|
||||
|
|
|
@ -184,6 +184,7 @@ void VulkanRenderDevice::InitializeState()
|
|||
mDescriptorSetManager.reset(new VkDescriptorSetManager(this));
|
||||
mRenderPassManager.reset(new VkRenderPassManager(this));
|
||||
mRaytrace.reset(new VkRaytrace(this));
|
||||
mLightmap.reset(new VkLightmap(this));
|
||||
|
||||
mBufferManager->Init();
|
||||
|
||||
|
@ -476,61 +477,6 @@ void VulkanRenderDevice::BeginFrame()
|
|||
mDescriptorSetManager->BeginFrame();
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::GenerateLightmap(TArray<uint16_t>& LMTextureData, int LMTextureSize, hwrenderer::LevelMesh& mesh)
|
||||
{
|
||||
if (false && mesh.surfaces.size() > 0)
|
||||
{
|
||||
Printf("Running VkLightmap.\n");
|
||||
|
||||
//VkLightmap lightmap(this);
|
||||
//lightmap.Raytrace(&mesh);
|
||||
|
||||
Printf("Copying data.\n");
|
||||
|
||||
// TODO refactor
|
||||
|
||||
auto clamp = [](float a, float min, float max) -> float { return a < min ? min : a > max ? max : a; };
|
||||
|
||||
|
||||
std::sort(mesh.surfaces.begin(), mesh.surfaces.end(), [](const std::unique_ptr<hwrenderer::Surface>& a, const std::unique_ptr<hwrenderer::Surface>& b) { return a->texHeight != b->texHeight ? a->texHeight > b->texHeight : a->texWidth > b->texWidth; });
|
||||
|
||||
|
||||
RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0));
|
||||
|
||||
for (auto& surface : mesh.surfaces)
|
||||
{
|
||||
mesh.FinishSurface(LMTextureSize, LMTextureSize, packer, *surface.get());
|
||||
|
||||
uint16_t* currentTexture = LMTextureData.Data() + (LMTextureSize * LMTextureSize * 3) * surface->atlasPageIndex;
|
||||
|
||||
FVector3* colorSamples = surface->texPixels.data();
|
||||
// store results to lightmap texture
|
||||
for (int i = 0; i < surface->texHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < surface->texWidth; j++)
|
||||
{
|
||||
// get texture offset
|
||||
int offs = ((surface->texWidth * (i + surface->atlasY)) + surface->atlasX) * 3;
|
||||
|
||||
// convert RGB to bytes
|
||||
currentTexture[offs + j * 3 + 0] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].X, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 1] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].Y, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 2] = floatToHalf(clamp(colorSamples[i * surface->texWidth + j].Z, 0.0f, 65000.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData)
|
||||
{
|
||||
if (LMTextureData.Size() > 0)
|
||||
{
|
||||
GetTextureManager()->SetLightmap(LMTextureSize, LMTextureCount, LMTextureData);
|
||||
LMTextureData.Reset(); // We no longer need this, release the memory
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::Draw2D()
|
||||
{
|
||||
::Draw2D(twod, *RenderState(0));
|
||||
|
@ -589,6 +535,61 @@ void VulkanRenderDevice::PrintStartupLog()
|
|||
void VulkanRenderDevice::SetLevelMesh(hwrenderer::LevelMesh* mesh)
|
||||
{
|
||||
mRaytrace->SetLevelMesh(mesh);
|
||||
|
||||
if (mesh->Surfaces.Size() > 0)
|
||||
{
|
||||
#if 0 // To do: GetLightmap()->Raytrace should output directly to the lightmap texture instead of forcing us to download it to the CPU first
|
||||
|
||||
GetTextureManager()->CreateLightmap(mesh->LMTextureSize, mesh->LMTextureCount);
|
||||
GetCommands()->WaitForCommands(false);
|
||||
GetLightmap()->Raytrace(mesh);
|
||||
|
||||
#else // Temporary version using the old zdray Raytracer code as-is
|
||||
|
||||
Printf("Running VkLightmap.\n");
|
||||
|
||||
GetLightmap()->Raytrace(mesh);
|
||||
|
||||
Printf("Copying data.\n");
|
||||
|
||||
// TODO refactor
|
||||
|
||||
auto clamp = [](float a, float min, float max) -> float { return a < min ? min : a > max ? max : a; };
|
||||
|
||||
// BUG: This is a destructive action as it reorders the surfaces array that is indexed by MeshSurfaces
|
||||
std::sort(mesh->Surfaces.begin(), mesh->Surfaces.end(), [](const hwrenderer::Surface& a, const hwrenderer::Surface& b) { return a.texHeight != b.texHeight ? a.texHeight > b.texHeight : a.texWidth > b.texWidth; });
|
||||
|
||||
RectPacker packer(mesh->LMTextureSize, mesh->LMTextureSize, RectPacker::Spacing(0));
|
||||
|
||||
TArray<uint16_t> LMTextureData;
|
||||
LMTextureData.Resize(mesh->LMTextureSize * mesh->LMTextureSize * mesh->LMTextureCount * 3);
|
||||
|
||||
for (auto& surface : mesh->Surfaces)
|
||||
{
|
||||
mesh->FinishSurface(mesh->LMTextureSize, mesh->LMTextureSize, packer, surface);
|
||||
|
||||
uint16_t* currentTexture = LMTextureData.Data() + (mesh->LMTextureSize * mesh->LMTextureSize * 3) * surface.atlasPageIndex;
|
||||
|
||||
FVector3* colorSamples = surface.texPixels.data();
|
||||
// store results to lightmap texture
|
||||
for (int i = 0; i < surface.texHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < surface.texWidth; j++)
|
||||
{
|
||||
// get texture offset
|
||||
int offs = ((surface.texWidth * (i + surface.atlasY)) + surface.atlasX) * 3;
|
||||
|
||||
// convert RGB to bytes
|
||||
currentTexture[offs + j * 3 + 0] = floatToHalf(clamp(colorSamples[i * surface.texWidth + j].X, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 1] = floatToHalf(clamp(colorSamples[i * surface.texWidth + j].Y, 0.0f, 65000.0f));
|
||||
currentTexture[offs + j * 3 + 2] = floatToHalf(clamp(colorSamples[i * surface.texWidth + j].Z, 0.0f, 65000.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetTextureManager()->SetLightmap(mesh->LMTextureSize, mesh->LMTextureCount, LMTextureData);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::SetShadowMaps(const TArray<float>& lights, hwrenderer::LevelAABBTree* tree, bool newTree)
|
||||
|
|
|
@ -15,6 +15,7 @@ class VkDescriptorSetManager;
|
|||
class VkRenderPassManager;
|
||||
class VkFramebufferManager;
|
||||
class VkRaytrace;
|
||||
class VkLightmap;
|
||||
class VkRenderState;
|
||||
class VkStreamBuffer;
|
||||
class VkHardwareDataBuffer;
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
VkDescriptorSetManager* GetDescriptorSetManager() { return mDescriptorSetManager.get(); }
|
||||
VkRenderPassManager *GetRenderPassManager() { return mRenderPassManager.get(); }
|
||||
VkRaytrace* GetRaytrace() { return mRaytrace.get(); }
|
||||
VkLightmap* GetLightmap() { return mLightmap.get(); }
|
||||
VkRenderState *GetRenderState(int threadIndex) { return mRenderState[threadIndex].get(); }
|
||||
VkPostprocess *GetPostprocess() { return mPostprocess.get(); }
|
||||
VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; }
|
||||
|
@ -56,8 +58,6 @@ public:
|
|||
void SetTextureFilterMode() override;
|
||||
void StartPrecaching() override;
|
||||
void BeginFrame() override;
|
||||
void GenerateLightmap(TArray<uint16_t>& LMTextureData, int LMTextureSize, hwrenderer::LevelMesh& mesh) override;
|
||||
void InitLightmap(int LMTextureSize, int LMTextureCount, TArray<uint16_t>& LMTextureData) override;
|
||||
void BlurScene(float amount) override;
|
||||
void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||
void AmbientOccludeScene(float m5) override;
|
||||
|
@ -108,6 +108,7 @@ private:
|
|||
std::unique_ptr<VkDescriptorSetManager> mDescriptorSetManager;
|
||||
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
|
||||
std::unique_ptr<VkRaytrace> mRaytrace;
|
||||
std::unique_ptr<VkLightmap> mLightmap;
|
||||
std::vector<std::unique_ptr<VkRenderState>> mRenderState;
|
||||
|
||||
VkRenderBuffers *mActiveRenderBuffers = nullptr;
|
||||
|
|
|
@ -396,9 +396,9 @@ void D_Render(std::function<void()> action, bool interpolate)
|
|||
for (auto Level : AllLevels())
|
||||
{
|
||||
// Check for the presence of dynamic lights at the start of the frame once.
|
||||
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4) || Level->LMTextureCount > 0)
|
||||
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4) || Level->lightmaps)
|
||||
{
|
||||
Level->HasDynamicLights = Level->lights || Level->LMTextureCount > 0;
|
||||
Level->HasDynamicLights = Level->lights || Level->lightmaps;
|
||||
}
|
||||
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
if (interpolate) Level->interpolator.DoInterpolations(I_GetTimeFrac());
|
||||
|
|
|
@ -454,11 +454,8 @@ public:
|
|||
TArray<FLinePortal> linePortals;
|
||||
|
||||
// Lightmaps
|
||||
bool lightmaps = false;
|
||||
TArray<LightmapSurface> LMSurfaces;
|
||||
TArray<float> LMTexCoords;
|
||||
int LMTextureCount = 0;
|
||||
int LMTextureSize = 0;
|
||||
TArray<uint16_t> LMTextureData;
|
||||
FVector3 SunDirection;
|
||||
FVector3 SunColor;
|
||||
|
||||
|
|
|
@ -3214,10 +3214,6 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
|
|||
Level->levelMesh = new DoomLevelMesh(*Level);
|
||||
InitLightmap(map);
|
||||
|
||||
screen->GenerateLightmap(Level->LMTextureData, Level->LMTextureSize, *Level->levelMesh);
|
||||
|
||||
screen->InitLightmap(Level->LMTextureSize, Level->LMTextureCount, Level->LMTextureData);
|
||||
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (Level->PlayerInGame(i) && Level->Players[i]->mo != nullptr)
|
||||
|
@ -3330,96 +3326,6 @@ void MapLoader::SetSideLightmap(const LightmapSurface &surface)
|
|||
}
|
||||
}
|
||||
|
||||
#include "vulkan/accelstructs/halffloat.h"
|
||||
|
||||
void MapLoader::GenerateLightmap(const DoomLevelMesh& mesh, int atlasPages, int atlasWidth, int atlasHeight)
|
||||
{
|
||||
Level->LMTextureData.Resize(atlasWidth * atlasHeight * 3 * atlasPages);
|
||||
|
||||
uint16_t* ptr = Level->LMTextureData.Data();
|
||||
|
||||
for (int i = 0; i < atlasPages; ++i)
|
||||
{
|
||||
for (int y = 0; y < atlasWidth; ++y)
|
||||
{
|
||||
for (int x = 0; x < atlasHeight; ++x)
|
||||
{
|
||||
/**(ptr++) = floatToHalf(float(x) / width);
|
||||
*(ptr++) = floatToHalf(float(y) / height);
|
||||
*(ptr++) = floatToHalf((x + y) % 2 == 0 ? 1.0f : 0.0f);*/
|
||||
switch (i % 3)
|
||||
{
|
||||
case 0:
|
||||
*(ptr++) = floatToHalf(1.0f);
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
break;
|
||||
case 1:
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
*(ptr++) = floatToHalf(1.0f);
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
break;
|
||||
case 2:
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
*(ptr++) = floatToHalf(0.0f);
|
||||
*(ptr++) = floatToHalf(1.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto get_xy = [&](int page, int x, int y) -> uint16_t*
|
||||
{
|
||||
return Level->LMTextureData.Data() + ((y * atlasWidth) + x + (atlasHeight * atlasWidth * page)) * 3;
|
||||
};
|
||||
|
||||
//#if 0
|
||||
srand(1337);
|
||||
for (auto& surface : mesh.Surfaces)
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
|
||||
r = rand() % 32 / 32.0f;
|
||||
g = rand() % 32 / 32.0f;
|
||||
b = rand() % 32 / 32.0f;
|
||||
|
||||
for (int y = 0; y <= surface.texHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x <= surface.texWidth; ++x)
|
||||
{
|
||||
auto ptr = get_xy(surface.atlasPageIndex, surface.atlasX + x, surface.atlasY + y);
|
||||
|
||||
ptr[0] = floatToHalf(r);
|
||||
ptr[1] = floatToHalf(g);
|
||||
ptr[2] = floatToHalf(b);
|
||||
|
||||
if (x % 4 == 0 || y % 4 == 0)
|
||||
{
|
||||
ptr[0] = floatToHalf(0.0f);
|
||||
ptr[1] = floatToHalf(0.0f);
|
||||
ptr[2] = floatToHalf(0.0f);
|
||||
}
|
||||
|
||||
/*if (Level->levelMesh->TraceSky(surface.worldOrigin - surface.worldStepX * 0.5f - surface.worldStepY * 0.5f + surface.worldStepX * x + surface.worldStepY * y + FVector3(surface.plane.Normal()), Level->SunDirection, 32000.0f))
|
||||
{
|
||||
ptr[0] = floatToHalf(Level->SunColor.X);
|
||||
ptr[1] = floatToHalf(Level->SunColor.Y);
|
||||
ptr[2] = floatToHalf(Level->SunColor.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[0] = 0;
|
||||
ptr[1] = 0;
|
||||
ptr[2] = 0;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapLoader::BindLightmapSurfacesToGeometry()
|
||||
{
|
||||
// Allocate room for all surfaces
|
||||
|
@ -3487,11 +3393,7 @@ void MapLoader::BindLightmapSurfacesToGeometry()
|
|||
void MapLoader::InitLightmap(MapData* map)
|
||||
{
|
||||
// We have to reset everything as FLevelLocals is recycled between maps
|
||||
Level->LMTexCoords.Reset();
|
||||
Level->LMSurfaces.Reset();
|
||||
Level->LMTextureData.Reset();
|
||||
|
||||
Level->LMTextureSize = 1024; // TODO cvar
|
||||
|
||||
// TODO read from ZDRayInfoThing
|
||||
Level->SunColor = FVector3(1.f, 1.f, 1.f);
|
||||
|
@ -3500,9 +3402,8 @@ void MapLoader::InitLightmap(MapData* map)
|
|||
Level->levelMesh->SunColor = Level->SunColor; // TODO keep only one copy?
|
||||
Level->levelMesh->SunDirection = Level->SunDirection;
|
||||
|
||||
Level->LMTextureCount = Level->levelMesh->SetupLightmapUvs(Level->LMTextureSize);
|
||||
Level->lightmaps = true;
|
||||
|
||||
GenerateLightmap(*Level->levelMesh, Level->LMTextureCount, Level->LMTextureSize, Level->LMTextureSize);
|
||||
BindLightmapSurfacesToGeometry();
|
||||
}
|
||||
|
||||
|
|
|
@ -312,7 +312,6 @@ public:
|
|||
void LoadLightmap(MapData *map);
|
||||
#endif
|
||||
void InitLightmap(MapData* map);
|
||||
void GenerateLightmap(const DoomLevelMesh& mesh, int atlasPages, int atlasWidth, int atlasHeight);
|
||||
void BindLightmapSurfacesToGeometry();
|
||||
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ void DoomLevelMesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *sub,
|
|||
surf.type = hwrenderer::ST_FLOOR;
|
||||
surf.typeIndex = typeIndex;
|
||||
surf.controlSector = is3DFloor ? sector : nullptr;
|
||||
surf.plane = FVector4(plane.Normal().X, plane.Normal().Y, plane.Normal().Z, plane.D);
|
||||
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, (float)plane.D);
|
||||
|
||||
Surfaces.Push(surf);
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ void DoomLevelMesh::CreateCeilingSurface(FLevelLocals &doomMap, subsector_t *sub
|
|||
surf.type = hwrenderer::ST_CEILING;
|
||||
surf.typeIndex = typeIndex;
|
||||
surf.controlSector = is3DFloor ? sector : nullptr;
|
||||
surf.plane = FVector4(plane.Normal().X, plane.Normal().Y, plane.Normal().Z, plane.D);
|
||||
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, (float)plane.D);
|
||||
|
||||
Surfaces.Push(surf);
|
||||
}
|
||||
|
@ -487,21 +487,23 @@ void DoomLevelMesh::DumpMesh(const FString& filename) const
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
int DoomLevelMesh::SetupLightmapUvs(int lightmapSize)
|
||||
void DoomLevelMesh::SetupLightmapUvs()
|
||||
{
|
||||
LMTextureSize = 1024; // TODO cvar
|
||||
|
||||
std::vector<Surface*> sortedSurfaces;
|
||||
sortedSurfaces.reserve(Surfaces.Size());
|
||||
|
||||
for (auto& surface : Surfaces)
|
||||
{
|
||||
BuildSurfaceParams(lightmapSize, lightmapSize, surface);
|
||||
BuildSurfaceParams(LMTextureSize, LMTextureSize, surface);
|
||||
sortedSurfaces.push_back(&surface);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
for (const auto& surface : Surfaces)
|
||||
{
|
||||
auto hwSurface = std::make_unique<hwrenderer::Surface>();
|
||||
hwrenderer::Surface hwSurface;
|
||||
|
||||
for (int i = 0; i < surface.numVerts; ++i)
|
||||
{
|
||||
|
@ -535,36 +537,37 @@ int DoomLevelMesh::SetupLightmapUvs(int lightmapSize)
|
|||
}
|
||||
|
||||
// TODO push
|
||||
surfaces.push_back(std::move(hwSurface));
|
||||
Surfaces.push_back(hwSurface);
|
||||
|
||||
SurfaceInfo info;
|
||||
info.Normal = surface.plane.XYZ();
|
||||
info.PortalIndex = 0;
|
||||
info.SamplingDistance = surface.sampleDimension;
|
||||
info.SamplingDistance = (float)surface.sampleDimension;
|
||||
info.Sky = surface.bSky;
|
||||
|
||||
surfaceInfo.Push(info);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
hwrenderer::SmoothingGroup smoothing;
|
||||
|
||||
for (auto& surface : surfaces)
|
||||
for (auto& surface : Surfaces)
|
||||
{
|
||||
smoothing.surfaces.push_back(surface.get());
|
||||
smoothing.surfaces.push_back(&surface);
|
||||
}
|
||||
smoothingGroups.Push(std::move(smoothing));
|
||||
}
|
||||
|
||||
std::sort(sortedSurfaces.begin(), sortedSurfaces.end(), [](Surface* a, Surface* b) { return a->texHeight != b->texHeight ? a->texHeight > b->texHeight : a->texWidth > b->texWidth; });
|
||||
|
||||
RectPacker packer(lightmapSize, lightmapSize, RectPacker::Spacing(0));
|
||||
RectPacker packer(LMTextureSize, LMTextureSize, RectPacker::Spacing(0));
|
||||
|
||||
for (Surface* surf : sortedSurfaces)
|
||||
{
|
||||
FinishSurface(lightmapSize, lightmapSize, packer, *surf);
|
||||
FinishSurface(LMTextureSize, LMTextureSize, packer, *surf);
|
||||
}
|
||||
|
||||
// You have no idea how long this took me to figure out...
|
||||
|
@ -589,8 +592,7 @@ int DoomLevelMesh::SetupLightmapUvs(int lightmapSize)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return packer.getNumPages();
|
||||
LMTextureCount = (int)packer.getNumPages();
|
||||
}
|
||||
|
||||
void DoomLevelMesh::FinishSurface(int lightmapTextureWidth, int lightmapTextureHeight, RectPacker& packer, Surface& surface)
|
||||
|
@ -642,7 +644,7 @@ void DoomLevelMesh::FinishSurface(int lightmapTextureWidth, int lightmapTextureH
|
|||
|
||||
BBox DoomLevelMesh::GetBoundsFromSurface(const Surface& surface) const
|
||||
{
|
||||
constexpr float M_INFINITY = 1e30; // TODO cleanup
|
||||
constexpr float M_INFINITY = 1e30f; // TODO cleanup
|
||||
|
||||
FVector3 low(M_INFINITY, M_INFINITY, M_INFINITY);
|
||||
FVector3 hi(-M_INFINITY, -M_INFINITY, -M_INFINITY);
|
||||
|
|
|
@ -25,18 +25,16 @@ public:
|
|||
return true;
|
||||
|
||||
int surfaceIndex = MeshSurfaces[hit.triangle];
|
||||
const hwrenderer::Surface& surface = Surfaces[surfaceIndex];
|
||||
return surface.bSky;
|
||||
return Surfaces[surfaceIndex].bSky;
|
||||
}
|
||||
|
||||
TArray<hwrenderer::Surface> Surfaces;
|
||||
TArray<FVector2> LightmapUvs;
|
||||
|
||||
static_assert(alignof(FVector2) == alignof(float[2]) && sizeof(FVector2) == sizeof(float) * 2);
|
||||
|
||||
void DumpMesh(const FString& filename) const;
|
||||
|
||||
int SetupLightmapUvs(int lightmapSize);
|
||||
void SetupLightmapUvs();
|
||||
|
||||
private:
|
||||
void CreateSubsectorSurfaces(FLevelLocals &doomMap);
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
|
||||
bool TraceSunVisibility(float x, float y, float z)
|
||||
{
|
||||
if (level.LMTextureCount == 0 || !Actor)
|
||||
if (!level.lightmaps || !Actor)
|
||||
return false;
|
||||
|
||||
if (!ActorMoved && CurrentBit < 64)
|
||||
|
|
Loading…
Reference in a new issue