Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
gameknife committed Jul 24, 2024
2 parents a56bcae + 1e6fdb5 commit e7f19fb
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 236 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@
* File Format support
* Wavefront OBJ File PBR Scene Support
* GLTF Scene File Support
* CrossPlatform support for Windows/Linux/MacOS
* CrossPlatform support for Windows/Linux/MacOS/Android
* Global Bindless TexturePool
* MultiThread Resource Loading
* HDR Display Support
* Screenshot HDR and encode to avif

Expand Down Expand Up @@ -101,7 +103,7 @@ gkNextRenderer.exe --width=1920 --height=1080 --benchmark --next-scenes
- Scene Management
- ~~Element Instancing~~
- ~~Multi draw indirect~~
- GLobal Dynamic Bindless Textures
- ~~GLobal Dynamic Bindless Textures~~
- RayTracing Pipeline
- ~~Temporal Reprojection~~
- ~~Ray Query Pipeline~~
Expand Down Expand Up @@ -143,7 +145,7 @@ gkNextRenderer.exe --width=1920 --height=1080 --benchmark --next-scenes
- [ ] Android Input Handling
- [x] Realtimg self statics system
- [ ] Auto release by Github action
- [ ] Global Dynamic Bindless Textures
- [x] Global Dynamic Bindless Textures
- [x] Hybrid rendering with ray query
- [ ] Blender Export Property as CustomProperty to glb
- [x] OpenImageDenoise (Only windows)
Expand Down
57 changes: 37 additions & 20 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,19 @@ void NextRendererApplication<Renderer>::OnDeviceSet()

// global textures
// texture id 0: global sky
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/canary_wharf_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/kloppenheim_01_puresky_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/kloppenheim_07_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/river_road_2.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/rainforest_trail_1k.hdr"), Vulkan::SamplerConfig());

Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/studio_small_03_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/studio_small_09_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/sunset_fairway_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/umhlanga_sunrise_1k.hdr"), Vulkan::SamplerConfig());
Assets::Texture::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/shanghai_bund_1k.hdr"), Vulkan::SamplerConfig());

if(userSettings_.HDRIfile != "") Assets::Texture::LoadHDRTexture(userSettings_.HDRIfile.c_str(), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/canary_wharf_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/kloppenheim_01_puresky_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/kloppenheim_07_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/river_road_2.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/rainforest_trail_1k.hdr"), Vulkan::SamplerConfig());

Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/studio_small_03_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/studio_small_09_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/sunset_fairway_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/umhlanga_sunrise_1k.hdr"), Vulkan::SamplerConfig());
Assets::GlobalTexturePool::LoadHDRTexture(Utilities::FileHelper::GetPlatformFilePath("assets/textures/shanghai_bund_1k.hdr"), Vulkan::SamplerConfig());

if(userSettings_.HDRIfile != "") Assets::GlobalTexturePool::LoadHDRTexture(userSettings_.HDRIfile.c_str(), Vulkan::SamplerConfig());
userSettings_.HDRIsLoaded = Assets::GlobalTexturePool::GetInstance()->TotalTextures() - 1;

//LoadScene(userSettings_.SceneIndex);
Expand Down Expand Up @@ -418,6 +418,23 @@ void NextRendererApplication<Renderer>::OnScroll(const double xoffset, const dou
UserSettings::FieldOfViewMaxValue);
}

template <typename Renderer>
void NextRendererApplication<Renderer>::OnDropFile(int path_count, const char* paths[])
{
// add glb to the last, and loaded
if (path_count > 0)
{
std::string path = paths[path_count - 1];
std::string ext = path.substr(path.find_last_of(".") + 1);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);

if (ext == "glb")
{
userSettings_.SceneIndex = SceneList::AddExternalScene(path);
}
}
}

template <typename Renderer>
void NextRendererApplication<Renderer>::OnTouch(bool down, double xpos, double ypos)
{
Expand Down Expand Up @@ -574,10 +591,13 @@ void NextRendererApplication<Renderer>::CheckAndUpdateBenchmarkState(double prev
const double totalTime = time_ - sceneInitialTime_;
std::string SceneName = SceneList::AllScenes[userSettings_.SceneIndex].first;
double fps = benchmarkTotalFrames_ / totalTime;

//fmt::format()
//printf("\n*** totalTime %s %.2f fps\n", buff, fps);

char buff[50];
Utilities::get_time_str(buff, static_cast<float>(totalTime));
printf("\n*** totalTime %s %.2f fps\n", buff, fps);
std::cout << "\n*** totalTime "
<< fmt::format("{:%H:%M:%S}", std::chrono::seconds(static_cast<long long>(totalTime)))
<< " fps " << std::fixed << std::setprecision(2) << fps << "\n";

Report(static_cast<int>(floor(fps)), SceneName, false, GOption->SaveFile);
benchmarkCsvReportFile << sceneIndex_ << ";" << SceneList::AllScenes[sceneIndex_].first <<";" << fps << std::endl;
Expand Down Expand Up @@ -795,10 +815,7 @@ void NextRendererApplication<Renderer>::Report(int fps, const std::string& scene
printf("screenshot saved to %s\n", filename.c_str());

std::uintmax_t img_file_size = std::filesystem::file_size(filename);

char buff[50];
Utilities::metricFormatter(static_cast<double>(img_file_size), buff, (void*)"b", 1024);
printf("file size: %s\n", buff);
std::cout << "file size: " << Utilities::metricFormatter(static_cast<double>(img_file_size), "b", 1024) << "\n";

// send to server
//img_encoded = base64_encode(data, img_file_size, false);
Expand Down
1 change: 1 addition & 0 deletions src/Application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class NextRendererApplication final : public Renderer
void OnCursorPosition(double xpos, double ypos) override;
void OnMouseButton(int button, int action, int mods) override;
void OnScroll(double xoffset, double yoffset) override;
void OnDropFile(int path_count, const char* paths[]) override;

private:

Expand Down
12 changes: 8 additions & 4 deletions src/Assets/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
// #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <tiny_gltf.h>
#include <fmt/format.h>

#include "Texture.hpp"

Expand Down Expand Up @@ -182,11 +183,14 @@ namespace Assets

std::filesystem::path filepath = filename;

for (tinygltf::Image& image : model.images)
for ( uint32_t i = 0; i < model.images.size(); ++i )
{
tinygltf::Image& image = model.images[i];

std::string texname = image.name.empty() ? fmt::format("tex_{}", i): image.name;
// 假设,这里的image id和外面的textures id是一样的
uint32_t texIdx = Texture::LoadTexture(
filepath.filename().string() + "_" + image.name, model.buffers[0].data.data() + model.bufferViews[image.bufferView].byteOffset,
uint32_t texIdx = GlobalTexturePool::LoadTexture(
filepath.filename().string() + "_" + texname, model.buffers[0].data.data() + model.bufferViews[image.bufferView].byteOffset,
model.bufferViews[image.bufferView].byteLength, Vulkan::SamplerConfig());

textureIdMap.push_back(texIdx);
Expand Down Expand Up @@ -542,7 +546,7 @@ namespace Assets
m.DiffuseTextureId = get_tex_id(tex_filename, isNew);
if (isNew)
{
uint32_t texIdx = Texture::LoadTexture(tex_filename, Vulkan::SamplerConfig());
uint32_t texIdx = GlobalTexturePool::LoadTexture(tex_filename, Vulkan::SamplerConfig());
m.DiffuseTextureId = static_cast<int32_t>(texIdx);
tex_names[tex_filename] = m.DiffuseTextureId;
}
Expand Down
123 changes: 15 additions & 108 deletions src/Assets/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,108 +16,29 @@ namespace Assets
float elapsed;
std::array<char, 256> outputInfo;
};


uint32_t Texture::LoadTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig)
uint32_t GlobalTexturePool::LoadTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig)
{
uint32_t texIdx = GlobalTexturePool::GetInstance()->TryGetTexureIndex(filename);
if (texIdx != -1)
{
return texIdx;
}
// std::cout << "- loading '" << filename << "'... " << std::flush;
// const auto timer = std::chrono::high_resolution_clock::now();
//
// // Load the texture in normal host memory.
// int width, height, channels;
// const auto pixels = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
//
// if (!pixels)
// {
// Throw(std::runtime_error("failed to load texture image '" + filename + "'"));
// }
//
// const auto elapsed = std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::high_resolution_clock::now() - timer).count();
// std::cout << "(" << width << " x " << height << " x " << channels << ") ";
// std::cout << elapsed << "s" << std::endl;
//
// // bind texture to global texture pool directly
// return GlobalTexturePool::GetInstance()->RequestNewTexture(Texture(filename, width, height, channels, 0, pixels));

return GlobalTexturePool::GetInstance()->RequestNewTextureFileAsync(filename, false);
return GetInstance()->RequestNewTextureFileAsync(filename, false);
}

uint32_t Texture::LoadTexture(const std::string& texname, const unsigned char* data, size_t bytelength, const Vulkan::SamplerConfig& samplerConfig)
uint32_t GlobalTexturePool::LoadTexture(const std::string& texname, const unsigned char* data, size_t bytelength, const Vulkan::SamplerConfig& samplerConfig)
{
uint32_t texIdx = GlobalTexturePool::GetInstance()->TryGetTexureIndex(texname);
if (texIdx != -1)
{
return texIdx;
}
// const auto timer = std::chrono::high_resolution_clock::now();
//
// // Load the texture in normal host memory.
// int width, height, channels;
// const auto pixels = stbi_load_from_memory(data, static_cast<uint32_t>(bytelength), &width, &height, &channels, STBI_rgb_alpha);
//
// if (!pixels)
// {
// Throw(std::runtime_error("failed to load texture image "));
// }
//
// const auto elapsed = std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::high_resolution_clock::now() - timer).count();
// std::cout << texname << "(" << width << " x " << height << " x " << channels << ") ";
// std::cout << elapsed << "s" << std::endl;
//
// return GlobalTexturePool::GetInstance()->RequestNewTexture( Texture(texname, width, height, channels, 0, pixels));

return GlobalTexturePool::GetInstance()->RequestNewTextureMemAsync(texname, false, data, bytelength);
return GetInstance()->RequestNewTextureMemAsync(texname, false, data, bytelength);
}

uint32_t Texture::LoadHDRTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig)
uint32_t GlobalTexturePool::LoadHDRTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig)
{
uint32_t texIdx = GlobalTexturePool::GetInstance()->TryGetTexureIndex(filename);
if (texIdx != -1)
{
return texIdx;
}
// std::cout << "- loading hdr '" << filename << "'... " << std::flush;
// const auto timer = std::chrono::high_resolution_clock::now();
//
// // Load the texture in normal host memory.
// int width, height, channels;
// void* pixels = stbi_loadf(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
//
// if (!pixels)
// {
// Throw(std::runtime_error("failed to load texture image '" + filename + "'"));
// }
//
// const auto elapsed = std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::high_resolution_clock::now() - timer).count();
// std::cout << "(" << width << " x " << height << " x " << channels << ") ";
// std::cout << elapsed << "s" << std::endl;
//
// return GlobalTexturePool::GetInstance()->RequestNewTexture( Texture(filename, width, height, channels, 1, static_cast<unsigned char*>((void*)pixels)));

return GlobalTexturePool::GetInstance()->RequestNewTextureFileAsync(filename, true);
return GetInstance()->RequestNewTextureFileAsync(filename, true);
}

Texture::Texture(std::string loadname, int width, int height, int channels, int hdr, unsigned char* const pixels) :
loadname_(loadname),
width_(width),
height_(height),
channels_(channels),
hdr_(hdr),
pixels_(pixels, stbi_image_free)
{
}


GlobalTexturePool::GlobalTexturePool(const Vulkan::Device& device, Vulkan::CommandPool& command_pool) :
device_(device),
commandPool_(command_pool)
{
static const uint32_t k_bindless_texture_binding = 0;
static const uint32_t k_max_bindless_resources = 2048;
// The maximum number of bindless resources is limited by the device.
static const uint32_t k_max_bindless_resources = device.DeviceProperties().limits.maxPerStageDescriptorSamplers;

// Create bindless descriptor pool
VkDescriptorPoolSize pool_sizes_bindless[] =
Expand Down Expand Up @@ -227,23 +148,7 @@ namespace Assets
}
return -1;
}

uint32_t GlobalTexturePool::RequestNewTexture(const Texture& texture)
{
if (textureNameMap_.find(texture.Loadname()) != textureNameMap_.end())
{
return textureNameMap_[texture.Loadname()];
}

textureImages_.emplace_back(new TextureImage(commandPool_, texture));
uint32_t newTextureIdx = static_cast<uint32_t>(textureImages_.size()) - 1;
BindTexture(newTextureIdx, *(textureImages_.back()));

// cache in namemap
textureNameMap_[texture.Loadname()] = newTextureIdx;
return newTextureIdx;
}


uint32_t GlobalTexturePool::RequestNewTextureFileAsync(const std::string& filename, bool hdr)
{
if (textureNameMap_.find(filename) != textureNameMap_.end())
Expand Down Expand Up @@ -276,8 +181,9 @@ namespace Assets
Throw(std::runtime_error("failed to load texture image '" + filename + "'"));
}

textureImages_[newTextureIdx] = std::make_unique<TextureImage>(commandPool_, Texture(filename, width, height, channels, hdr, static_cast<unsigned char*>((void*)pixels)));
textureImages_[newTextureIdx] = std::make_unique<TextureImage>(commandPool_, width, height, hdr, static_cast<unsigned char*>((void*)pixels));
BindTexture(newTextureIdx, *(textureImages_[newTextureIdx]));
stbi_image_free(pixels);

taskContext.elapsed = std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::high_resolution_clock::now() - timer).count();
std::stringstream stream;
Expand Down Expand Up @@ -324,9 +230,10 @@ namespace Assets
}

// create texture image
textureImages_[newTextureIdx] = std::make_unique<TextureImage>(commandPool_, Texture(texname, width, height, channels, 0, pixels));
textureImages_[newTextureIdx] = std::make_unique<TextureImage>(commandPool_, width, height, false, static_cast<unsigned char*>((void*)pixels));
BindTexture(newTextureIdx, *(textureImages_[newTextureIdx]));

stbi_image_free(pixels);

taskContext.elapsed = std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::high_resolution_clock::now() - timer).count();
std::stringstream stream;
stream << "loaded " << texname << "(" << width << " x " << height << " x " << channels << ") in " << std::fixed << std::setprecision(2) << taskContext.elapsed * 1000.f << "ms";
Expand Down
41 changes: 3 additions & 38 deletions src/Assets/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,6 @@ namespace Assets
{
class TextureImage;

class Texture final
{
public:

static uint32_t LoadTexture(const std::string& texname, const unsigned char* data, size_t bytelength, const Vulkan::SamplerConfig& samplerConfig);
static uint32_t LoadTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig);
static uint32_t LoadHDRTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig);

Texture& operator = (const Texture&) = delete;
Texture& operator = (Texture&&) = delete;

Texture(std::string loadname, int width, int height, int channels, int hdr, unsigned char* pixels);
Texture() = delete;
Texture(const Texture&) = delete;
Texture(Texture&&) = default;
~Texture() = default;

const unsigned char* Pixels() const { return pixels_.get(); }
int Width() const { return width_; }
int Height() const { return height_; }
bool Hdr() const {return hdr_ != 0; }
int Channels() const { return channels_; }
const std::string& Loadname() const { return loadname_; }

private:



Vulkan::SamplerConfig samplerConfig_;
std::string loadname_;
int width_;
int height_;
int channels_;
int hdr_;
std::unique_ptr<unsigned char, void (*) (void*)> pixels_;
};

class GlobalTexturePool final
{
public:
Expand All @@ -63,13 +26,15 @@ namespace Assets

void BindTexture(uint32_t textureIdx, const TextureImage& textureImage);
uint32_t TryGetTexureIndex(const std::string& textureName) const;
uint32_t RequestNewTexture(const Texture& texture);
uint32_t RequestNewTextureFileAsync(const std::string& filename, bool hdr);
uint32_t RequestNewTextureMemAsync(const std::string& texname, bool hdr, const unsigned char* data, size_t bytelength);

uint32_t TotalTextures() const {return static_cast<uint32_t>(textureImages_.size());}

static GlobalTexturePool* GetInstance() {return instance_;}
static uint32_t LoadTexture(const std::string& texname, const unsigned char* data, size_t bytelength, const Vulkan::SamplerConfig& samplerConfig);
static uint32_t LoadTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig);
static uint32_t LoadHDRTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig);

private:
static GlobalTexturePool* instance_;
Expand Down
Loading

0 comments on commit e7f19fb

Please sign in to comment.