mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-01-24 08:41:06 +00:00
Save lightmap lump
This commit is contained in:
parent
df010a5643
commit
7c1acb5075
6 changed files with 50 additions and 69 deletions
|
@ -941,8 +941,7 @@ void FProcessor::WriteUDMF(FWadWriter &out)
|
||||||
|
|
||||||
if (LightmapMesh)
|
if (LightmapMesh)
|
||||||
{
|
{
|
||||||
LightmapMesh->AddLightmapLump(out);
|
LightmapMesh->AddLightmapLump(Level, out);
|
||||||
//LightmapMesh->Export("level.obj");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out.CreateLabel("ENDMAP");
|
out.CreateLabel("ENDMAP");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "doom_levelmesh.h"
|
#include "doom_levelmesh.h"
|
||||||
#include "level/level.h"
|
#include "level/level.h"
|
||||||
#include "framework/halffloat.h"
|
#include "framework/halffloat.h"
|
||||||
|
#include "framework/binfile.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ void DoomLevelMesh::DumpMesh(const FString& objFilename, const FString& mtlFilen
|
||||||
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->DumpMesh(objFilename, mtlFilename);
|
static_cast<DoomLevelSubmesh*>(StaticMesh.get())->DumpMesh(objFilename, mtlFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile)
|
void DoomLevelMesh::AddLightmapLump(FLevel& doomMap, FWadWriter& wadFile)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
// LIGHTMAP V2 pseudo-C specification:
|
// LIGHTMAP V2 pseudo-C specification:
|
||||||
|
@ -62,20 +63,15 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile)
|
||||||
for (unsigned int i = 0; i < submesh->Surfaces.Size(); i++)
|
for (unsigned int i = 0; i < submesh->Surfaces.Size(); i++)
|
||||||
{
|
{
|
||||||
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
||||||
if (surface->atlasPageIndex != -1)
|
if (surface->AtlasTile.ArrayIndex != -1)
|
||||||
{
|
{
|
||||||
surfaceCount++;
|
surfaceCount++;
|
||||||
pixelCount += surface->Area();
|
pixelCount += surface->Area();
|
||||||
uvCount += surface->verts.size();
|
uvCount += surface->numVerts;
|
||||||
|
|
||||||
if (surface->Area() != surf.texPixels.size())
|
|
||||||
{
|
|
||||||
printf("Error: Surface area does not match the pixel count.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" Writing %u surfaces out of %llu\n", surfaceCount, surfaces.size());
|
printf(" Writing %u surfaces out of %llu\n", surfaceCount, (size_t)submesh->Surfaces.Size());
|
||||||
|
|
||||||
const int version = 2;
|
const int version = 2;
|
||||||
|
|
||||||
|
@ -118,23 +114,23 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile)
|
||||||
{
|
{
|
||||||
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
||||||
|
|
||||||
if (surface->atlasPageIndex == -1)
|
if (surface->AtlasTile.ArrayIndex == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lumpFile.Write32(surface->Type);
|
lumpFile.Write32(surface->Type);
|
||||||
lumpFile.Write32(surface->TypeIndex);
|
lumpFile.Write32(surface->TypeIndex);
|
||||||
lumpFile.Write32(surface->ControlSector ? uint32_t(surface->ControlSector - &map->Sectors[0]) : 0xffffffff);
|
lumpFile.Write32(surface->ControlSector ? uint32_t(surface->ControlSector->Index(doomMap)) : 0xffffffff);
|
||||||
|
|
||||||
lumpFile.Write16(uint16_t(surface->texWidth));
|
lumpFile.Write16(uint16_t(surface->AtlasTile.Width));
|
||||||
lumpFile.Write16(uint16_t(surface->texHeight));
|
lumpFile.Write16(uint16_t(surface->AtlasTile.Height));
|
||||||
|
|
||||||
lumpFile.Write32(pixelsOffset * 3);
|
lumpFile.Write32(pixelsOffset * 3);
|
||||||
|
|
||||||
lumpFile.Write32(surface->lightUV.size());
|
lumpFile.Write32(surface->numVerts);
|
||||||
lumpFile.Write32(uvOffset);
|
lumpFile.Write32(uvOffset);
|
||||||
|
|
||||||
pixelsOffset += surface->Area();
|
pixelsOffset += surface->Area();
|
||||||
uvOffset += surface->lightUV.size();
|
uvOffset += (uint32_t)surface->numVerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
|
@ -147,19 +143,22 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile)
|
||||||
{
|
{
|
||||||
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
||||||
|
|
||||||
if (surface->atlasPageIndex == -1)
|
if (surface->AtlasTile.ArrayIndex == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (debug)
|
const uint16_t* pixels = submesh->LMTextureData.Data() + surface->AtlasTile.ArrayIndex * submesh->LMTextureSize * submesh->LMTextureSize * 4;
|
||||||
|
int width = surface->AtlasTile.Width;
|
||||||
|
int height = surface->AtlasTile.Height;
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
printf("Surface %llu contains %llu pixels\n", i, surface->texPixels.size());
|
const uint16_t* srcline = pixels + (surface->AtlasTile.X + (surface->AtlasTile.Y + y) * submesh->LMTextureSize) * 4;
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
lumpFile.Write16(*(srcline++));
|
||||||
|
lumpFile.Write16(*(srcline++));
|
||||||
|
lumpFile.Write16(*(srcline++));
|
||||||
|
srcline++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& pixel : surface->texPixels)
|
|
||||||
{
|
|
||||||
lumpFile.Write16(floatToHalf(clamp(pixel.r, 0.0f, 65000.0f)));
|
|
||||||
lumpFile.Write16(floatToHalf(clamp(pixel.g, 0.0f, 65000.0f)));
|
|
||||||
lumpFile.Write16(floatToHalf(clamp(pixel.b, 0.0f, 65000.0f)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,45 +172,32 @@ void DoomLevelMesh::AddLightmapLump(FWadWriter& wadFile)
|
||||||
{
|
{
|
||||||
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
DoomLevelMeshSurface* surface = &submesh->Surfaces[i];
|
||||||
|
|
||||||
if (surface->atlasPageIndex == -1)
|
if (surface->AtlasTile.ArrayIndex == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
printf("Surface %llu contains %llu UVs\n", i, surface->verts.size());
|
printf("Surface %u contains %u UVs\n", i, surface->numVerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// as of V2 LIGHTMAP version: internal lightmapper uses ZDRay order triangle strips in its internal representation. It will convert from triangle strips to triangle fan on its own.
|
// as of V2 LIGHTMAP version: internal lightmapper uses ZDRay order triangle strips in its internal representation. It will convert from triangle strips to triangle fan on its own.
|
||||||
|
|
||||||
int count = surface->verts.size();
|
float offsetU = surface->AtlasTile.X / (float)submesh->LMTextureSize;
|
||||||
if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
|
float offsetV = surface->AtlasTile.Y / (float)submesh->LMTextureSize;
|
||||||
|
float scaleU = surface->AtlasTile.Width / (float)submesh->LMTextureSize;
|
||||||
|
float scaleV = surface->AtlasTile.Height / (float)submesh->LMTextureSize;
|
||||||
|
FVector2* texcoords = (FVector2*)surface->TexCoords;
|
||||||
|
for (int j = 0, count = surface->numVerts; j < count; j++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < count; j++)
|
lumpFile.WriteFloat((texcoords[j].X - offsetU) * scaleU);
|
||||||
{
|
lumpFile.WriteFloat((texcoords[j].Y - offsetV) * scaleV);
|
||||||
lumpFile.WriteFloat(surface->lightUV[j].x);
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[j].y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[0].x);
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[0].y);
|
|
||||||
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[1].x);
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[1].y);
|
|
||||||
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[2].x);
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[2].y);
|
|
||||||
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[3].x);
|
|
||||||
lumpFile.WriteFloat(surface->lightUV[3].y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress and store in lump
|
// Compress and store in lump
|
||||||
ZLibOut zout(wadFile);
|
ZLibOut zout(wadFile);
|
||||||
wadFile.StartWritingLump("LIGHTMAP");
|
wadFile.StartWritingLump("LIGHTMAP");
|
||||||
zout.Write(buffer.data(), lumpFile.BufferAt() - lumpFile.Buffer());
|
zout.Write(buffer.data(), (int)(ptrdiff_t)(lumpFile.BufferAt() - lumpFile.Buffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1150,12 +1136,10 @@ void DoomLevelSubmesh::DumpMesh(const FString& objFilename, const FString& mtlFi
|
||||||
fprintf(f, "v %f %f %f\n", v.X * scale, v.Z * scale, -v.Y * scale);
|
fprintf(f, "v %f %f %f\n", v.X * scale, v.Z * scale, -v.Y * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
for (const auto& uv : LightmapUvs)
|
for (const auto& uv : LightmapUvs)
|
||||||
{
|
{
|
||||||
fprintf(f, "vt %f %f\n", uv.X, uv.Y);
|
fprintf(f, "vt %f %f\n", uv.X, uv.Y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto name = [](DoomLevelMeshSurfaceType type) -> const char* {
|
auto name = [](DoomLevelMeshSurfaceType type) -> const char* {
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) override;
|
int AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLight* list, int listMaxSize) override;
|
||||||
void DumpMesh(const FString& objFilename, const FString& mtlFilename) const;
|
void DumpMesh(const FString& objFilename, const FString& mtlFilename) const;
|
||||||
|
|
||||||
void AddLightmapLump(FWadWriter& out);
|
void AddLightmapLump(FLevel& doomMap, FWadWriter& out);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DoomLevelMeshSurfaceType
|
enum DoomLevelMeshSurfaceType
|
||||||
|
@ -55,7 +55,6 @@ public:
|
||||||
void BindLightmapSurfacesToGeometry(FLevel& doomMap);
|
void BindLightmapSurfacesToGeometry(FLevel& doomMap);
|
||||||
void PackLightmapAtlas(int lightmapStartIndex);
|
void PackLightmapAtlas(int lightmapStartIndex);
|
||||||
void CreatePortals(FLevel& doomMap);
|
void CreatePortals(FLevel& doomMap);
|
||||||
void DisableLightmaps() { Surfaces.Clear(); } // Temp hack that disables lightmapping
|
|
||||||
|
|
||||||
TArray<DoomLevelMeshSurface> Surfaces;
|
TArray<DoomLevelMeshSurface> Surfaces;
|
||||||
TArray<FVector2> LightmapUvs;
|
TArray<FVector2> LightmapUvs;
|
||||||
|
|
|
@ -39,8 +39,9 @@ void GPURaytracer::Raytrace(DoomLevelMesh* mesh)
|
||||||
{
|
{
|
||||||
auto raytrace = mDevice->GetRaytrace();
|
auto raytrace = mDevice->GetRaytrace();
|
||||||
auto lightmap = mDevice->GetLightmap();
|
auto lightmap = mDevice->GetLightmap();
|
||||||
|
auto submesh = mesh->StaticMesh.get();
|
||||||
|
|
||||||
// mDevice->GetTextureManager()->CreateLightmap(mesh->LMTextureSize, mesh->LMTextureCount);
|
mDevice->GetTextureManager()->CreateLightmap(submesh->LMTextureSize, submesh->LMTextureCount);
|
||||||
|
|
||||||
printf(".");
|
printf(".");
|
||||||
raytrace->SetLevelMesh(mesh);
|
raytrace->SetLevelMesh(mesh);
|
||||||
|
@ -49,16 +50,15 @@ void GPURaytracer::Raytrace(DoomLevelMesh* mesh)
|
||||||
lightmap->BeginFrame();
|
lightmap->BeginFrame();
|
||||||
|
|
||||||
printf(".");
|
printf(".");
|
||||||
// lightmap->Raytrace(surfaces);
|
//lightmap->Raytrace(surfaces);
|
||||||
|
|
||||||
printf(".");
|
printf(".");
|
||||||
/*
|
|
||||||
TArray<uint16_t> buffer;
|
submesh->LMTextureData.Resize(submesh->LMTextureSize * submesh->LMTextureSize * submesh->LMTextureCount * 4);
|
||||||
for (int arrayIndex = 0; arrayIndex < mesh->LMTextureCount; arrayIndex++)
|
for (int arrayIndex = 0; arrayIndex < submesh->LMTextureCount; arrayIndex++)
|
||||||
{
|
{
|
||||||
mDevice->GetTextureManager()->DownloadLightmap(arrayIndex, buffer);
|
mDevice->GetTextureManager()->DownloadLightmap(arrayIndex, submesh->LMTextureData.Data() + arrayIndex * submesh->LMTextureSize * submesh->LMTextureSize * 4);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,10 +116,9 @@ void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCoun
|
||||||
.Execute(fb->GetCommands()->GetTransferCommands(), 0, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
.Execute(fb->GetCommands()->GetTransferCommands(), 0, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkTextureManager::DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer)
|
void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer)
|
||||||
{
|
{
|
||||||
unsigned int totalSize = LMTextureSize * LMTextureSize;
|
unsigned int totalSize = LMTextureSize * LMTextureSize * 4;
|
||||||
buffer.Resize(totalSize);
|
|
||||||
|
|
||||||
auto stagingBuffer = BufferBuilder()
|
auto stagingBuffer = BufferBuilder()
|
||||||
.Size(totalSize * sizeof(uint16_t))
|
.Size(totalSize * sizeof(uint16_t))
|
||||||
|
@ -150,7 +149,7 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer
|
||||||
fb->GetCommands()->SubmitAndWait();
|
fb->GetCommands()->SubmitAndWait();
|
||||||
|
|
||||||
uint16_t* srcdata = (uint16_t*)stagingBuffer->Map(0, totalSize * sizeof(uint16_t));
|
uint16_t* srcdata = (uint16_t*)stagingBuffer->Map(0, totalSize * sizeof(uint16_t));
|
||||||
memcpy(buffer.Data(), srcdata, totalSize * sizeof(uint16_t));
|
memcpy(buffer, srcdata, totalSize * sizeof(uint16_t));
|
||||||
stagingBuffer->Unmap();
|
stagingBuffer->Unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ public:
|
||||||
VkTextureManager(VulkanRenderDevice* fb);
|
VkTextureManager(VulkanRenderDevice* fb);
|
||||||
|
|
||||||
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
||||||
void DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer);
|
void DownloadLightmap(int arrayIndex, uint16_t* buffer);
|
||||||
|
|
||||||
VkTextureImage Lightmap;
|
VkTextureImage Lightmap;
|
||||||
int LMTextureSize = 0;
|
int LMTextureSize = 0;
|
||||||
|
|
Loading…
Reference in a new issue