mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-21 19:50:54 +00:00
Hook up texture loading
This commit is contained in:
parent
e1fe4658b5
commit
a6e4290431
9 changed files with 220 additions and 30 deletions
|
@ -59,6 +59,7 @@ class FolderFileSystemSource : public IFileSystemSource
|
||||||
public:
|
public:
|
||||||
FolderFileSystemSource(const FString& foldername)
|
FolderFileSystemSource(const FString& foldername)
|
||||||
{
|
{
|
||||||
|
Basepath = foldername;
|
||||||
ScanFolder(foldername.GetChars());
|
ScanFolder(foldername.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,15 +70,15 @@ public:
|
||||||
|
|
||||||
int CheckNumForFullName(const FString& fullname) override
|
int CheckNumForFullName(const FString& fullname) override
|
||||||
{
|
{
|
||||||
auto it = FilenameKeyToIndex.find(fullname.GetChars());
|
auto it = FullnameKeyToIndex.find(ToFullnameKey(fullname.GetChars()));
|
||||||
if (it == FilenameKeyToIndex.end())
|
if (it == FullnameKeyToIndex.end())
|
||||||
return -1;
|
return -1;
|
||||||
return (int)it->second;
|
return (int)it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileLength(int lump) override
|
int FileLength(int lump) override
|
||||||
{
|
{
|
||||||
int64_t size = File::open_existing(Filenames[lump])->size();
|
int64_t size = File::open_existing(FilePath::combine(Basepath, Filenames[lump]))->size();
|
||||||
// For safety. The filesystem API clearly wasn't designed to handle large files.
|
// For safety. The filesystem API clearly wasn't designed to handle large files.
|
||||||
if (size >= 0x7fffffff) throw std::runtime_error("File is too big");
|
if (size >= 0x7fffffff) throw std::runtime_error("File is too big");
|
||||||
return (int)size;
|
return (int)size;
|
||||||
|
@ -86,7 +87,7 @@ public:
|
||||||
FileData ReadFile(int lump) override
|
FileData ReadFile(int lump) override
|
||||||
{
|
{
|
||||||
FileData data;
|
FileData data;
|
||||||
data.Buffer = File::read_all_bytes(Filenames[lump]);
|
data.Buffer = File::read_all_bytes(FilePath::combine(Basepath, Filenames[lump]));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,26 +96,40 @@ public:
|
||||||
return Filenames[lump].c_str();
|
return Filenames[lump].c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScanFolder(const std::string& foldername, int depth = 0)
|
static std::string ToFullnameKey(std::string name)
|
||||||
{
|
{
|
||||||
for (const std::string& filename : Directory::files(foldername))
|
for (char& c : name)
|
||||||
{
|
{
|
||||||
std::string fullname = FilePath::combine(foldername, filename);
|
if (c == '\\')
|
||||||
FilenameKeyToIndex[fullname] = Filenames.size();
|
c = '/';
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
c = c - 'A' + 'a';
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScanFolder(const std::string& foldername, const std::string& relativefoldername = {}, int depth = 0)
|
||||||
|
{
|
||||||
|
std::string search = FilePath::combine(foldername, "*");
|
||||||
|
for (const std::string& filename : Directory::files(search))
|
||||||
|
{
|
||||||
|
std::string fullname = FilePath::combine(relativefoldername, filename);
|
||||||
|
FullnameKeyToIndex[ToFullnameKey(fullname)] = Filenames.size();
|
||||||
Filenames.push_back(fullname);
|
Filenames.push_back(fullname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth < 16)
|
if (depth < 16)
|
||||||
{
|
{
|
||||||
for (const std::string& subfolder : Directory::folders(foldername))
|
for (const std::string& subfolder : Directory::folders(search))
|
||||||
{
|
{
|
||||||
ScanFolder(FilePath::combine(foldername, subfolder), depth + 1);
|
ScanFolder(FilePath::combine(foldername, subfolder), FilePath::combine(relativefoldername, subfolder), depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Basepath;
|
||||||
std::vector<std::string> Filenames;
|
std::vector<std::string> Filenames;
|
||||||
std::map<std::string, size_t> FilenameKeyToIndex;
|
std::map<std::string, size_t> FullnameKeyToIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -7,7 +7,15 @@ FTextureManager TexMan;
|
||||||
|
|
||||||
FGameTexture::FGameTexture(FString name) : Name(name)
|
FGameTexture::FGameTexture(FString name) : Name(name)
|
||||||
{
|
{
|
||||||
|
// To do: improve this to support subfolders?
|
||||||
|
// To do: figure out what type of data we got here instead of assuming it is a png.
|
||||||
|
|
||||||
int lump = fileSystem.CheckNumForFullName(name);
|
int lump = fileSystem.CheckNumForFullName(name);
|
||||||
|
if (lump < 0)
|
||||||
|
lump = fileSystem.CheckNumForFullName("textures/" + name + ".png");
|
||||||
|
if (lump < 0)
|
||||||
|
lump = fileSystem.CheckNumForFullName("flats/" + name + ".png");
|
||||||
|
|
||||||
if (lump < 0)
|
if (lump < 0)
|
||||||
{
|
{
|
||||||
// Not found - should we mark it as invalid or use a dummy texture?
|
// Not found - should we mark it as invalid or use a dummy texture?
|
||||||
|
@ -16,8 +24,6 @@ FGameTexture::FGameTexture(FString name) : Name(name)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// To do: figure out what type of data we got here instead of assuming it is a png.
|
|
||||||
|
|
||||||
FileData filedata = fileSystem.ReadFile(lump);
|
FileData filedata = fileSystem.ReadFile(lump);
|
||||||
int result = decodePNG(Pixels, Width, Height, (const unsigned char*)filedata.GetMem(), fileSystem.FileLength(lump), true);
|
int result = decodePNG(Pixels, Width, Height, (const unsigned char*)filedata.GetMem(), fileSystem.FileLength(lump), true);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
|
|
|
@ -81,17 +81,26 @@ public:
|
||||||
bool isValid() const { return Valid; }
|
bool isValid() const { return Valid; }
|
||||||
float GetDisplayWidth() const { return DisplayWidth; }
|
float GetDisplayWidth() const { return DisplayWidth; }
|
||||||
float GetDisplayHeight() const { return DisplayHeight; }
|
float GetDisplayHeight() const { return DisplayHeight; }
|
||||||
|
|
||||||
|
float GetScaleX() const { return ScaleX; }
|
||||||
float GetScaleY() const { return ScaleY; }
|
float GetScaleY() const { return ScaleY; }
|
||||||
|
|
||||||
const void* GetImagePixels() const { return Pixels.data(); }
|
const void* GetImagePixels() const { return Pixels.data(); }
|
||||||
int GetImageWidth() const { return Width; }
|
int GetImageWidth() const { return Width; }
|
||||||
int GetImageHeight() const { return Height; }
|
int GetImageHeight() const { return Height; }
|
||||||
|
|
||||||
|
int GetTexelWidth() const { return GetImageWidth(); }
|
||||||
|
int GetTexelHeight() const { return GetImageHeight(); }
|
||||||
|
|
||||||
|
bool isHardwareCanvas() const { return false; }
|
||||||
|
bool useWorldPanning() const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FString Name;
|
FString Name;
|
||||||
bool Valid = true;
|
bool Valid = true;
|
||||||
float DisplayWidth = 0.0f;
|
float DisplayWidth = 0.0f;
|
||||||
float DisplayHeight = 0.0f;
|
float DisplayHeight = 0.0f;
|
||||||
|
float ScaleX = 1.0f;
|
||||||
float ScaleY = 1.0f;
|
float ScaleY = 1.0f;
|
||||||
|
|
||||||
std::vector<unsigned char> Pixels;
|
std::vector<unsigned char> Pixels;
|
||||||
|
|
|
@ -105,6 +105,9 @@ struct IntSideDef
|
||||||
return TexMan.CheckForTexture(names[(int)part], ETextureType::Wall);
|
return TexMan.CheckForTexture(names[(int)part], ETextureType::Wall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GetTextureXOffset(WallPart part) { return 0.0f; }
|
||||||
|
float GetTextureXScale(WallPart part) { return 1.0f; }
|
||||||
|
|
||||||
float GetTextureYOffset(WallPart part) { return 0.0f; }
|
float GetTextureYOffset(WallPart part) { return 0.0f; }
|
||||||
float GetTextureYScale(WallPart part) { return 1.0f; }
|
float GetTextureYScale(WallPart part) { return 1.0f; }
|
||||||
|
|
||||||
|
@ -115,6 +118,16 @@ struct IntSideDef
|
||||||
|
|
||||||
FVector2 V1(const FLevel& level) const;
|
FVector2 V1(const FLevel& level) const;
|
||||||
FVector2 V2(const FLevel& level) const;
|
FVector2 V2(const FLevel& level) const;
|
||||||
|
|
||||||
|
float GetTexelLength(const FLevel& level) const
|
||||||
|
{
|
||||||
|
FVector2 v1 = V1(level);
|
||||||
|
FVector2 v2 = V2(level);
|
||||||
|
double dx = v2.X - v1.X;
|
||||||
|
double dy = v2.Y - v1.Y;
|
||||||
|
int len = (int)(g_sqrt(dx * dx + dy * dy) + 0.5f);
|
||||||
|
return (float)len;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapLineDef
|
struct MapLineDef
|
||||||
|
|
|
@ -316,7 +316,7 @@ void DoomLevelMesh::CreateLineHorizonSurface(FLevel& doomMap, IntSideDef* side)
|
||||||
verts[3].z = v2Top;
|
verts[3].z = v2Top;
|
||||||
AddWallVertices(surf, verts);
|
AddWallVertices(surf, verts);
|
||||||
|
|
||||||
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ void DoomLevelMesh::CreateFrontWallSurface(FLevel& doomMap, IntSideDef* side)
|
||||||
surf.Texture = side->GetTexture(WallPart::MIDDLE);
|
surf.Texture = side->GetTexture(WallPart::MIDDLE);
|
||||||
AddWallVertices(surf, verts);
|
AddWallVertices(surf, verts);
|
||||||
|
|
||||||
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
||||||
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
|
@ -433,7 +433,7 @@ void DoomLevelMesh::CreateMidWallSurface(FLevel& doomMap, IntSideDef* side)
|
||||||
surf.Plane.W = -surf.Plane.W;
|
surf.Plane.W = -surf.Plane.W;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSideTextureUVs(surf, side, WallPart::TOP, verts[2].z, verts[0].z, verts[3].z, verts[1].z);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::TOP, verts[2].z, verts[0].z, verts[3].z, verts[1].z);
|
||||||
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
|
@ -495,7 +495,7 @@ void DoomLevelMesh::Create3DFloorWallSurfaces(FLevel& doomMap, IntSideDef* side)
|
||||||
surf.Texture = xfloor->Line->sidedef[0]->GetTexture(WallPart::MIDDLE);
|
surf.Texture = xfloor->Line->sidedef[0]->GetTexture(WallPart::MIDDLE);
|
||||||
|
|
||||||
AddWallVertices(surf, verts);
|
AddWallVertices(surf, verts);
|
||||||
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::TOP, v1Top, v1Bottom, v2Top, v2Bottom);
|
||||||
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::MIDDLE));
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
|
@ -539,7 +539,7 @@ void DoomLevelMesh::CreateTopWallSurface(FLevel& doomMap, IntSideDef* side)
|
||||||
surf.Texture = side->GetTexture(WallPart::TOP);
|
surf.Texture = side->GetTexture(WallPart::TOP);
|
||||||
|
|
||||||
AddWallVertices(surf, verts);
|
AddWallVertices(surf, verts);
|
||||||
SetSideTextureUVs(surf, side, WallPart::TOP, v1Top, v1TopBack, v2Top, v2TopBack);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::TOP, v1Top, v1TopBack, v2Top, v2TopBack);
|
||||||
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::TOP));
|
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::TOP));
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
|
@ -581,17 +581,97 @@ void DoomLevelMesh::CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side)
|
||||||
surf.Texture = side->GetTexture(WallPart::BOTTOM);
|
surf.Texture = side->GetTexture(WallPart::BOTTOM);
|
||||||
|
|
||||||
AddWallVertices(surf, verts);
|
AddWallVertices(surf, verts);
|
||||||
SetSideTextureUVs(surf, side, WallPart::BOTTOM, v1BottomBack, v1Bottom, v2BottomBack, v2Bottom);
|
SetSideTextureUVs(doomMap, surf, side, WallPart::BOTTOM, v1BottomBack, v1Bottom, v2BottomBack, v2Bottom);
|
||||||
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::BOTTOM));
|
AddSurfaceToTile(surf, doomMap, side->GetSampleDistance(WallPart::BOTTOM));
|
||||||
|
|
||||||
Surfaces.Push(surf);
|
Surfaces.Push(surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoomLevelMesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ)
|
struct FTexCoordInfo
|
||||||
|
{
|
||||||
|
int mRenderWidth;
|
||||||
|
int mRenderHeight;
|
||||||
|
int mWidth;
|
||||||
|
FVector2 mScale;
|
||||||
|
FVector2 mTempScale;
|
||||||
|
bool mWorldPanning;
|
||||||
|
|
||||||
|
float FloatToTexU(float v) const { return v / mRenderWidth; }
|
||||||
|
float FloatToTexV(float v) const { return v / mRenderHeight; }
|
||||||
|
|
||||||
|
float RowOffset(float rowoffset) const
|
||||||
|
{
|
||||||
|
float scale = fabsf(mScale.Y);
|
||||||
|
if (scale == 1.f || mWorldPanning) return rowoffset;
|
||||||
|
else return rowoffset / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextureOffset(float textureoffset) const
|
||||||
|
{
|
||||||
|
float scale = fabsf(mScale.X);
|
||||||
|
if (scale == 1.f || mWorldPanning) return textureoffset;
|
||||||
|
else return textureoffset / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TextureAdjustWidth() const
|
||||||
|
{
|
||||||
|
if (mWorldPanning)
|
||||||
|
{
|
||||||
|
float tscale = fabsf(mTempScale.X);
|
||||||
|
if (tscale == 1.f) return (float)mRenderWidth;
|
||||||
|
else return mWidth / fabsf(tscale);
|
||||||
|
}
|
||||||
|
else return (float)mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning)
|
||||||
|
{
|
||||||
|
if (x == 1.f)
|
||||||
|
{
|
||||||
|
mRenderWidth = xs_RoundToInt(tex->GetDisplayWidth());
|
||||||
|
mScale.X = tex->GetScaleX();
|
||||||
|
mTempScale.X = 1.f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale_x = x * tex->GetScaleX();
|
||||||
|
mRenderWidth = xs_CeilToInt(tex->GetTexelWidth() / scale_x);
|
||||||
|
mScale.X = scale_x;
|
||||||
|
mTempScale.X = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y == 1.f)
|
||||||
|
{
|
||||||
|
mRenderHeight = xs_RoundToInt(tex->GetDisplayHeight());
|
||||||
|
mScale.Y = tex->GetScaleY();
|
||||||
|
mTempScale.Y = 1.f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale_y = y * tex->GetScaleY();
|
||||||
|
mRenderHeight = xs_CeilToInt(tex->GetTexelHeight() / scale_y);
|
||||||
|
mScale.Y = scale_y;
|
||||||
|
mTempScale.Y = y;
|
||||||
|
}
|
||||||
|
if (tex->isHardwareCanvas())
|
||||||
|
{
|
||||||
|
mScale.Y = -mScale.Y;
|
||||||
|
mRenderHeight = -mRenderHeight;
|
||||||
|
}
|
||||||
|
mWorldPanning = tex->useWorldPanning() || forceworldpanning;
|
||||||
|
mWidth = tex->GetTexelWidth();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void GetTexCoordInfo(FGameTexture* tex, FTexCoordInfo* tci, IntSideDef* side, WallPart texpos)
|
||||||
|
{
|
||||||
|
tci->GetFromTexture(tex, (float)side->GetTextureXScale(texpos), (float)side->GetTextureYScale(texpos), false/*!!(side->GetLevel()->flags3 & LEVEL3_FORCEWORLDPANNING)*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoomLevelMesh::SetSideTextureUVs(FLevel& doomMap, DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ)
|
||||||
{
|
{
|
||||||
FFlatVertex* verts = &Mesh.Vertices[surface.MeshLocation.StartVertIndex];
|
FFlatVertex* verts = &Mesh.Vertices[surface.MeshLocation.StartVertIndex];
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (surface.Texture.isValid())
|
if (surface.Texture.isValid())
|
||||||
{
|
{
|
||||||
const auto gtxt = TexMan.GetGameTexture(surface.Texture);
|
const auto gtxt = TexMan.GetGameTexture(surface.Texture);
|
||||||
|
@ -600,7 +680,7 @@ void DoomLevelMesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef*
|
||||||
GetTexCoordInfo(gtxt, &tci, side, texpart);
|
GetTexCoordInfo(gtxt, &tci, side, texpart);
|
||||||
|
|
||||||
float startU = tci.FloatToTexU(tci.TextureOffset((float)side->GetTextureXOffset(texpart)) + tci.TextureOffset((float)side->GetTextureXOffset(texpart)));
|
float startU = tci.FloatToTexU(tci.TextureOffset((float)side->GetTextureXOffset(texpart)) + tci.TextureOffset((float)side->GetTextureXOffset(texpart)));
|
||||||
float endU = startU + tci.FloatToTexU(side->TexelLength);
|
float endU = startU + tci.FloatToTexU(side->GetTexelLength(doomMap));
|
||||||
|
|
||||||
verts[0].u = startU;
|
verts[0].u = startU;
|
||||||
verts[1].u = endU;
|
verts[1].u = endU;
|
||||||
|
@ -608,8 +688,8 @@ void DoomLevelMesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef*
|
||||||
verts[3].u = endU;
|
verts[3].u = endU;
|
||||||
|
|
||||||
// To do: the ceiling version is apparently used in some situation related to 3d floors (rover->top.isceiling)
|
// To do: the ceiling version is apparently used in some situation related to 3d floors (rover->top.isceiling)
|
||||||
//float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(PLANE_CEILING);
|
//float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)doomMap.Sectors[side->sector].ceilingTexZ;
|
||||||
float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(PLANE_FLOOR);
|
float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)doomMap.Sectors[side->sector].floorTexZ;
|
||||||
|
|
||||||
verts[0].v = tci.FloatToTexV(offset - v1BottomZ);
|
verts[0].v = tci.FloatToTexV(offset - v1BottomZ);
|
||||||
verts[1].v = tci.FloatToTexV(offset - v2BottomZ);
|
verts[1].v = tci.FloatToTexV(offset - v2BottomZ);
|
||||||
|
@ -617,7 +697,6 @@ void DoomLevelMesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef*
|
||||||
verts[3].v = tci.FloatToTexV(offset - v2TopZ);
|
verts[3].v = tci.FloatToTexV(offset - v2TopZ);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,7 +83,7 @@ private:
|
||||||
void CreateTopWallSurface(FLevel& doomMap, IntSideDef* side);
|
void CreateTopWallSurface(FLevel& doomMap, IntSideDef* side);
|
||||||
void CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side);
|
void CreateBottomWallSurface(FLevel& doomMap, IntSideDef* side);
|
||||||
void AddWallVertices(DoomLevelMeshSurface& surf, FFlatVertex* verts);
|
void AddWallVertices(DoomLevelMeshSurface& surf, FFlatVertex* verts);
|
||||||
void SetSideTextureUVs(DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ);
|
void SetSideTextureUVs(FLevel& doomMap, DoomLevelMeshSurface& surface, IntSideDef* side, WallPart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ);
|
||||||
|
|
||||||
void CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, X3DFloor* controlSector, int typeIndex);
|
void CreateFloorSurface(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, X3DFloor* controlSector, int typeIndex);
|
||||||
void CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, X3DFloor* controlSector, int typeIndex);
|
void CreateCeilingSurface(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, X3DFloor* controlSector, int typeIndex);
|
||||||
|
|
|
@ -102,10 +102,17 @@ int VulkanRenderDevice::GetBindlessTextureIndex(FTextureID textureID)
|
||||||
if (textureIndex != 0)
|
if (textureIndex != 0)
|
||||||
return textureIndex;
|
return textureIndex;
|
||||||
|
|
||||||
// To do: upload image
|
VulkanImageView* view;
|
||||||
|
|
||||||
VulkanImageView* view = GetTextureManager()->GetNullTextureView();
|
|
||||||
VulkanSampler* sampler = GetSamplerManager()->Get();
|
VulkanSampler* sampler = GetSamplerManager()->Get();
|
||||||
|
if (tex->GetImageWidth() > 0 && tex->GetImageHeight() > 0)
|
||||||
|
{
|
||||||
|
int index = GetTextureManager()->CreateGameTexture(tex->GetImageWidth(), tex->GetImageHeight(), tex->GetImagePixels());
|
||||||
|
view = GetTextureManager()->GetGameTextureView(index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
view = GetTextureManager()->GetNullTextureView();
|
||||||
|
}
|
||||||
|
|
||||||
textureIndex = GetDescriptorSetManager()->AddBindlessTextureIndex(view, sampler);
|
textureIndex = GetDescriptorSetManager()->AddBindlessTextureIndex(view, sampler);
|
||||||
return textureIndex;
|
return textureIndex;
|
||||||
|
@ -477,6 +484,56 @@ void VkTextureManager::CreateNullTexture()
|
||||||
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VkTextureManager::CreateGameTexture(int width, int height, const void* pixels)
|
||||||
|
{
|
||||||
|
int index = (int)GameTextures.size();
|
||||||
|
|
||||||
|
auto texture = ImageBuilder()
|
||||||
|
.Format(VK_FORMAT_R8G8B8A8_UNORM)
|
||||||
|
.Size(width, height)
|
||||||
|
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||||
|
.DebugName("VkTextureManager.GameTexture")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
auto textureView = ImageViewBuilder()
|
||||||
|
.Image(texture.get(), VK_FORMAT_R8G8B8A8_UNORM)
|
||||||
|
.DebugName("VkTextureManager.GameTextureView")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
auto stagingBuffer = BufferBuilder()
|
||||||
|
.Size(width * height * sizeof(uint32_t))
|
||||||
|
.Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||||
|
.DebugName("VkTextureManager.GameTextureStaging")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
uint32_t* data = (uint32_t*)stagingBuffer->Map(0, width * height * sizeof(uint32_t));
|
||||||
|
memcpy(data, pixels, width * height * sizeof(uint32_t));
|
||||||
|
stagingBuffer->Unmap();
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(texture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
|
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {};
|
||||||
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
region.imageSubresource.layerCount = 1;
|
||||||
|
region.imageExtent.depth = 1;
|
||||||
|
region.imageExtent.width = width;
|
||||||
|
region.imageExtent.height = height;
|
||||||
|
fb->GetCommands()->GetTransferCommands()->copyBufferToImage(stagingBuffer->buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
|
fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer));
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(texture.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
|
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
|
GameTextures.push_back(std::move(texture));
|
||||||
|
GameTextureViews.push_back(std::move(textureView));
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount)
|
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount)
|
||||||
{
|
{
|
||||||
if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount + 1)
|
if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount + 1)
|
||||||
|
@ -548,7 +605,7 @@ VkSamplerManager::VkSamplerManager(VulkanRenderDevice* fb) : fb(fb)
|
||||||
Sampler = SamplerBuilder()
|
Sampler = SamplerBuilder()
|
||||||
.MagFilter(VK_FILTER_NEAREST)
|
.MagFilter(VK_FILTER_NEAREST)
|
||||||
.MinFilter(VK_FILTER_NEAREST)
|
.MinFilter(VK_FILTER_NEAREST)
|
||||||
.AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT)
|
.AddressMode(VK_SAMPLER_ADDRESS_MODE_REPEAT/*VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE*/, VK_SAMPLER_ADDRESS_MODE_REPEAT/*VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE*/, VK_SAMPLER_ADDRESS_MODE_REPEAT)
|
||||||
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
|
.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
|
||||||
.MaxLod(0.25f)
|
.MaxLod(0.25f)
|
||||||
.DebugName("VkSamplerManager.Sampler")
|
.DebugName("VkSamplerManager.Sampler")
|
||||||
|
|
|
@ -166,6 +166,11 @@ public:
|
||||||
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
||||||
void DownloadLightmap(int arrayIndex, uint16_t* buffer);
|
void DownloadLightmap(int arrayIndex, uint16_t* buffer);
|
||||||
|
|
||||||
|
int CreateGameTexture(int width, int height, const void* pixels);
|
||||||
|
|
||||||
|
VulkanImage* GetGameTexture(int index) { return GameTextures[index].get(); }
|
||||||
|
VulkanImageView* GetGameTextureView(int index) { return GameTextureViews[index].get(); }
|
||||||
|
|
||||||
VulkanImage* GetNullTexture() { return NullTexture.get(); }
|
VulkanImage* GetNullTexture() { return NullTexture.get(); }
|
||||||
VulkanImageView* GetNullTextureView() { return NullTextureView.get(); }
|
VulkanImageView* GetNullTextureView() { return NullTextureView.get(); }
|
||||||
|
|
||||||
|
@ -180,6 +185,9 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<VulkanImage> NullTexture;
|
std::unique_ptr<VulkanImage> NullTexture;
|
||||||
std::unique_ptr<VulkanImageView> NullTextureView;
|
std::unique_ptr<VulkanImageView> NullTextureView;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<VulkanImage>> GameTextures;
|
||||||
|
std::vector<std::unique_ptr<VulkanImageView>> GameTextureViews;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VkSamplerManager
|
class VkSamplerManager
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "framework/zdray.h"
|
#include "framework/zdray.h"
|
||||||
|
#include "framework/filesystem.h"
|
||||||
#include "wad/wad.h"
|
#include "wad/wad.h"
|
||||||
#include "level/level.h"
|
#include "level/level.h"
|
||||||
#include "commandline/getopt.h"
|
#include "commandline/getopt.h"
|
||||||
|
@ -233,6 +234,8 @@ int main(int argc, char **argv)
|
||||||
fixSame = true;
|
fixSame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileSystem.AddFolderSource("C:\\Development\\VkDoom\\build\\RelWithDebInfo\\ElderJamReignited");
|
||||||
|
|
||||||
{
|
{
|
||||||
FWadReader inwad(InName);
|
FWadReader inwad(InName);
|
||||||
FWadWriter outwad(OutName, inwad.IsIWAD());
|
FWadWriter outwad(OutName, inwad.IsIWAD());
|
||||||
|
|
Loading…
Reference in a new issue