Skip to content

Commit

Permalink
Fix textures loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyuu17 committed Jun 14, 2024
1 parent dc21e65 commit 6a009b9
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 50 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ target_sources(${PROJECT_NAME}
"SWBF2/Native/Level.cpp"
"SWBF2/Core.cpp"
"SWBF2/Level.cpp"
"SWBF2/MaterialPools.cpp"

"RegisterExtension.cpp"
)

Expand Down
6 changes: 5 additions & 1 deletion src/SWBF2/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ namespace SWBF2

void Core::_ready()
{
set_name("Core");

godot::UtilityFunctions::print("hello world!");

// SWBF2::Native::UcfbChunk::ReadUcfbFile("data/_lvl_pc/common.lvl");
// SWBF2::Native::UcfbChunk::ReadUcfbFile("data/_lvl_pc/core.lvl");

add_child(memnew(Level));
Level *lvl = memnew(Level);
add_child(lvl);
lvl->set_owner(this);
}

void Core::_bind_methods()
Expand Down
52 changes: 23 additions & 29 deletions src/SWBF2/Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,22 @@ namespace SWBF2
{
void Level::_ready()
{
set_name("Level");

SWBF2::Native::UcfbChunk::ReadUcfbFile("data/_lvl_pc/cor/cor1.lvl");

LoadTextures();
LoadMeshes();
}

void Level::LoadTextures()
{
for (auto const &[id, tex] : Native::Level::m_tex)
{
for (auto const format : tex->m_formats)
{
for (auto const faceLevel : format.m_faceLevels)
{
godot::Ref<godot::StandardMaterial3D> material;
material.instantiate();
material->set_texture(godot::StandardMaterial3D::TEXTURE_ALBEDO, faceLevel.m_gdImageTexture);
material->set_flag(godot::BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
material->set_cull_mode(godot::BaseMaterial3D::CULL_DISABLED);

m_textureMaterials.insert_or_assign(id, material);
}
}
}
}

void Level::LoadMeshes()
{
for (auto const &[id, model] : Native::Level::m_models)
{
uint32_t segment_id = 0;
for (auto const &segment : model.m_segments)
{
godot::MeshInstance3D *meshInstance = memnew(godot::MeshInstance3D);
meshInstance->set_name(std::format("_lvl_mesh_{}", id).c_str());

add_child(meshInstance);
meshInstance->set_name(std::format("{}_segm_{}", id, segment_id).c_str());

godot::PackedVector3Array vertices;
godot::PackedVector3Array normals;
Expand Down Expand Up @@ -100,18 +80,28 @@ namespace SWBF2
godot::ArrayMesh *arrMesh = memnew(godot::ArrayMesh);
arrMesh->add_surface_from_arrays(godot::Mesh::PRIMITIVE_TRIANGLE_STRIP, arrays);

meshInstance->set_mesh(arrMesh);

auto tex_id = 0;
for (const auto &texName : segment.m_textureNames)
{
if (!m_textureMaterials.contains(texName))
// TODO, apply bump to texture
if (texName.ends_with("bump"))
continue;

auto &material = m_materialPool.getItem(texName);
if (material.is_null())
{
godot::UtilityFunctions::printerr(__FILE__, ":", __LINE__, ": No texture found for ", texName.c_str());
godot::UtilityFunctions::printerr(__FILE__, ":", __LINE__, ": No material found for ", texName.c_str());
continue;
}

godot::UtilityFunctions::print(__FILE__, ":", __LINE__, ": Found texture of ", texName.c_str());
godot::UtilityFunctions::print(__FILE__, ":", __LINE__, ": Found texture ", texName.c_str(), " for mesh ", id.c_str(), " with segment id ", segment_id);

// if (segment.m_material.m_flags & Native::MaterialFlags::Transparent)
// material->set_transparency(godot::BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR);

meshInstance->set_material_override(m_textureMaterials[texName]);
meshInstance->set_surface_override_material(0, material);

tex_id++;
}
Expand All @@ -121,7 +111,11 @@ namespace SWBF2
godot::UtilityFunctions::printerr(__FILE__, ":", __LINE__, ": Mesh ", id.c_str(), " has no texture at all");
}

meshInstance->set_mesh(arrMesh);
add_child(meshInstance);
meshInstance->set_owner(this->get_parent());
meshInstance->add_to_group("Level Meshes");

segment_id++;
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/SWBF2/Level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/classes/standard_material3d.hpp>

#include "MaterialPools.hpp"

namespace SWBF2
{
class Level : public godot::Node3D {
GDCLASS(Level, godot::Node3D)

private:
std::unordered_map<std::string, godot::Ref<godot::StandardMaterial3D>> m_textureMaterials;
public:
Level() {}
~Level() = default;

MaterialPools m_materialPool;

virtual void _ready() override;

void LoadTextures();
void LoadMeshes();

void _process(double delta_time) override;
Expand Down
33 changes: 33 additions & 0 deletions src/SWBF2/MaterialPools.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

#pragma once

#include "Native/Level.hpp"

#include "MaterialPools.hpp"

namespace SWBF2
{
const godot::Ref<godot::Texture> &SWBF2::MaterialPools::findTexture(const std::string &id)
{
if (!Native::Level::m_tex.contains(id))
return m_empty;

auto &tex = Native::Level::m_tex[id];
auto &gdTex = tex.m_formats.at(0).m_faceLevels.at(0).m_gdTexture;
return gdTex;
}

godot::Ref<godot::StandardMaterial3D> &MaterialPools::getItem(const std::string &key)
{
auto &texture = findTexture(key);

godot::Ref<godot::StandardMaterial3D> material = memnew(godot::StandardMaterial3D);
material->set_texture(godot::StandardMaterial3D::TEXTURE_ALBEDO, texture);
material->set_flag(godot::BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
material->set_cull_mode(godot::BaseMaterial3D::CULL_DISABLED);

m_pool.emplace(key, material);

return m_pool[key];
}
}
20 changes: 20 additions & 0 deletions src/SWBF2/MaterialPools.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

#pragma once

#include <godot_cpp/classes/standard_material3d.hpp>
#include <godot_cpp/classes/texture2d.hpp>

#include "Pools.hpp"

namespace SWBF2
{
class MaterialPools : public Pools<std::string, godot::StandardMaterial3D> {
private:
godot::Ref<godot::Texture> m_empty;

const godot::Ref<godot::Texture> &findTexture(const std::string &id);
public:

godot::Ref<godot::StandardMaterial3D> &getItem(const std::string &key) override;
};
}
26 changes: 14 additions & 12 deletions src/SWBF2/Native/Chunks/TextureChunk.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <godot_cpp/variant/utility_functions.hpp>

#include <godot_cpp/classes/image_texture.hpp>

#include "Native/Chunks/StreamReader.hpp"
#include "Native/Chunks/TextureChunk.hpp"

Expand All @@ -10,19 +12,19 @@ namespace SWBF2::Native
{
void TextureChunk::ProcessChunk(StreamReader &streamReader)
{
std::unique_ptr<Texture> tex = std::make_unique<Texture>();
Texture tex{};

auto texNameReaderChild = streamReader.ReadChildWithHeader<"NAME"_m>();
{
*texNameReaderChild >> tex->m_name;
*texNameReaderChild >> tex.m_name;
}

auto infoReaderChild = streamReader.ReadChildWithHeader<"INFO"_m>();
{
*infoReaderChild >> tex->m_formatCount;
*infoReaderChild >> tex.m_formatCount;

tex->m_d3dFormats.resize(tex->m_formatCount);
*infoReaderChild >> tex->m_d3dFormats;
tex.m_d3dFormats.resize(tex.m_formatCount);
*infoReaderChild >> tex.m_d3dFormats;

std::optional<StreamReader> fmtReaderChild;
while ((fmtReaderChild = streamReader.ReadChild()).has_value())
Expand All @@ -31,7 +33,7 @@ namespace SWBF2::Native
{
case "FMT_"_m: {
StreamReader r{ *fmtReaderChild };
TextureChunk::ProcessFMTChunk(r, tex.get());
TextureChunk::ProcessFMTChunk(r, tex);
break;
}

Expand All @@ -42,14 +44,14 @@ namespace SWBF2::Native
}
}

Level::m_tex.try_emplace(tex->m_name, std::move(tex));
Level::m_tex.try_emplace(tex.m_name, std::move(tex));
}

void TextureChunk::ProcessFMTChunk(StreamReader &streamReader, Texture *tex)
void TextureChunk::ProcessFMTChunk(StreamReader &streamReader, Texture &tex)
{
auto infoReaderChild = streamReader.ReadChildWithHeader<"INFO"_m>();

auto &fmt = tex->m_formats.emplace_back(TextureFormat());
auto &fmt = tex.m_formats.emplace_back(TextureFormat{});
{
*infoReaderChild >> fmt.m_format;
*infoReaderChild >> fmt.m_width;
Expand All @@ -73,7 +75,7 @@ namespace SWBF2::Native

void TextureChunk::ProcessTextureLevelChunk(StreamReader &streamReader, TextureFormat &fmt)
{
TextureFormatFaceLevel lvl;
TextureFormatFaceLevel lvl{};

auto infoReaderChild = streamReader.ReadChildWithHeader<"INFO"_m>();
{
Expand All @@ -95,9 +97,9 @@ namespace SWBF2::Native
std::copy(lvl.m_imageInBytes.begin(), lvl.m_imageInBytes.end(), (std::byte *)imageBuf.ptrw());

godot::Ref<godot::Image> image{ godot::Image::create_from_data(fmt.m_width, fmt.m_height, false, TextureUtils::D3DToGLFormat(fmt.m_format), imageBuf) };
godot::Ref<godot::ImageTexture> imageTex{ godot::ImageTexture::create_from_image(image) };

lvl.m_gdImageTexture.instantiate();
lvl.m_gdImageTexture->create_from_image(image);
lvl.m_gdTexture = imageTex;
}

fmt.m_faceLevels.push_back(lvl);
Expand Down
2 changes: 1 addition & 1 deletion src/SWBF2/Native/Chunks/TextureChunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace SWBF2::Native
class TextureChunk {
public:
static void ProcessChunk(StreamReader &streamReader);
static void ProcessFMTChunk(StreamReader &streamReader, Texture *tex);
static void ProcessFMTChunk(StreamReader &streamReader, Texture &tex);
static void ProcessTextureLevelChunk(StreamReader &streamReader, TextureFormat &fmt);
};

Expand Down
2 changes: 1 addition & 1 deletion src/SWBF2/Native/Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace SWBF2::Native
World Level::m_world;

std::unordered_map<std::string, Model> Level::m_models;
std::unordered_map<std::string, std::unique_ptr<Texture>> Level::m_tex;
std::unordered_map<std::string, Texture> Level::m_tex;
std::unordered_map<std::string, Level::LoclEntriesMap> Level::m_locl;
}
2 changes: 1 addition & 1 deletion src/SWBF2/Native/Level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace SWBF2::Native
static World m_world;

static std::unordered_map<std::string, Model> m_models;
static std::unordered_map<std::string, std::unique_ptr<Texture>> m_tex;
static std::unordered_map<std::string, Texture> m_tex;

using LoclEntriesMap = std::unordered_map<FNVHash, std::u16string>;
static std::unordered_map<std::string, LoclEntriesMap> m_locl;
Expand Down
4 changes: 2 additions & 2 deletions src/SWBF2/Native/Texture/Texture.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

#pragma once

#include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/texture.hpp>

#include "Native/D3D9/d3dformat.hpp"

Expand All @@ -13,7 +13,7 @@ namespace SWBF2::Native
uint32_t m_bodySize;
std::vector<std::byte> m_imageInBytes;

godot::Ref<godot::ImageTexture> m_gdImageTexture;
godot::Ref<godot::Texture> m_gdTexture;
} TextureFormatFaceLevel;

typedef struct _TEX_FMT
Expand Down
28 changes: 28 additions & 0 deletions src/SWBF2/Pools.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

#pragma once

#include <godot_cpp/classes/ref.hpp>

#include "Types.hpp"

namespace SWBF2
{
template <typename K, typename T>
class Pools {

godot::Ref<T> m_empty;

public:
std::unordered_map<K, godot::Ref<T>> m_pool;

inline virtual bool contains(const K &key)
{
return m_pool.contains(key);
}

inline virtual godot::Ref<T> &getItem(const K &key)
{
return m_pool.contains(key) ? m_pool.at(key) : m_empty;
}
};
}

0 comments on commit 6a009b9

Please sign in to comment.