diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index e02f5468d..572f57443 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -18,6 +18,7 @@ typedef dp::rect_pack::RectPacker RectPacker; class LevelSubmesh; class FMaterial; +class FGameTexture; class LevelMeshLight { @@ -58,7 +59,7 @@ struct LevelMeshSurface bool NeedsUpdate = true; bool AlwaysUpdate = false; - FTextureID texture = FNullTextureID(); + FGameTexture* texture = nullptr; float alpha = 1.0; int portalIndex = 0; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index d1f3ed33e..d75440c2d 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -305,9 +305,9 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) info.SamplingDistance = (float)surface->sampleDimension; info.Sky = surface->bSky; info.Alpha = surface->alpha; - if (surface->texture.isValid()) + if (surface->texture) { - auto mat = FMaterial::ValidateTexture(TexMan.GetGameTexture(surface->texture), 0); + auto mat = FMaterial::ValidateTexture(surface->texture, 0); info.TextureIndex = fb->GetBindlessTextureIndex(mat, CLAMP_NONE, 0); } else diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index a2070e2a7..b34349f45 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -82,7 +82,7 @@ void PrintSurfaceInfo(const DoomLevelMeshSurface* surface) { if (!RequireLevelMesh()) return; - auto gameTexture = TexMan.GameByIndex(surface->texture.GetIndex()); + auto gameTexture = surface->texture; Printf("Surface %d (%p)\n Type: %d, TypeIndex: %d, ControlSector: %d\n", surface->Submesh->GetSurfaceIndex(surface), surface, surface->Type, surface->TypeIndex, surface->ControlSector ? surface->ControlSector->Index() : -1); Printf(" Atlas page: %d, x:%d, y:%d\n", surface->AtlasTile.ArrayIndex, surface->AtlasTile.X, surface->AtlasTile.Y); @@ -91,7 +91,7 @@ void PrintSurfaceInfo(const DoomLevelMeshSurface* surface) Printf(" Needs update?: %d\n", surface->NeedsUpdate); Printf(" Always update?: %d\n", surface->AlwaysUpdate); Printf(" Sector group: %d\n", surface->sectorGroup); - Printf(" Texture: '%s' (id=%d)\n", gameTexture ? gameTexture->GetName().GetChars() : "", surface->texture.GetIndex()); + Printf(" Texture: '%s'\n", gameTexture ? gameTexture->GetName().GetChars() : ""); Printf(" Alpha: %f\n", surface->alpha); } diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.cpp b/src/rendering/hwrenderer/doom_levelsubmesh.cpp index c20e3eb83..202730372 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelsubmesh.cpp @@ -30,7 +30,6 @@ void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) CreateStaticSurfaces(doomMap); LinkSurfaces(doomMap); - ProcessStaticSurfaces(doomMap); CreateIndexes(); SetupLightmapUvs(doomMap); @@ -51,7 +50,6 @@ void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap, int lightmapStartInd CreateDynamicSurfaces(doomMap); LinkSurfaces(doomMap); - ProcessStaticSurfaces(doomMap); CreateIndexes(); SetupLightmapUvs(doomMap); @@ -74,149 +72,6 @@ void DoomLevelSubmesh::Reset() } void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) -{ - // Create surface objects for all visible side parts - for (unsigned int i = 0; i < doomMap.sides.Size(); i++) - { - bool isPolyLine = !!(doomMap.sides[i].Flags & WALLF_POLYOBJ); - if (!isPolyLine) - { - // To do: it would be nice if HWWall could figure this out for us. - - side_t* side = &doomMap.sides[i]; - - sector_t* front = side->sector; - sector_t* back = (side->linedef->frontsector == front) ? side->linedef->backsector : side->linedef->frontsector; - - FVector2 v1 = ToFVector2(side->V1()->fPos()); - FVector2 v2 = ToFVector2(side->V2()->fPos()); - - float v1Top = (float)front->ceilingplane.ZatPoint(v1); - float v1Bottom = (float)front->floorplane.ZatPoint(v1); - float v2Top = (float)front->ceilingplane.ZatPoint(v2); - float v2Bottom = (float)front->floorplane.ZatPoint(v2); - - DoomLevelMeshSurface surf; - surf.Submesh = this; - surf.TypeIndex = side->Index(); - surf.Side = side; - surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); - surf.sectorGroup = sectorGroup[front->Index()]; - - if (side->linedef->getPortal() && side->linedef->frontsector == front) // line portal - { - surf.Type = ST_MIDDLESIDE; - surf.bSky = front->GetTexture(sector_t::floor) == skyflatnum || front->GetTexture(sector_t::ceiling) == skyflatnum; - surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - //surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); - Surfaces.Push(surf); - } - else if (side->linedef->special == Line_Horizon && front != back) // line horizon - { - surf.Type = ST_MIDDLESIDE; - surf.bSky = front->GetTexture(sector_t::floor) == skyflatnum || front->GetTexture(sector_t::ceiling) == skyflatnum; - surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - //surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); - Surfaces.Push(surf); - } - else if (!back) // front wall - { - surf.Type = ST_MIDDLESIDE; - surf.bSky = false; - surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - surf.texture = side->textures[side_t::mid].texture; - Surfaces.Push(surf); - } - else - { - if (side->textures[side_t::mid].texture.isValid()) // mid wall - { - surf.Type = ST_MIDDLESIDE; - surf.bSky = false; - surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - surf.texture = side->textures[side_t::mid].texture; - surf.alpha = float(side->linedef->alpha); - Surfaces.Push(surf); - surf.alpha = 1.0f; - } - - float v1TopBack = (float)back->ceilingplane.ZatPoint(v1); - float v1BottomBack = (float)back->floorplane.ZatPoint(v1); - float v2TopBack = (float)back->ceilingplane.ZatPoint(v2); - float v2BottomBack = (float)back->floorplane.ZatPoint(v2); - - if (v1Bottom < v1BottomBack || v2Bottom < v2BottomBack) // lower wall - { - surf.Type = ST_LOWERSIDE; - surf.bSky = false; - surf.sampleDimension = side->textures[side_t::bottom].LightmapSampleDistance; - surf.texture = side->textures[side_t::bottom].texture; - Surfaces.Push(surf); - } - - if (v1Top > v1TopBack || v2Top > v2TopBack) // top wall - { - bool bSky = IsTopSideSky(front, back, side); - //if (bSky || IsTopSideVisible(side)) - { - surf.Type = ST_UPPERSIDE; - surf.bSky = bSky; - surf.sampleDimension = side->textures[side_t::top].LightmapSampleDistance; - surf.texture = side->textures[side_t::top].texture; - Surfaces.Push(surf); - } - } - - for (unsigned int j = 0; j < front->e->XFloor.ffloors.Size(); j++) - { - F3DFloor* xfloor = front->e->XFloor.ffloors[j]; - - // Don't create a line when both sectors have the same 3d floor - bool bothSides = false; - for (unsigned int k = 0; k < back->e->XFloor.ffloors.Size(); k++) - { - if (back->e->XFloor.ffloors[k] == xfloor) - { - bothSides = true; - break; - } - } - if (bothSides) - continue; - - surf.Type = ST_MIDDLESIDE; - surf.ControlSector = xfloor->model; - surf.bSky = false; - surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - surf.texture = side->textures[side_t::mid].texture; - Surfaces.Push(surf); - } - } - } - } - - // Create surfaces for all flats - for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) - { - subsector_t* sub = &doomMap.subsectors[i]; - if (sub->numlines < 3 || !sub->sector) - continue; - sector_t* sector = sub->sector; - - // To do: only create the surface objects here and then fill them in ProcessStaticSurfaces - - CreateFloorSurface(doomMap, sub, sector, nullptr, i); - CreateCeilingSurface(doomMap, sub, sector, nullptr, i); - - for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++) - { - CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); - CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); - } - } -} - -void DoomLevelSubmesh::ProcessStaticSurfaces(FLevelLocals& doomMap) { // We can't use side->segs since it is null. TArray> sideSegs(doomMap.sides.Size(), true); @@ -232,6 +87,7 @@ void DoomLevelSubmesh::ProcessStaticSurfaces(FLevelLocals& doomMap) } } + // Create surface objects for all visible side parts for (unsigned int i = 0; i < doomMap.sides.Size(); i++) { side_t* side = &doomMap.sides[i]; @@ -263,14 +119,9 @@ void DoomLevelSubmesh::ProcessStaticSurfaces(FLevelLocals& doomMap) for (HWWall& wallpart : result.list) { - DoomLevelMeshSurface* surface = wall.surface; - if (!surface) - continue; - wallpart.DrawWall(&disp, state, false); int startVertIndex = MeshVertices.Size(); - for (auto& it : state.mSortedLists) { const MeshApplyState& applyState = it.first; @@ -288,15 +139,26 @@ void DoomLevelSubmesh::ProcessStaticSurfaces(FLevelLocals& doomMap) } } } - - surface->startVertIndex = startVertIndex; - surface->numVerts = MeshVertices.Size() - startVertIndex; - surface->plane = ToPlane(MeshVertices[startVertIndex].fPos(), MeshVertices[startVertIndex + 1].fPos(), MeshVertices[startVertIndex + 2].fPos(), MeshVertices[startVertIndex + 3].fPos()); - state.mSortedLists.clear(); + + DoomLevelMeshSurface surf; + surf.Submesh = this; + surf.Type = wallpart.LevelMeshInfo.Type; + surf.ControlSector = wallpart.LevelMeshInfo.ControlSector; + surf.TypeIndex = side->Index(); + surf.Side = side; + surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + surf.sectorGroup = sectorGroup[front->Index()]; + surf.alpha = float(side->linedef->alpha); + surf.startVertIndex = startVertIndex; + surf.numVerts = MeshVertices.Size() - startVertIndex; + surf.plane = ToPlane(MeshVertices[startVertIndex].fPos(), MeshVertices[startVertIndex + 1].fPos(), MeshVertices[startVertIndex + 2].fPos(), MeshVertices[startVertIndex + 3].fPos()); + surf.texture = wallpart.texture; + Surfaces.Push(surf); } } + // Create surfaces for all flats for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) { subsector_t* sub = &doomMap.subsectors[i]; @@ -304,9 +166,14 @@ void DoomLevelSubmesh::ProcessStaticSurfaces(FLevelLocals& doomMap) continue; sector_t* sector = sub->sector; - // To do: use HWFlat - // HWFlat flat; - // flat.Process(&disp, state, sector, whichplane, notexture); + CreateFloorSurface(doomMap, sub, sector, nullptr, i); + CreateCeilingSurface(doomMap, sub, sector, nullptr, i); + + for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++) + { + CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); + CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); + } } } @@ -333,10 +200,6 @@ void DoomLevelSubmesh::CreateDynamicSurfaces(FLevelLocals& doomMap) } } -void DoomLevelSubmesh::ProcessDynamicSurfaces(FLevelLocals& doomMap) -{ -} - void DoomLevelSubmesh::CreateIndexes() { for (size_t i = 0; i < Surfaces.Size(); i++) @@ -850,7 +713,7 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; surf.ControlSector = nullptr; surf.sectorGroup = sectorGroup[front->Index()]; - surf.texture = side->textures[side_t::mid].texture; + surf.texture = TexMan.GetGameTexture(side->textures[side_t::mid].texture); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); surf.Side = side; @@ -952,7 +815,7 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; surf.ControlSector = nullptr; surf.sectorGroup = sectorGroup[front->Index()]; - surf.texture = texture; + surf.texture = TexMan.GetGameTexture(texture); surf.alpha = float(side->linedef->alpha); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); surf.Side = side; @@ -1038,7 +901,7 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevelLocals& doomMap, side_t* surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; - surf.texture = side->textures[side_t::mid].texture; + surf.texture = TexMan.GetGameTexture(side->textures[side_t::mid].texture); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); SurfaceUniforms uniforms = DefaultUniforms(); @@ -1103,7 +966,7 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) surf.sampleDimension = side->textures[side_t::top].LightmapSampleDistance; surf.ControlSector = nullptr; surf.sectorGroup = sectorGroup[front->Index()]; - surf.texture = side->textures[side_t::top].texture; + surf.texture = TexMan.GetGameTexture(side->textures[side_t::top].texture); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); surf.Side = side; @@ -1167,7 +1030,7 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si surf.sampleDimension = side->textures[side_t::bottom].LightmapSampleDistance; surf.ControlSector = nullptr; surf.sectorGroup = sectorGroup[front->Index()]; - surf.texture = side->textures[side_t::bottom].texture; + surf.texture = TexMan.GetGameTexture(side->textures[side_t::bottom].texture); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); surf.Side = side; @@ -1187,9 +1050,9 @@ void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, side_t* { FFlatVertex* uvs = &MeshVertices[surface.startVertIndex]; - if (surface.texture.isValid()) + if (surface.texture) { - const auto gtxt = TexMan.GetGameTexture(surface.texture); + const auto gtxt = surface.texture; FTexCoordInfo tci; GetTexCoordInfo(gtxt, &tci, side, texpart); @@ -1244,9 +1107,9 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su surf.numVerts = sub->numlines; surf.startVertIndex = MeshVertices.Size(); - surf.texture = (controlSector ? controlSector : sector)->planes[sector_t::floor].Texture; + surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::floor].Texture); - FGameTexture* txt = TexMan.GetGameTexture(surf.texture); + FGameTexture* txt = surf.texture; float w = txt->GetDisplayWidth(); float h = txt->GetDisplayHeight(); VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor); @@ -1321,9 +1184,9 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* surf.numVerts = sub->numlines; surf.startVertIndex = MeshVertices.Size(); - surf.texture = (controlSector ? controlSector : sector)->planes[sector_t::ceiling].Texture; + surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::ceiling].Texture); - FGameTexture* txt = TexMan.GetGameTexture(surf.texture); + FGameTexture* txt = surf.texture; float w = txt->GetDisplayWidth(); float h = txt->GetDisplayHeight(); VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling); diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.h b/src/rendering/hwrenderer/doom_levelsubmesh.h index 1985d8186..914575ef4 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.h +++ b/src/rendering/hwrenderer/doom_levelsubmesh.h @@ -63,8 +63,6 @@ private: void CreateStaticSurfaces(FLevelLocals& doomMap); void CreateDynamicSurfaces(FLevelLocals& doomMap); - void ProcessStaticSurfaces(FLevelLocals& doomMap); - void ProcessDynamicSurfaces(FLevelLocals& doomMap); void CreateSubsectorSurfaces(FLevelLocals& doomMap); void CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex); diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 42f18eb8b..3b4e68c9b 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -8,6 +8,7 @@ #include "renderstyle.h" #include "textures.h" #include "r_data/colormaps.h" +#include "doom_levelmesh.h" #ifdef _MSC_VER #pragma warning(disable:4244) @@ -202,7 +203,11 @@ public: }; }; - + struct + { + DoomLevelMeshSurfaceType Type; + sector_t* ControlSector; + } LevelMeshInfo; // these are not the same as ytop and ybottom!!! float zceil[2]; diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 1067c285a..a5ac585b1 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -1170,16 +1170,33 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_ type = _type; - if (seg->sidedef->surface.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM) + if (di->di) { - surface = seg->sidedef->surface[type - RENDERWALL_TOP]; - if (surface && di->di) + if (seg->sidedef->surface.Size() >= 4 && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM) { - di->di->PushVisibleSurface(surface); + surface = seg->sidedef->surface[type - RENDERWALL_TOP]; + if (surface && di->di) + { + di->di->PushVisibleSurface(surface); + } + } + else + { + surface = nullptr; } } else { + if (type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM) + { + static const DoomLevelMeshSurfaceType surfTypes[] = { ST_UPPERSIDE, ST_MIDDLESIDE, ST_MIDDLESIDE, ST_LOWERSIDE }; + LevelMeshInfo.Type = surfTypes[type - RENDERWALL_TOP]; + } + else + { + LevelMeshInfo.Type = ST_NONE; + } + LevelMeshInfo.ControlSector = nullptr; surface = nullptr; } @@ -1237,14 +1254,23 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg // if (texture) { - if (seg->sidedef->surface.Size() >= 4) + if (di->di) { - surface = seg->sidedef->surface[side_t::mid]; - if (surface && di->di) + if (seg->sidedef->surface.Size() >= 4) { - di->di->PushVisibleSurface(surface); + surface = seg->sidedef->surface[side_t::mid]; + if (surface && di->di) + { + di->di->PushVisibleSurface(surface); + } } } + else + { + LevelMeshInfo.Type = ST_MIDDLESIDE; + LevelMeshInfo.ControlSector = nullptr; + surface = nullptr; + } // Align the texture to the ORIGINAL sector's height!! // At this point slopes don't matter because they don't affect the texture's z-position @@ -1575,15 +1601,23 @@ void HWWall::BuildFFBlock(HWWallDispatcher *di, FRenderState& state, seg_t * seg float texlength; FTexCoordInfo tci; - surface = nullptr; - if (seg->sidedef == seg->linedef->sidedef[0]) - surface = seg->linedef->sidedef[1]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[1]->surface[4 + roverIndex] : nullptr; - else - surface = seg->linedef->sidedef[0]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[0]->surface[4 + roverIndex] : nullptr; - - if (surface && di->di) + if (di->di) { - di->di->PushVisibleSurface(surface); + if (seg->sidedef == seg->linedef->sidedef[0]) + surface = seg->linedef->sidedef[1]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[1]->surface[4 + roverIndex] : nullptr; + else + surface = seg->linedef->sidedef[0]->surface.Size() > 4 + roverIndex ? seg->linedef->sidedef[0]->surface[4 + roverIndex] : nullptr; + + if (surface) + { + di->di->PushVisibleSurface(surface); + } + } + else + { + LevelMeshInfo.Type = ST_MIDDLESIDE; + LevelMeshInfo.ControlSector = rover->model; + surface = nullptr; } if (rover->flags&FF_FOG) @@ -1979,6 +2013,9 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect surface = nullptr; + LevelMeshInfo.Type = ST_NONE; + LevelMeshInfo.ControlSector = nullptr; + // note: we always have a valid sidedef and linedef reference when getting here. this->seg = seg;