qbsp: add -missing_textures_as_zero_size flag to allow writing 0x0 textures when a texture is missing
this allows us to write the texture name, but it's non-standard. light: warn when a surface light template doesn't match any faces in the bsp
This commit is contained in:
parent
c62633f1a3
commit
f0c8d92993
|
|
@ -28,7 +28,8 @@ testmaps/quake_map_source/*.prt
|
||||||
testmaps/quake_map_source/*.pts
|
testmaps/quake_map_source/*.pts
|
||||||
testmaps/quake_map_source/*.vis
|
testmaps/quake_map_source/*.vis
|
||||||
testmaps/quake_map_source/*.texinfo
|
testmaps/quake_map_source/*.texinfo
|
||||||
testmaps/quake_map_source/*.bsp.json
|
testmaps/quake_map_source/*.json
|
||||||
|
testmaps/quake_map_source/*.obj
|
||||||
**/autosave
|
**/autosave
|
||||||
CMakeSettings.json
|
CMakeSettings.json
|
||||||
sphinx-venv
|
sphinx-venv
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ void dmiptexlump_t::stream_write(std::ostream &stream) const
|
||||||
|
|
||||||
// write out the miptex offsets
|
// write out the miptex offsets
|
||||||
for (auto &texture : textures) {
|
for (auto &texture : textures) {
|
||||||
if (!texture.name[0] || texture.width == 0 || texture.height == 0) {
|
if (texture.null_texture) {
|
||||||
// dummy texture
|
// dummy texture
|
||||||
stream <= static_cast<int32_t>(-1);
|
stream <= static_cast<int32_t>(-1);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -213,7 +213,7 @@ void dmiptexlump_t::stream_write(std::ostream &stream) const
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &texture : textures) {
|
for (auto &texture : textures) {
|
||||||
if (texture.name[0] && texture.width && texture.height) {
|
if (!texture.null_texture) {
|
||||||
// fix up the padding to match the above conditions
|
// fix up the padding to match the above conditions
|
||||||
if (stream.tellp() % 4) {
|
if (stream.tellp() % 4) {
|
||||||
constexpr const char pad[4]{};
|
constexpr const char pad[4]{};
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,7 @@ public:
|
||||||
setting_invertible_bool transwater;
|
setting_invertible_bool transwater;
|
||||||
setting_bool transsky;
|
setting_bool transsky;
|
||||||
setting_bool notextures;
|
setting_bool notextures;
|
||||||
|
setting_bool missing_textures_as_zero_size;
|
||||||
setting_enum<conversion_t> convertmapformat;
|
setting_enum<conversion_t> convertmapformat;
|
||||||
setting_invertible_bool oldaxis;
|
setting_invertible_bool oldaxis;
|
||||||
setting_bool forcegoodtree;
|
setting_bool forcegoodtree;
|
||||||
|
|
|
||||||
|
|
@ -1511,6 +1511,15 @@ static void MakeSurfaceLights(const mbsp_t *bsp)
|
||||||
|
|
||||||
logging::print("Creating surface lights for texture \"{}\" from template at ({})\n", tex,
|
logging::print("Creating surface lights for texture \"{}\" from template at ({})\n", tex,
|
||||||
entity->epairs->get("origin"));
|
entity->epairs->get("origin"));
|
||||||
|
|
||||||
|
// Warning if no faces exist matching the texture
|
||||||
|
const bool found_face = std::any_of(bsp->dfaces.begin(), bsp->dfaces.end(), [&](const mface_t &face) -> bool {
|
||||||
|
return !Q_strcasecmp(Face_TextureName(bsp, &face), entity->epairs->get("_surface"));
|
||||||
|
});
|
||||||
|
if (!found_face) {
|
||||||
|
logging::print("WARNING: no faces found with texture {} (qbsp may have been run with .wad's missing?)\n",
|
||||||
|
entity->epairs->get("_surface"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
11
qbsp/qbsp.cc
11
qbsp/qbsp.cc
|
|
@ -479,6 +479,8 @@ qbsp_settings::qbsp_settings()
|
||||||
transsky{this, "transsky", false, &map_development_group, "compute portal information for transparent sky"},
|
transsky{this, "transsky", false, &map_development_group, "compute portal information for transparent sky"},
|
||||||
notextures{this, "notex", false, &common_format_group,
|
notextures{this, "notex", false, &common_format_group,
|
||||||
"write only placeholder textures to depend upon replacements, keep file sizes down, or to skirt copyrights"},
|
"write only placeholder textures to depend upon replacements, keep file sizes down, or to skirt copyrights"},
|
||||||
|
missing_textures_as_zero_size{this, "missing_textures_as_zero_size", false, &common_format_group,
|
||||||
|
"write missing textures as 0x0"},
|
||||||
convertmapformat{this, "convert", conversion_t::none,
|
convertmapformat{this, "convert", conversion_t::none,
|
||||||
{{"quake", conversion_t::quake}, {"quake2", conversion_t::quake2}, {"valve", conversion_t::valve},
|
{{"quake", conversion_t::quake}, {"quake2", conversion_t::quake2}, {"valve", conversion_t::valve},
|
||||||
{"bp", conversion_t::bp}},
|
{"bp", conversion_t::bp}},
|
||||||
|
|
@ -1539,6 +1541,15 @@ static void LoadTextureData()
|
||||||
header.height = miptex.height;
|
header.height = miptex.height;
|
||||||
header.offsets = {0, 0, 0, 0};
|
header.offsets = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
if (!miptex.name[0])
|
||||||
|
miptex.null_texture = true;
|
||||||
|
|
||||||
|
if (!qbsp_options.missing_textures_as_zero_size.value()) {
|
||||||
|
if (miptex.width == 0 || miptex.height == 0) {
|
||||||
|
miptex.null_texture = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
omemstream stream(miptex.data.data(), miptex.data.size());
|
omemstream stream(miptex.data.data(), miptex.data.size());
|
||||||
stream <= header;
|
stream <= header;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1969,6 +1969,28 @@ TEST_CASE("q1_missing_texture")
|
||||||
CHECK(6 == bsp.dfaces.size());
|
CHECK(6 == bsp.dfaces.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("q1_missing_texture, -missing_textures_as_zero_size")
|
||||||
|
{
|
||||||
|
const auto [bsp, bspx, prt] = LoadTestmap("q1_missing_texture.map", {"-missing_textures_as_zero_size"});
|
||||||
|
|
||||||
|
REQUIRE(2 == bsp.dtex.textures.size());
|
||||||
|
|
||||||
|
// FIXME: we shouldn't really be writing skip
|
||||||
|
// (our test data includes an actual "skip" texture,
|
||||||
|
// so that gets included in the bsp.)
|
||||||
|
CHECK("skip" == bsp.dtex.textures[0].name);
|
||||||
|
CHECK(!bsp.dtex.textures[0].null_texture);
|
||||||
|
CHECK(64 == bsp.dtex.textures[0].width);
|
||||||
|
CHECK(64 == bsp.dtex.textures[0].height);
|
||||||
|
|
||||||
|
CHECK("somemissingtext" == bsp.dtex.textures[1].name);
|
||||||
|
CHECK(!bsp.dtex.textures[1].null_texture);
|
||||||
|
CHECK(0 == bsp.dtex.textures[1].width);
|
||||||
|
CHECK(0 == bsp.dtex.textures[1].height);
|
||||||
|
|
||||||
|
CHECK(6 == bsp.dfaces.size());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("q1 notex")
|
TEST_CASE("q1 notex")
|
||||||
{
|
{
|
||||||
const auto [bsp, bspx, prt] = LoadTestmap("q1_cube.map", {"-notex"});
|
const auto [bsp, bspx, prt] = LoadTestmap("q1_cube.map", {"-notex"});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue