From e7e23ed2db43058ac9f963a43c5e91c4e6e3be87 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Mon, 5 Aug 2019 16:11:36 -0700 Subject: [PATCH 01/24] 1st commit: -) fixed a couple of loggings; -) use join in corrade to generate the file path; --- src/esp/assets/Asset.cpp | 5 +++ src/esp/assets/PTexMeshData.cpp | 54 +++++++++++++++++++----------- src/esp/assets/ResourceManager.cpp | 15 ++++++--- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/esp/assets/Asset.cpp b/src/esp/assets/Asset.cpp index 3dc13c11b1..59e75b9ffc 100644 --- a/src/esp/assets/Asset.cpp +++ b/src/esp/assets/Asset.cpp @@ -20,6 +20,11 @@ AssetInfo AssetInfo::fromPath(const std::string& path) { info.type = AssetType::INSTANCE_MESH; } else if (endsWith(path, "ptex_quad_mesh.ply")) { info.type = AssetType::FRL_PTEX_MESH; + } else if (endsWith(path, "mesh.ply")) { + // Warning: + // The order of if clause matters. cannot move "mesh.ply" before + // "ptex_quad_mesh.ply" or "semantic_quad_mesh.ply" + info.type = AssetType::FRL_PTEX_MESH; } else if (endsWith(path, "house.json")) { info.type = AssetType::SUNCG_SCENE; } else if (endsWith(path, ".glb")) { diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index d4984728cc..8551e5b1fd 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -14,6 +14,7 @@ #include #include #include +// #include #include "esp/core/esp.h" #include "esp/gfx/PTexMeshShader.h" @@ -34,7 +35,10 @@ void PTexMeshData::load(const std::string& meshFile, ASSERT(io::exists(atlasFolder)); // Parse parameters - const auto& paramsFile = atlasFolder + "/parameters.json"; + // careful: when using "join", no leading forward slash in the file name. + // otherwise the corrade would think it is absolute path + const auto& paramsFile = + Corrade::Utility::Directory::join(atlasFolder, "parameters.json"); ASSERT(io::exists(paramsFile)); const io::JsonDocument json = io::parseJsonFile(paramsFile); splitSize_ = json["splitSize"].GetDouble(); @@ -203,20 +207,23 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, std::unordered_map> edgeMap; - size_t numFaces = mesh.ibo.size() / 4; + // only works on quad meshes + const int polygonStride = 4; + size_t numFaces = mesh.ibo.size() / polygonStride; typedef std::unordered_map>::iterator EdgeIter; - std::vector edgeIterators(numFaces * 4); + std::vector edgeIterators(numFaces * polygonStride); // for each face for (int f = 0; f < numFaces; f++) { // for each edge - for (int e = 0; e < 4; e++) { + for (int e = 0; e < polygonStride; e++) { // add to edge to face map - const int e_index = f * 4 + e; + const int e_index = f * polygonStride + e; const uint32_t i0 = mesh.ibo[e_index]; - const uint32_t i1 = mesh.ibo[f * 4 + ((e + 1) % 4)]; + const uint32_t i1 = + mesh.ibo[f * polygonStride + ((e + 1) % polygonStride)]; const uint64_t key = (uint64_t)std::min(i0, i1) << 32 | (uint32_t)std::max(i0, i1); @@ -236,11 +243,11 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, } } - adjFaces.resize(numFaces * 4); + adjFaces.resize(numFaces * polygonStride); for (int f = 0; f < numFaces; f++) { - for (int e = 0; e < 4; e++) { - const int e_index = f * 4 + e; + for (int e = 0; e < polygonStride; e++) { + const int e_index = f * polygonStride + e; auto it = edgeIterators[e_index]; const std::vector& adj = it->second; @@ -267,13 +274,16 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, } // pack adjacent face and rotation into 32-bit int - adjFaces[f * 4 + e] = (rot << ROTATION_SHIFT) | (adjFace & FACE_MASK); + adjFaces[f * polygonStride + e] = + (rot << ROTATION_SHIFT) | (adjFace & FACE_MASK); } } } void PTexMeshData::loadMeshData(const std::string& meshFile) { PTexMeshData::MeshData originalMesh; + + std::cout << "start parsing PLY... " << std::endl; parsePLY(meshFile, originalMesh); submeshes_.clear(); @@ -583,7 +593,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { currentMesh->ibo.setData(submeshes_[iMesh].ibo, Magnum::GL::BufferUsage::StaticDraw); } - std::cout << "... done" << std::endl; + std::cout << "done" << std::endl; std::cout << "Calculating mesh adjacency... "; std::cout.flush(); @@ -594,6 +604,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { calculateAdjacency(submeshes_[iMesh], adjFaces[iMesh]); } + std::cout << "... done" << std::endl; for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; @@ -609,28 +620,33 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { Magnum::GL::MeshIndexType::UnsignedInt); } + // load atlas data and upload them to GPU + + std::cout << "loading atlas textures: " << std::endl; for (size_t iMesh = 0; iMesh < renderingBuffers_.size(); ++iMesh) { - const std::string rgbFile = - atlasFolder_ + "/" + std::to_string(iMesh) + "-color-ptex.rgb"; - if (!io::exists(rgbFile)) { - ASSERT(false, "Can't find " + rgbFile); - } + const std::string rgbFile = Corrade::Utility::Directory::join( + atlasFolder_, std::to_string(iMesh) + "-color-ptex.rgb"); + + ASSERT(io::exists(rgbFile)); + std::cout << "\rLoading atlas " << iMesh + 1 << "/" - << renderingBuffers_.size() << "... "; + << renderingBuffers_.size() << " from " << rgbFile << "... "; std::cout.flush(); Cr::Containers::Array data = Cr::Utility::Directory::mapRead(rgbFile); const int dim = static_cast(std::sqrt(data.size() / 3)); // square + // atlas Magnum::ImageView2D image(Magnum::PixelFormat::RGB8UI, {dim, dim}, data); renderingBuffers_[iMesh] ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) - // .setStorage(1, GL::TextureFormat::RGB8UI, image.size()) + // .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) .setSubImage(0, {}, image); + + std::cout << "done" << std::endl; } - std::cout << "... done" << std::endl; buffersOnGPU_ = true; } diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index d2e11a6d08..69240c2e4c 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -105,14 +105,21 @@ bool ResourceManager::loadPTexMeshData(const AssetInfo& info, // if this is a new file, load it and add it to the dictionary const std::string& filename = info.filepath; if (resourceDict_.count(filename) == 0) { - const std::string atlasDir = - Corrade::Utility::String::stripSuffix(filename, "ptex_quad_mesh.ply") + - "ptex_textures"; + const auto atlasDir = [=]()->std::string{ + // backwards compatibility + if (Corrade::Utility::String::endsWith(filename, "ptex_quad_mesh.ply")) { + return (Corrade::Utility::String::stripSuffix(filename, "ptex_quad_mesh.ply") + + "ptex_textures"); + } + // officially released Replica dataset + return (Corrade::Utility::String::stripSuffix(filename, "mesh.ply") + + "textures"); + }; meshes_.emplace_back(std::make_unique()); int index = meshes_.size() - 1; auto* pTexMeshData = dynamic_cast(meshes_[index].get()); - pTexMeshData->load(filename, atlasDir); + pTexMeshData->load(filename, atlasDir()); // update the dictionary resourceDict_.emplace(filename, MeshMetaData(index, index)); From 542d34fdb379d20a70a38db8169eb3eb2c2b4ef6 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Tue, 6 Aug 2019 15:34:21 -0700 Subject: [PATCH 02/24] pTexmeshdata -) fix bug: numBytes -) load customized image (.rgb file) using file to memory mapping; --- src/esp/assets/PTexMeshData.cpp | 41 +++++++++++++++++++++++++++++---- src/esp/assets/PTexMeshData.h | 19 +++++++++++++-- src/esp/core/logging.h | 1 + 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 8551e5b1fd..0d525d39d7 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -4,12 +4,16 @@ #include "PTexMeshData.h" +#include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -21,6 +25,19 @@ #include "esp/io/io.h" #include "esp/io/json.h" +#if __linux__ +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22) +#define _MAP_POPULATE_AVAILABLE +#endif +#endif + +#ifdef _MAP_POPULATE_AVAILABLE +#define MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE) +#else +#define MMAP_FLAGS MAP_PRIVATE +#endif + static constexpr int ROTATION_SHIFT = 30; static constexpr int FACE_MASK = 0x3FFFFFFF; @@ -613,6 +630,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { currentMesh->abo); currentMesh->abo.setData(adjFaces[iMesh], Magnum::GL::BufferUsage::StaticDraw); + + // experiment code (may not work): currentMesh->mesh.setPrimitive(Magnum::GL::MeshPrimitive::LinesAdjacency) .setCount(currentMesh->ibo.size() / 2) .addVertexBuffer(currentMesh->vbo, 0, gfx::PTexMeshShader::Position{}) @@ -627,16 +646,27 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { const std::string rgbFile = Corrade::Utility::Directory::join( atlasFolder_, std::to_string(iMesh) + "-color-ptex.rgb"); - ASSERT(io::exists(rgbFile)); + ASSERT(io::exists(rgbFile), Error : Cannot find the rgb file); std::cout << "\rLoading atlas " << iMesh + 1 << "/" << renderingBuffers_.size() << " from " << rgbFile << "... "; std::cout.flush(); - Cr::Containers::Array data = - Cr::Utility::Directory::mapRead(rgbFile); - const int dim = static_cast(std::sqrt(data.size() / 3)); // square + const size_t numBytes = io::fileSize(rgbFile); + const int dim = static_cast(std::sqrt(numBytes / 3)); // square + + // Open file + int fd = open(std::string(rgbFile).c_str(), O_RDONLY, 0); + // MAP_POPULATE does not work on mac. It is to reduce the penalty of page + // faults. Code should be OK without it. void* mmappedData = mmap(NULL, + // numBytes, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0); + void* mmappedData = mmap(NULL, numBytes, PROT_READ, MAP_PRIVATE, fd, 0); + + Corrade::Containers::ArrayView data( + (unsigned char*)(mmappedData), numBytes); + // atlas + // the size of each image is dim x dim x 3 (RGB), which equals to numBytes Magnum::ImageView2D image(Magnum::PixelFormat::RGB8UI, {dim, dim}, data); renderingBuffers_[iMesh] ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) @@ -645,6 +675,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) .setSubImage(0, {}, image); + munmap(mmappedData, numBytes); + close(fd); + std::cout << "done" << std::endl; } diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index e7d8407f35..86b4eefdf8 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -42,8 +42,7 @@ class PTexMeshData : public BaseMesh { // ==== geometry ==== void load(const std::string& meshFile, const std::string& atlasFolder); - float exposure() const; - void setExposure(const float& val); + uint32_t tileSize() const { return tileSize_; } const std::vector& meshes() const; @@ -61,13 +60,29 @@ class PTexMeshData : public BaseMesh { virtual void uploadBuffersToGPU(bool forceReload = false) override; virtual Magnum::GL::Mesh* getMagnumGLMesh(int submeshID) override; + float exposure() const; + void setExposure(const float& val); + + // TODO: + float gamma() const; + void setGamma(const float& val); + + float saturation() const; + void setSaturation(const float& val); + protected: void loadMeshData(const std::string& meshFile); float splitSize_ = 0.0f; uint32_t tileSize_ = 0; + float exposure_ = 1.0f; + float gamma_ = 1.0f; + float saturation_ = 1.0f; + bool isHdr_ = false; + std::string atlasFolder_; + std::vector submeshes_; // ==== rendering ==== diff --git a/src/esp/core/logging.h b/src/esp/core/logging.h index ad4a9cbd34..ce72b97d9a 100644 --- a/src/esp/core/logging.h +++ b/src/esp/core/logging.h @@ -15,6 +15,7 @@ if (!(x)) { \ std::cout << "Assert failed: " #x << ", " << __FILE__ << ":" << __LINE__ \ << std::endl; \ + std::cout << #__VA_ARGS__ << std::endl; \ exit(-1); \ } \ } while (false) From 68852973a1934caf81dc7528248c508410d00fd9 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Tue, 6 Aug 2019 15:38:30 -0700 Subject: [PATCH 03/24] remove unnecessary macros --- src/esp/assets/PTexMeshData.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 0d525d39d7..805587f7f2 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -18,26 +18,12 @@ #include #include #include -// #include #include "esp/core/esp.h" #include "esp/gfx/PTexMeshShader.h" #include "esp/io/io.h" #include "esp/io/json.h" -#if __linux__ -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22) -#define _MAP_POPULATE_AVAILABLE -#endif -#endif - -#ifdef _MAP_POPULATE_AVAILABLE -#define MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE) -#else -#define MMAP_FLAGS MAP_PRIVATE -#endif - static constexpr int ROTATION_SHIFT = 30; static constexpr int FACE_MASK = 0x3FFFFFFF; From 809ab0ae8f08a2ed8a0bbd66af7479ced87daf6d Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 12:16:22 -0700 Subject: [PATCH 04/24] -) revert the mmap; -) atlasDir; --- src/esp/assets/Asset.cpp | 4 +-- src/esp/assets/PTexMeshData.cpp | 57 ++++++++++++++++++------------ src/esp/assets/PTexMeshData.h | 6 ++++ src/esp/assets/ResourceManager.cpp | 20 +++++------ 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/esp/assets/Asset.cpp b/src/esp/assets/Asset.cpp index 59e75b9ffc..c2c90e538b 100644 --- a/src/esp/assets/Asset.cpp +++ b/src/esp/assets/Asset.cpp @@ -21,9 +21,7 @@ AssetInfo AssetInfo::fromPath(const std::string& path) { } else if (endsWith(path, "ptex_quad_mesh.ply")) { info.type = AssetType::FRL_PTEX_MESH; } else if (endsWith(path, "mesh.ply")) { - // Warning: - // The order of if clause matters. cannot move "mesh.ply" before - // "ptex_quad_mesh.ply" or "semantic_quad_mesh.ply" + ASSERT(!endsWith(path, "quad_mesh.ply")); info.type = AssetType::FRL_PTEX_MESH; } else if (endsWith(path, "house.json")) { info.type = AssetType::SUNCG_SCENE; diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 805587f7f2..b78fd0fa23 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -4,9 +4,6 @@ #include "PTexMeshData.h" -#include -#include -#include #include #include #include @@ -16,6 +13,7 @@ #include #include #include +#include #include #include @@ -27,8 +25,6 @@ static constexpr int ROTATION_SHIFT = 30; static constexpr int FACE_MASK = 0x3FFFFFFF; -namespace Cr = Corrade; - namespace esp { namespace assets { @@ -513,8 +509,9 @@ void PTexMeshData::parsePLY(const std::string& filename, file.close(); - Cr::Containers::Array - mmappedData = Cr::Utility::Directory::mapRead(filename); + Corrade::Containers::Array + mmappedData = Corrade::Utility::Directory::mapRead(filename); const size_t fileSize = io::fileSize(filename); @@ -574,6 +571,30 @@ void PTexMeshData::parsePLY(const std::string& filename, } } +bool PTexMeshData::loadAdjacency(const std::string& filename, + std::vector>& adjFaces) { + if (!io::exists(filename)) { + return false; + } + std::ifstream file; + file.open(filename, std::ios::in | std::ios::binary); + + file.close(); + return true; +} + +void PTexMeshData::saveAdjacency(const std::string& filename, + std::vector>& adjFaces) { + std::ofstream file; + file.open(filename, std::ios::out | std::ios::binary); + if (!file.good()) { + std::cout << "Error: cannot open " << filename << " to save the adjacency." + << std::endl; + return; + } + file.close(); +} + void PTexMeshData::uploadBuffersToGPU(bool forceReload) { if (forceReload) { buffersOnGPU_ = false; @@ -638,18 +659,11 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { << renderingBuffers_.size() << " from " << rgbFile << "... "; std::cout.flush(); - const size_t numBytes = io::fileSize(rgbFile); - const int dim = static_cast(std::sqrt(numBytes / 3)); // square - - // Open file - int fd = open(std::string(rgbFile).c_str(), O_RDONLY, 0); - // MAP_POPULATE does not work on mac. It is to reduce the penalty of page - // faults. Code should be OK without it. void* mmappedData = mmap(NULL, - // numBytes, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0); - void* mmappedData = mmap(NULL, numBytes, PROT_READ, MAP_PRIVATE, fd, 0); - - Corrade::Containers::ArrayView data( - (unsigned char*)(mmappedData), numBytes); + Corrade::Containers::Array + data = Corrade::Utility::Directory::mapRead(rgbFile); + // divided by 3, since there are 3 channels, R, G, B, each of which takes 1 byte + const int dim = static_cast(std::sqrt(data.size() / 3)); // square // atlas // the size of each image is dim x dim x 3 (RGB), which equals to numBytes @@ -658,12 +672,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) - // .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) + .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) .setSubImage(0, {}, image); - munmap(mmappedData, numBytes); - close(fd); - std::cout << "done" << std::endl; } diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index 86b4eefdf8..ed8a10525b 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -55,6 +55,12 @@ class PTexMeshData : public BaseMesh { static void calculateAdjacency(const MeshData& mesh, std::vector& adjFaces); + // return true, if the data are loaded successfully + static bool loadAdjacency(const std::string& filename, + std::vector>& adjFaces); + static void saveAdjacency(const std::string& filename, + std::vector>& adjFaces); + // ==== rendering ==== RenderingBuffer* getRenderingBuffer(int submeshID); virtual void uploadBuffersToGPU(bool forceReload = false) override; diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index 69240c2e4c..81fb6f2211 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -105,21 +106,18 @@ bool ResourceManager::loadPTexMeshData(const AssetInfo& info, // if this is a new file, load it and add it to the dictionary const std::string& filename = info.filepath; if (resourceDict_.count(filename) == 0) { - const auto atlasDir = [=]()->std::string{ - // backwards compatibility - if (Corrade::Utility::String::endsWith(filename, "ptex_quad_mesh.ply")) { - return (Corrade::Utility::String::stripSuffix(filename, "ptex_quad_mesh.ply") + - "ptex_textures"); - } - // officially released Replica dataset - return (Corrade::Utility::String::stripSuffix(filename, "mesh.ply") + - "textures"); - }; + + const auto atlasDir = + Corrade::Utility::String::endsWith(filename, "ptex_quad_mesh.ply") + ? Corrade::Utility::Directory::join( + Corrade::Utility::Directory::path(filename), "ptex_textures") + : Corrade::Utility::Directory::join( + Corrade::Utility::Directory::path(filename), "textures"); meshes_.emplace_back(std::make_unique()); int index = meshes_.size() - 1; auto* pTexMeshData = dynamic_cast(meshes_[index].get()); - pTexMeshData->load(filename, atlasDir()); + pTexMeshData->load(filename, atlasDir); // update the dictionary resourceDict_.emplace(filename, MeshMetaData(index, index)); From 97eeb0fbac96ee1c18415bd4b112a200340db702 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 14:29:05 -0700 Subject: [PATCH 05/24] save and load the adjacent faces --- src/esp/assets/PTexMeshData.cpp | 49 +++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index b78fd0fa23..04b86b7710 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -579,6 +579,18 @@ bool PTexMeshData::loadAdjacency(const std::string& filename, std::ifstream file; file.open(filename, std::ios::in | std::ios::binary); + uint64_t numSubMeshes = 0; + file.read((char*)&numSubMeshes, sizeof(uint64_t)); + adjFaces.resize(numSubMeshes); + + for (uint64_t iMesh = 0; iMesh < numSubMeshes; ++iMesh) { + uint64_t numAdjFaces = 0; + file.read((char*)&numAdjFaces, sizeof(uint64_t)); + adjFaces[iMesh].resize(numAdjFaces); + uint32_t* data = adjFaces[iMesh].data(); + file.read((char*)data, sizeof(uint32_t) * numAdjFaces); + } + file.close(); return true; } @@ -592,6 +604,22 @@ void PTexMeshData::saveAdjacency(const std::string& filename, << std::endl; return; } + + // storage: + // a uint64_t, to save the number of submeshes (N); + // followed by N items, each of which: + // a uint64_t, to save the number of adjacent faces (M) of submesh_j, then + // M uint32_t numbers, each of which is the adjacent face ID + + uint64_t numSubMeshes = adjFaces.size(); + file.write((char*)&numSubMeshes, sizeof(uint64_t)); + + for (uint64_t iMesh = 0; iMesh < numSubMeshes; ++iMesh) { + uint64_t numAdjFaces = adjFaces[iMesh].size(); + file.write((char*)&numAdjFaces, sizeof(uint64_t)); + file.write((char*)adjFaces[iMesh].data(), sizeof(uint32_t) * numAdjFaces); + } + file.close(); } @@ -619,16 +647,26 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { } std::cout << "done" << std::endl; - std::cout << "Calculating mesh adjacency... "; + std::cout << "Calculating mesh adjacency... " << std::endl; std::cout.flush(); std::vector> adjFaces(submeshes_.size()); + // load it if it is computed before. + // otherwise compute it once and save it for future usage. + const std::string adjFaceFilename = + Corrade::Utility::Directory::join(atlasFolder_, "../mesh.adjacency"); + if (!loadAdjacency(adjFaceFilename, adjFaces)) { #pragma omp parallel for - for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { - calculateAdjacency(submeshes_[iMesh], adjFaces[iMesh]); + for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { + calculateAdjacency(submeshes_[iMesh], adjFaces[iMesh]); + } + saveAdjacency(adjFaceFilename, adjFaces); + std::cout << "Done: it is computed and saved to: " << adjFaceFilename + << std::endl; + } else { + std::cout << "Done: Loaded it from " << adjFaceFilename << std::endl; } - std::cout << "... done" << std::endl; for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; @@ -662,7 +700,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { Corrade::Containers::Array data = Corrade::Utility::Directory::mapRead(rgbFile); - // divided by 3, since there are 3 channels, R, G, B, each of which takes 1 byte + // divided by 3, since there are 3 channels, R, G, B, each of which takes 1 + // byte const int dim = static_cast(std::sqrt(data.size() / 3)); // square // atlas From 17c982fcb2d7803982d3e32be205a84255d3690f Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 14:58:12 -0700 Subject: [PATCH 06/24] minor --- src/esp/assets/PTexMeshData.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 04b86b7710..797e2a0696 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -655,12 +655,14 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // load it if it is computed before. // otherwise compute it once and save it for future usage. const std::string adjFaceFilename = - Corrade::Utility::Directory::join(atlasFolder_, "../mesh.adjacency"); + Corrade::Utility::Directory::join(atlasFolder_, "../adjFaces.bin"); if (!loadAdjacency(adjFaceFilename, adjFaces)) { #pragma omp parallel for for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { calculateAdjacency(submeshes_[iMesh], adjFaces[iMesh]); } + // Warning: you should have enough disk space to store the info + // it usually takes a couple of 100MB (usually 200+MB). saveAdjacency(adjFaceFilename, adjFaces); std::cout << "Done: it is computed and saved to: " << adjFaceFilename << std::endl; From df7f34f76b6db9d9a09da7b4b27b4eaba9adac45 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 15:03:41 -0700 Subject: [PATCH 07/24] minor --- src/esp/assets/PTexMeshData.cpp | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 797e2a0696..b3ae702589 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -282,14 +282,14 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, void PTexMeshData::loadMeshData(const std::string& meshFile) { PTexMeshData::MeshData originalMesh; - std::cout << "start parsing PLY... " << std::endl; + LOG(INFO) << "start parsing PLY... " << std::endl; parsePLY(meshFile, originalMesh); submeshes_.clear(); if (splitSize_ > 0.0f) { - std::cout << "Splitting mesh... "; + LOG(INFO) << "Splitting mesh... "; submeshes_ = splitMesh(originalMesh, splitSize_); - std::cout << "done" << std::endl; + LOG(INFO) << "done" << std::endl; } else { submeshes_.emplace_back(std::move(originalMesh)); } @@ -550,12 +550,12 @@ void PTexMeshData::parsePLY(const std::string& filename, // Not sure what to do here // if(predictedFaces < numFaces) // { - // std::cout << "Skipping " << numFaces - predictedFaces << " missing + // LOG(INFO) << "Skipping " << numFaces - predictedFaces << " missing // faces" << std::endl; // } // else if(numFaces < predictedFaces) // { - // std::cout << "Ignoring " << predictedFaces - numFaces << " extra + // LOG(INFO) << "Ignoring " << predictedFaces - numFaces << " extra // faces" << std::endl; // } @@ -600,7 +600,7 @@ void PTexMeshData::saveAdjacency(const std::string& filename, std::ofstream file; file.open(filename, std::ios::out | std::ios::binary); if (!file.good()) { - std::cout << "Error: cannot open " << filename << " to save the adjacency." + LOG(INFO) << "Error: cannot open " << filename << " to save the adjacency." << std::endl; return; } @@ -632,9 +632,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { } for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { - std::cout << "\rLoading mesh " << iMesh + 1 << "/" << submeshes_.size() + LOG(INFO) << "\rLoading mesh " << iMesh + 1 << "/" << submeshes_.size() << "... "; - std::cout.flush(); + LOG(INFO).flush(); renderingBuffers_.emplace_back( std::make_unique()); @@ -645,10 +645,10 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { currentMesh->ibo.setData(submeshes_[iMesh].ibo, Magnum::GL::BufferUsage::StaticDraw); } - std::cout << "done" << std::endl; + LOG(INFO) << "done" << std::endl; - std::cout << "Calculating mesh adjacency... " << std::endl; - std::cout.flush(); + LOG(INFO) << "Calculating mesh adjacency... " << std::endl; + LOG(INFO).flush(); std::vector> adjFaces(submeshes_.size()); @@ -664,10 +664,10 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // Warning: you should have enough disk space to store the info // it usually takes a couple of 100MB (usually 200+MB). saveAdjacency(adjFaceFilename, adjFaces); - std::cout << "Done: it is computed and saved to: " << adjFaceFilename + LOG(INFO) << "Done: it is computed and saved to: " << adjFaceFilename << std::endl; } else { - std::cout << "Done: Loaded it from " << adjFaceFilename << std::endl; + LOG(INFO) << "Done: Loaded it from " << adjFaceFilename << std::endl; } for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { @@ -688,16 +688,16 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // load atlas data and upload them to GPU - std::cout << "loading atlas textures: " << std::endl; + LOG(INFO) << "loading atlas textures: " << std::endl; for (size_t iMesh = 0; iMesh < renderingBuffers_.size(); ++iMesh) { const std::string rgbFile = Corrade::Utility::Directory::join( atlasFolder_, std::to_string(iMesh) + "-color-ptex.rgb"); ASSERT(io::exists(rgbFile), Error : Cannot find the rgb file); - std::cout << "\rLoading atlas " << iMesh + 1 << "/" + LOG(INFO) << "\rLoading atlas " << iMesh + 1 << "/" << renderingBuffers_.size() << " from " << rgbFile << "... "; - std::cout.flush(); + LOG(INFO).flush(); Corrade::Containers::Array @@ -716,7 +716,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) .setSubImage(0, {}, image); - std::cout << "done" << std::endl; + LOG(INFO) << "done" << std::endl; } buffersOnGPU_ = true; From 3ee45ed0f77d4d107c2a5aa8f409c047bdee7d09 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 15:21:37 -0700 Subject: [PATCH 08/24] minor --- src/esp/assets/PTexMeshData.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index c5080512c6..5e60bbfc58 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -289,7 +289,7 @@ void PTexMeshData::loadMeshData(const std::string& meshFile) { if (splitSize_ > 0.0f) { LOG(INFO) << "Splitting mesh... "; submeshes_ = splitMesh(originalMesh, splitSize_); - LOG(INFO) << "done" << std::endl; + LOG(INFO) << "Splitting mesh: Done" << std::endl; } else { submeshes_.emplace_back(std::move(originalMesh)); } @@ -633,8 +633,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { LOG(INFO) << "\rLoading mesh " << iMesh + 1 << "/" << submeshes_.size() - << "... "; - LOG(INFO).flush(); + << "... " << std::endl; renderingBuffers_.emplace_back( std::make_unique()); @@ -645,10 +644,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { currentMesh->ibo.setData(submeshes_[iMesh].ibo, Magnum::GL::BufferUsage::StaticDraw); } - LOG(INFO) << "done" << std::endl; LOG(INFO) << "Calculating mesh adjacency... " << std::endl; - std::vector> adjFaces(submeshes_.size()); // load it if it is computed before. @@ -696,7 +693,6 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { LOG(INFO) << "\rLoading atlas " << iMesh + 1 << "/" << renderingBuffers_.size() << " from " << rgbFile << "... "; - LOG(INFO).flush(); Corrade::Containers::Array @@ -714,8 +710,6 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) .setSubImage(0, {}, image); - - LOG(INFO) << "done" << std::endl; } buffersOnGPU_ = true; } From 940df4ee4a563c09d6215229e8638a2f7e5d77a0 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 7 Aug 2019 16:38:19 -0700 Subject: [PATCH 09/24] Stop supporting the old format. Based on offline sync, we would like to only support the public released replica models. --- src/esp/assets/Asset.cpp | 7 +------ src/esp/assets/PTexMeshData.cpp | 27 ++++++++++++++------------- src/esp/assets/PTexMeshData.h | 1 - src/esp/assets/ResourceManager.cpp | 11 +++-------- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/esp/assets/Asset.cpp b/src/esp/assets/Asset.cpp index c2c90e538b..5fc137c551 100644 --- a/src/esp/assets/Asset.cpp +++ b/src/esp/assets/Asset.cpp @@ -14,14 +14,9 @@ using namespace Corrade::Utility::String; AssetInfo AssetInfo::fromPath(const std::string& path) { AssetInfo info{AssetType::UNKNOWN, path}; - if (endsWith(path, "semantic_quad_mesh.ply")) { - info.type = AssetType::FRL_INSTANCE_MESH; - } else if (endsWith(path, "_semantic.ply")) { + if (endsWith(path, "_semantic.ply")) { info.type = AssetType::INSTANCE_MESH; - } else if (endsWith(path, "ptex_quad_mesh.ply")) { - info.type = AssetType::FRL_PTEX_MESH; } else if (endsWith(path, "mesh.ply")) { - ASSERT(!endsWith(path, "quad_mesh.ply")); info.type = AssetType::FRL_PTEX_MESH; } else if (endsWith(path, "house.json")) { info.type = AssetType::SUNCG_SCENE; diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 5e60bbfc58..903f74290e 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -657,7 +657,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { calculateAdjacency(submeshes_[iMesh], adjFaces[iMesh]); } - // Warning: you should have enough disk space to store the info + // Warning: you should have enough disk space to store the info // it usually takes a couple of 100MB (usually 200+MB). saveAdjacency(adjFaceFilename, adjFaces); LOG(INFO) << "Done: it is computed and saved to: " << adjFaceFilename @@ -683,32 +683,33 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { } // load atlas data and upload them to GPU - LOG(INFO) << "loading atlas textures: " << std::endl; for (size_t iMesh = 0; iMesh < renderingBuffers_.size(); ++iMesh) { - const std::string rgbFile = Corrade::Utility::Directory::join( - atlasFolder_, std::to_string(iMesh) + "-color-ptex.rgb"); + const std::string hdrFile = Corrade::Utility::Directory::join( + atlasFolder_, std::to_string(iMesh) + "-color-ptex.hdr"); - ASSERT(io::exists(rgbFile), Error : Cannot find the rgb file); + ASSERT(io::exists(hdrFile), Error : Cannot find the.hdr file); LOG(INFO) << "\rLoading atlas " << iMesh + 1 << "/" - << renderingBuffers_.size() << " from " << rgbFile << "... "; + << renderingBuffers_.size() << " from " << hdrFile << "... "; Corrade::Containers::Array - data = Corrade::Utility::Directory::mapRead(rgbFile); - // divided by 3, since there are 3 channels, R, G, B, each of which takes 1 - // byte - const int dim = static_cast(std::sqrt(data.size() / 3)); // square + data = Corrade::Utility::Directory::mapRead(hdrFile); + // divided by 6, since there are 3 channels, R, G, B, each of which takes 1 + // half_float (2 bytes) + const int dim = static_cast(std::sqrt(data.size() / 6)); // square // atlas - // the size of each image is dim x dim x 3 (RGB), which equals to numBytes - Magnum::ImageView2D image(Magnum::PixelFormat::RGB8UI, {dim, dim}, data); + // the size of each image is dim x dim x 3 (RGB) x 2 (half_float), which + // equals to numBytes + Magnum::ImageView2D image(Magnum::PixelFormat::RGB16F, {dim, dim}, data); + const int mipLevelCount = 1; renderingBuffers_[iMesh] ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) - .setStorage(1, Magnum::GL::TextureFormat::RGB8UI, image.size()) + .setStorage(mipLevelCount, Magnum::GL::TextureFormat::RGB16F, image.size()) .setSubImage(0, {}, image); } buffersOnGPU_ = true; diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index ed8a10525b..a7c6c5549d 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -85,7 +85,6 @@ class PTexMeshData : public BaseMesh { float exposure_ = 1.0f; float gamma_ = 1.0f; float saturation_ = 1.0f; - bool isHdr_ = false; std::string atlasFolder_; diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index e806dd93ab..210335b186 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include #include #include @@ -112,13 +112,8 @@ bool ResourceManager::loadPTexMeshData(const AssetInfo& info, // if this is a new file, load it and add it to the dictionary const std::string& filename = info.filepath; if (resourceDict_.count(filename) == 0) { - - const auto atlasDir = - Corrade::Utility::String::endsWith(filename, "ptex_quad_mesh.ply") - ? Corrade::Utility::Directory::join( - Corrade::Utility::Directory::path(filename), "ptex_textures") - : Corrade::Utility::Directory::join( - Corrade::Utility::Directory::path(filename), "textures"); + const auto atlasDir = Corrade::Utility::Directory::join( + Corrade::Utility::Directory::path(filename), "textures"); meshes_.emplace_back(std::make_unique()); int index = meshes_.size() - 1; From 9aae2d8ffc4dafa85b8e5dc8029eed5d71b22178 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Fri, 9 Aug 2019 11:02:41 -0700 Subject: [PATCH 10/24] minor --- src/esp/assets/PTexMeshData.cpp | 44 ++++++++++++++++++++++----------- src/esp/assets/PTexMeshData.h | 1 - src/esp/core/logging.h | 16 ++++++------ 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 903f74290e..3da64f2910 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -55,6 +55,22 @@ void PTexMeshData::setExposure(const float& val) { exposure_ = val; } +float PTexMeshData::gamma() const { + return gamma_; +} + +void PTexMeshData::setGamma(const float& val) { + gamma_ = val; +} + +float PTexMeshData::saturation() const { + return saturation_; +} + +void PTexMeshData::setSaturation(const float& val) { + saturation_ = val; +} + const std::vector& PTexMeshData::meshes() const { return submeshes_; } @@ -282,14 +298,15 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, void PTexMeshData::loadMeshData(const std::string& meshFile) { PTexMeshData::MeshData originalMesh; - LOG(INFO) << "start parsing PLY... " << std::endl; + LOG(INFO) << "Start parsing PLY... "; parsePLY(meshFile, originalMesh); + LOG(INFO) << "Parsing PLY: Done"; submeshes_.clear(); if (splitSize_ > 0.0f) { LOG(INFO) << "Splitting mesh... "; submeshes_ = splitMesh(originalMesh, splitSize_); - LOG(INFO) << "Splitting mesh: Done" << std::endl; + LOG(INFO) << "Splitting mesh: Done"; } else { submeshes_.emplace_back(std::move(originalMesh)); } @@ -600,8 +617,7 @@ void PTexMeshData::saveAdjacency(const std::string& filename, std::ofstream file; file.open(filename, std::ios::out | std::ios::binary); if (!file.good()) { - LOG(INFO) << "Error: cannot open " << filename << " to save the adjacency." - << std::endl; + LOG(INFO) << "Error: cannot open " << filename << " to save the adjacency."; return; } @@ -632,8 +648,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { } for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { - LOG(INFO) << "\rLoading mesh " << iMesh + 1 << "/" << submeshes_.size() - << "... " << std::endl; + LOG(INFO) << "Loading mesh " << iMesh + 1 << "/" << submeshes_.size() + << ". "; renderingBuffers_.emplace_back( std::make_unique()); @@ -645,7 +661,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { Magnum::GL::BufferUsage::StaticDraw); } - LOG(INFO) << "Calculating mesh adjacency... " << std::endl; + LOG(INFO) << "Calculating mesh adjacency... "; std::vector> adjFaces(submeshes_.size()); // load it if it is computed before. @@ -660,10 +676,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // Warning: you should have enough disk space to store the info // it usually takes a couple of 100MB (usually 200+MB). saveAdjacency(adjFaceFilename, adjFaces); - LOG(INFO) << "Done: it is computed and saved to: " << adjFaceFilename - << std::endl; + LOG(INFO) << "Done: it is computed and saved to: " << adjFaceFilename; } else { - LOG(INFO) << "Done: Loaded it from " << adjFaceFilename << std::endl; + LOG(INFO) << "Done: Loaded it from " << adjFaceFilename; } for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { @@ -683,15 +698,15 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { } // load atlas data and upload them to GPU - LOG(INFO) << "loading atlas textures: " << std::endl; + LOG(INFO) << "loading atlas textures: "; for (size_t iMesh = 0; iMesh < renderingBuffers_.size(); ++iMesh) { const std::string hdrFile = Corrade::Utility::Directory::join( atlasFolder_, std::to_string(iMesh) + "-color-ptex.hdr"); ASSERT(io::exists(hdrFile), Error : Cannot find the.hdr file); - LOG(INFO) << "\rLoading atlas " << iMesh + 1 << "/" - << renderingBuffers_.size() << " from " << hdrFile << "... "; + LOG(INFO) << "Loading atlas " << iMesh + 1 << "/" + << renderingBuffers_.size() << " from " << hdrFile << ". "; Corrade::Containers::Array @@ -709,7 +724,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) - .setStorage(mipLevelCount, Magnum::GL::TextureFormat::RGB16F, image.size()) + .setStorage(mipLevelCount, Magnum::GL::TextureFormat::RGB16F, + image.size()) .setSubImage(0, {}, image); } buffersOnGPU_ = true; diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index a7c6c5549d..b2c0bf6eaf 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -69,7 +69,6 @@ class PTexMeshData : public BaseMesh { float exposure() const; void setExposure(const float& val); - // TODO: float gamma() const; void setGamma(const float& val); diff --git a/src/esp/core/logging.h b/src/esp/core/logging.h index 179ded338d..cf19cd69ac 100644 --- a/src/esp/core/logging.h +++ b/src/esp/core/logging.h @@ -43,12 +43,12 @@ class LogMessageVoidify { #include #endif -#define ASSERT(x, ...) \ - do { \ - if (!(x)) { \ - LOG(ERROR) << "Assert failed: " #x << ", " << __FILE__ << ":" << __LINE__ \ - << std::endl; \ - LOG(ERROR) << #__VA_ARGS__ << std::endl; \ - exit(-1); \ - } \ +#define ASSERT(x, ...) \ + do { \ + if (!(x)) { \ + LOG(ERROR) << "Assert failed: " #x << ", " << __FILE__ << ":" \ + << __LINE__ << std::endl; \ + LOG(ERROR) << #__VA_ARGS__ << std::endl; \ + exit(-1); \ + } \ } while (false) From e2ed28c24de054f05a4a0945b8b6e70c08a19292 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Mon, 12 Aug 2019 16:37:23 -0700 Subject: [PATCH 11/24] working on the shaders - add gamma, saturation; - change the line_adjacency; - change the shader: texelFetch(...).r; --- src/esp/assets/PTexMeshData.cpp | 7 +++--- src/esp/assets/PTexMeshData.h | 2 +- src/esp/gfx/PTexMeshDrawable.cpp | 11 +++++---- src/esp/gfx/PTexMeshDrawable.h | 5 +++- src/esp/gfx/PTexMeshShader.h | 17 ++++++++++--- src/shaders/ptex-default-gl410.frag | 31 ++++++++++++++++++------ src/shaders/ptex-default-gl410.geom | 37 +++++++++++++++++------------ src/shaders/ptex-default-gl410.vert | 8 +++++-- 8 files changed, 82 insertions(+), 36 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 3da64f2910..0cd0b8866e 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -684,14 +684,15 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; - currentMesh->adjTex.setBuffer(Magnum::GL::BufferTextureFormat::R32UI, - currentMesh->abo); + currentMesh->adjFaces.setBuffer(Magnum::GL::BufferTextureFormat::R32UI, + currentMesh->abo); currentMesh->abo.setData(adjFaces[iMesh], Magnum::GL::BufferUsage::StaticDraw); // experiment code (may not work): + // using GL_LINES_ADJACENCY here to send quads to geometry shader currentMesh->mesh.setPrimitive(Magnum::GL::MeshPrimitive::LinesAdjacency) - .setCount(currentMesh->ibo.size() / 2) + .setCount(currentMesh->ibo.size()) .addVertexBuffer(currentMesh->vbo, 0, gfx::PTexMeshShader::Position{}) .setIndexBuffer(currentMesh->ibo, 0, Magnum::GL::MeshIndexType::UnsignedInt); diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index b2c0bf6eaf..d60aa5b490 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -34,7 +34,7 @@ class PTexMeshData : public BaseMesh { Magnum::GL::Buffer vbo; Magnum::GL::Buffer ibo; Magnum::GL::Buffer abo; - Magnum::GL::BufferTexture adjTex; + Magnum::GL::BufferTexture adjFaces; }; PTexMeshData() : BaseMesh(SupportedMeshType::PTEX_MESH) {} diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index a391cb33e1..57e14eeb8b 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -18,16 +18,19 @@ PTexMeshDrawable::PTexMeshDrawable( : Drawable{node, shader, ptexMeshData.getRenderingBuffer(submeshID)->mesh, group}, tex_(ptexMeshData.getRenderingBuffer(submeshID)->tex), - adjTex_(ptexMeshData.getRenderingBuffer(submeshID)->adjTex), + adjFaces_(ptexMeshData.getRenderingBuffer(submeshID)->adjFaces), tileSize_(ptexMeshData.tileSize()), - exposure_(ptexMeshData.exposure()) {} + exposure_(ptexMeshData.exposure()), + gamma_(ptexMeshData.gamma()), + saturation_(ptexMeshData.saturation()) {} void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, Magnum::SceneGraph::Camera3D& camera) { - adjTex_.bind(1); + adjFaces_.bind(1); PTexMeshShader& ptexMeshShader = static_cast(shader_); ptexMeshShader.bindTexture(tex_, 0) - .setPTexUniforms(tex_, tileSize_, exposure_) + .setPTexUniforms(tex_, tileSize_, exposure_, gamma_, saturation_) + .setClipPlane(clipPlane_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); mesh_.draw(ptexMeshShader); } diff --git a/src/esp/gfx/PTexMeshDrawable.h b/src/esp/gfx/PTexMeshDrawable.h index a5d7c7d5ce..812d79aac9 100644 --- a/src/esp/gfx/PTexMeshDrawable.h +++ b/src/esp/gfx/PTexMeshDrawable.h @@ -29,9 +29,12 @@ class PTexMeshDrawable : public Drawable { Magnum::SceneGraph::Camera3D& camera) override; Magnum::GL::Texture2D& tex_; - Magnum::GL::BufferTexture& adjTex_; + Magnum::GL::BufferTexture& adjFaces_; uint32_t tileSize_; float exposure_; + float gamma_; + float saturation_; + Magnum::Vector4 clipPlane_{0.0f, 0.0f, 0.0f, 0.0f}; }; } // namespace gfx diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index c0976626e2..dc92ee0302 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -38,18 +38,27 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { return *this; } + PTexMeshShader& setClipPlane(const Magnum::Vector4& clipPlane) { + setUniform(uniformLocation("clipPlane"), clipPlane); + return *this; + } + PTexMeshShader& setPTexUniforms(assets::PTexMeshData& ptexMeshData, int submeshID, uint32_t tileSize, - float exposure) { + float exposure, + float gamma, + float saturation) { setPTexUniforms(ptexMeshData.getRenderingBuffer(submeshID)->tex, tileSize, - exposure); + exposure, gamma, saturation); return *this; } PTexMeshShader& setPTexUniforms(Magnum::GL::Texture2D& tex, uint32_t tileSize, - float exposure) { + float exposure, + float gamma, + float saturation) { setUniform(uniformLocation("atlasTex"), 0); setUniform(uniformLocation("tileSize"), (int)tileSize); // Image size in given mip level 0 @@ -60,6 +69,8 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { setUniform(uniformLocation("widthInTiles"), int(width / tileSize)); } setUniform(uniformLocation("exposure"), exposure); + setUniform(uniformLocation("gamma"), gamma); + setUniform(uniformLocation("saturation"), saturation); return *this; } }; diff --git a/src/shaders/ptex-default-gl410.frag b/src/shaders/ptex-default-gl410.frag index 56542370c2..2ed9f77cd7 100644 --- a/src/shaders/ptex-default-gl410.frag +++ b/src/shaders/ptex-default-gl410.frag @@ -1,6 +1,6 @@ uniform int tileSize; uniform int widthInTiles; -uniform samplerBuffer meshAdjFaces; +uniform usamplerBuffer meshAdjFaces; ivec2 FaceToAtlasPos(int faceID, int tileSize) { ivec2 tilePos; @@ -29,7 +29,7 @@ const uint FACE_MASK = 0x3FFFFFFF; int GetAdjFace(int face, int edge, out int rot) { // uint data = meshAdjFaces[face * 4 + edge]; - uint data = uint(texelFetch(meshAdjFaces, face * 4 + edge)); + uint data = texelFetch(meshAdjFaces, face * 4 + edge).r; rot = int(data >> ROTATION_SHIFT); return int(data & FACE_MASK); } @@ -142,8 +142,8 @@ vec4 texelFetchAtlasAdj(sampler2D tex, int faceID, ivec2 p, int level) { } // fetch with bilinear filtering -vec4 textureAtlas(sampler2D tex, int faceID, vec2 p) { - int level = 0; +vec4 textureAtlas(sampler2D tex, int faceID, vec2 p, float lod) { + int level = int(lod); p -= 0.5; ivec2 i = ivec2(floor(p)); vec2 f = p - vec2(i); @@ -155,15 +155,32 @@ vec4 textureAtlas(sampler2D tex, int faceID, vec2 p) { f.y); } +void applySaturation(inout vec4 c, float saturation) { + float Pr = 0.299f; + float Pg = 0.587f; + float Pb = 0.114f; + + float P = sqrt(c.r * c.r * Pr + c.g * c.g * Pg + c.b * c.b * Pb); + + c.r = P + (c.r - P) * saturation; + c.g = P + (c.g - P) * saturation; + c.b = P + (c.b - P) * saturation; +} + layout(location = 0) out vec4 FragColor; uniform sampler2D atlasTex; uniform float exposure; +uniform float gamma; +uniform float saturation; in vec2 uv; void main() { - vec4 c = textureAtlas(atlasTex, gl_PrimitiveID, uv * tileSize) * exposure; - // c = vec4(1.0f, 1.0f, 1.0f, 1.0f); - FragColor = vec4(c.xyz, 1.0f); + float lod = 0.0f; + vec4 c = textureAtlas(atlasTex, gl_PrimitiveID, uv * tileSize, lod); + c *= exposure; + applySaturation(c, saturation); + c.rgb = pow(c.rgb, vec3(gamma)); + FragColor = vec4(c.rgb, 1.0f); } diff --git a/src/shaders/ptex-default-gl410.geom b/src/shaders/ptex-default-gl410.geom index 1075c07f9e..67cd349064 100644 --- a/src/shaders/ptex-default-gl410.geom +++ b/src/shaders/ptex-default-gl410.geom @@ -1,26 +1,33 @@ +// generates UVs for quads + layout(lines_adjacency) in; layout(triangle_strip, max_vertices = 4) out; out vec2 uv; -void main() { - gl_PrimitiveID = gl_PrimitiveIDIn; +void main() +{ + gl_PrimitiveID = gl_PrimitiveIDIn; - uv = vec2(1.0, 0.0); - gl_Position = gl_in[1].gl_Position; - EmitVertex(); + uv = vec2(1.0, 0.0); + gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0]; + gl_Position = gl_in[1].gl_Position; + EmitVertex(); - uv = vec2(0.0, 0.0); - gl_Position = gl_in[0].gl_Position; - EmitVertex(); + uv = vec2(0.0, 0.0); + gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0]; + gl_Position = gl_in[0].gl_Position; + EmitVertex(); - uv = vec2(1.0, 1.0); - gl_Position = gl_in[2].gl_Position; - EmitVertex(); + uv = vec2(1.0, 1.0); + gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0]; + gl_Position = gl_in[2].gl_Position; + EmitVertex(); - uv = vec2(0.0, 1.0); - gl_Position = gl_in[3].gl_Position; - EmitVertex(); + uv = vec2(0.0, 1.0); + gl_ClipDistance[0] = gl_in[3].gl_ClipDistance[0]; + gl_Position = gl_in[3].gl_Position; + EmitVertex(); - EndPrimitive(); + EndPrimitive(); } diff --git a/src/shaders/ptex-default-gl410.vert b/src/shaders/ptex-default-gl410.vert index 9e1088329e..e71c77ca2d 100644 --- a/src/shaders/ptex-default-gl410.vert +++ b/src/shaders/ptex-default-gl410.vert @@ -1,6 +1,10 @@ layout(location = 0) in vec4 position; + uniform mat4 MVP; +uniform vec4 clipPlane; -void main() { - gl_Position = MVP * position; +void main() +{ + gl_ClipDistance[0] = dot(position, clipPlane); + gl_Position = MVP * position; } From fb665b5edaa165ff0177b1a9ce5449e186853921 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Mon, 12 Aug 2019 17:00:04 -0700 Subject: [PATCH 12/24] format --- src/esp/assets/Asset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/esp/assets/Asset.cpp b/src/esp/assets/Asset.cpp index 5fc137c551..c752173323 100644 --- a/src/esp/assets/Asset.cpp +++ b/src/esp/assets/Asset.cpp @@ -14,7 +14,7 @@ using namespace Corrade::Utility::String; AssetInfo AssetInfo::fromPath(const std::string& path) { AssetInfo info{AssetType::UNKNOWN, path}; - if (endsWith(path, "_semantic.ply")) { + if (endsWith(path, "_semantic.ply")) { info.type = AssetType::INSTANCE_MESH; } else if (endsWith(path, "mesh.ply")) { info.type = AssetType::FRL_PTEX_MESH; From 57593bbf8bdc0e2268f432b8e89a1352091657de Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Tue, 13 Aug 2019 17:05:38 -0700 Subject: [PATCH 13/24] Add clear binding points for textures --- src/esp/assets/PTexMeshData.cpp | 1 + src/esp/gfx/PTexMeshDrawable.cpp | 17 +++++-- src/esp/gfx/PTexMeshShader.cpp | 63 +++++++++++++++++++++++--- src/esp/gfx/PTexMeshShader.h | 62 +++++++------------------ src/esp/gfx/TextureBindingPointIndex.h | 14 ++++++ 5 files changed, 100 insertions(+), 57 deletions(-) create mode 100644 src/esp/gfx/TextureBindingPointIndex.h diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 0cd0b8866e..602fb68603 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -730,6 +730,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { .setSubImage(0, {}, image); } buffersOnGPU_ = true; + LOG(INFO) << "data are uploaded to GPU."; } PTexMeshData::RenderingBuffer* PTexMeshData::getRenderingBuffer(int submeshID) { diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index 57e14eeb8b..af4396a704 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -22,15 +22,22 @@ PTexMeshDrawable::PTexMeshDrawable( tileSize_(ptexMeshData.tileSize()), exposure_(ptexMeshData.exposure()), gamma_(ptexMeshData.gamma()), - saturation_(ptexMeshData.saturation()) {} + saturation_(ptexMeshData.saturation()) { + PTexMeshShader& ptexMeshShader = static_cast(shader_); + // clipPlane is const for every ptex mesh in this version. + // Set it in the constructor, not in the draw() + ptexMeshShader.setClipPlane(clipPlane_); +} void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, Magnum::SceneGraph::Camera3D& camera) { - adjFaces_.bind(1); PTexMeshShader& ptexMeshShader = static_cast(shader_); - ptexMeshShader.bindTexture(tex_, 0) - .setPTexUniforms(tex_, tileSize_, exposure_, gamma_, saturation_) - .setClipPlane(clipPlane_) + ptexMeshShader.setExposure(exposure_) + .setGamma(gamma_) + .setSaturation(saturation_) + .setAtlasTextureSize(tex_, tileSize_) + .bindAtlasTexture(tex_) + .bindAdjFacesBufferTexture(adjFaces_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); mesh_.draw(ptexMeshShader); } diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 35a85ffc78..00b6e46055 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -2,12 +2,6 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. -#include "PTexMeshShader.h" - -#include -#include -#include - #include #include #include @@ -16,6 +10,9 @@ #include #include #include +#include +#include "PTexMeshShader.h" +#include "TextureBindingPointIndex.h" #include "esp/assets/PTexMeshData.h" #include "esp/core/esp.h" @@ -56,6 +53,60 @@ PTexMeshShader::PTexMeshShader() { attachShaders({vert, geom, frag}); CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + + // set texture binding points in the shader; + // see ptex fragment shader code for details + setUniform(uniformLocation("atlasTex"), TextureBindingPointIndex::atlas); + setUniform(uniformLocation("meshAdjFaces"), + TextureBindingPointIndex::adjFaces); +} + +PTexMeshShader& PTexMeshShader::bindAtlasTexture( + Magnum::GL::Texture2D& texture) { + texture.bind(TextureBindingPointIndex::atlas); + return *this; +} + +PTexMeshShader& PTexMeshShader::bindAdjFacesBufferTexture( + Magnum::GL::BufferTexture& texture) { + texture.bind(TextureBindingPointIndex::adjFaces); + return *this; +} + +PTexMeshShader& PTexMeshShader::setMVPMatrix(const Magnum::Matrix4& matrix) { + setUniform(uniformLocation("MVP"), matrix); + return *this; +} + +PTexMeshShader& PTexMeshShader::setExposure(float exposure) { + setUniform(uniformLocation("exposure"), exposure); + return *this; +} +PTexMeshShader& PTexMeshShader::setGamma(float gamma) { + setUniform(uniformLocation("gamma"), gamma); + return *this; +} + +PTexMeshShader& PTexMeshShader::setSaturation(float saturation) { + setUniform(uniformLocation("saturation"), saturation); + return *this; +} + +PTexMeshShader& PTexMeshShader::setClipPlane(const Magnum::Vector4& clipPlane) { + setUniform(uniformLocation("clipPlane"), clipPlane); + return *this; +} + +PTexMeshShader& PTexMeshShader::setAtlasTextureSize(Magnum::GL::Texture2D& tex, + uint32_t tileSize) { + setUniform(uniformLocation("tileSize"), (int)tileSize); + + // Image size in given mip level 0 + int mipLevel = 0; + int widthEntry = 0; + const auto width = tex.imageSize(mipLevel)[widthEntry]; + setUniform(uniformLocation("widthInTiles"), int(width / tileSize)); + return *this; } } // namespace gfx diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index dc92ee0302..364aa868fd 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -27,52 +27,22 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { explicit PTexMeshShader(); - PTexMeshShader& bindTexture(Magnum::GL::Texture2D& texture, - uint32_t textureUnit = 0) { - texture.bind(textureUnit); - return *this; - } - - PTexMeshShader& setMVPMatrix(const Magnum::Matrix4& matrix) { - setUniform(uniformLocation("MVP"), matrix); - return *this; - } - - PTexMeshShader& setClipPlane(const Magnum::Vector4& clipPlane) { - setUniform(uniformLocation("clipPlane"), clipPlane); - return *this; - } - - PTexMeshShader& setPTexUniforms(assets::PTexMeshData& ptexMeshData, - int submeshID, - uint32_t tileSize, - float exposure, - float gamma, - float saturation) { - setPTexUniforms(ptexMeshData.getRenderingBuffer(submeshID)->tex, tileSize, - exposure, gamma, saturation); - return *this; - } - - PTexMeshShader& setPTexUniforms(Magnum::GL::Texture2D& tex, - uint32_t tileSize, - float exposure, - float gamma, - float saturation) { - setUniform(uniformLocation("atlasTex"), 0); - setUniform(uniformLocation("tileSize"), (int)tileSize); - // Image size in given mip level 0 - { - int mipLevel = 0; - int widthEntry = 0; - const auto width = tex.imageSize(mipLevel)[widthEntry]; - setUniform(uniformLocation("widthInTiles"), int(width / tileSize)); - } - setUniform(uniformLocation("exposure"), exposure); - setUniform(uniformLocation("gamma"), gamma); - setUniform(uniformLocation("saturation"), saturation); - return *this; - } + // ======== texture binding ======== + // Note: the texture binding points are explicitly specified + // in TextureBindingPointIndex.h + // Cannot use "explicit uniform location" directly in shader since + // it requires GL4.3 (We stick to GL4.1 for MacOS). + PTexMeshShader& bindAtlasTexture(Magnum::GL::Texture2D& texture); + PTexMeshShader& bindAdjFacesBufferTexture(Magnum::GL::BufferTexture& texture); + + // ======== set uniforms =========== + PTexMeshShader& setMVPMatrix(const Magnum::Matrix4& matrix); + PTexMeshShader& setExposure(float exposure); + PTexMeshShader& setGamma(float gamma); + PTexMeshShader& setSaturation(float saturation); + PTexMeshShader& setClipPlane(const Magnum::Vector4& clipPlane); + PTexMeshShader& setAtlasTextureSize(Magnum::GL::Texture2D& texture, + uint32_t tileSize); }; } // namespace gfx diff --git a/src/esp/gfx/TextureBindingPointIndex.h b/src/esp/gfx/TextureBindingPointIndex.h new file mode 100644 index 0000000000..e9a0ab2525 --- /dev/null +++ b/src/esp/gfx/TextureBindingPointIndex.h @@ -0,0 +1,14 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +namespace esp { +namespace gfx { +enum TextureBindingPointIndex { + atlas = 1, + adjFaces = 2, +}; +} // namespace gfx +} // namespace esp From dd6a0ae0f7ebe2f93684fb6c3f8be498b1ca86a6 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 14 Aug 2019 14:16:17 -0700 Subject: [PATCH 14/24] cache the uniform locations --- src/esp/gfx/PTexMeshShader.cpp | 22 +++++++++++++++------- src/esp/gfx/PTexMeshShader.h | 11 +++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 00b6e46055..65d5d8b1e3 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -59,6 +59,14 @@ PTexMeshShader::PTexMeshShader() { setUniform(uniformLocation("atlasTex"), TextureBindingPointIndex::atlas); setUniform(uniformLocation("meshAdjFaces"), TextureBindingPointIndex::adjFaces); + + MVPMatrixUniform_ = uniformLocation("MVP"); + exposureUniform_ = uniformLocation("exposure"); + gammaUniform_ = uniformLocation("gamma"); + saturationUniform_ = uniformLocation("saturation"); + clipPlaneUniform_ = uniformLocation("clipPlane"); + tileSizeUniform_ = uniformLocation("tileSize"); + widthInTilesUniform_ = uniformLocation("widthInTiles"); } PTexMeshShader& PTexMeshShader::bindAtlasTexture( @@ -74,38 +82,38 @@ PTexMeshShader& PTexMeshShader::bindAdjFacesBufferTexture( } PTexMeshShader& PTexMeshShader::setMVPMatrix(const Magnum::Matrix4& matrix) { - setUniform(uniformLocation("MVP"), matrix); + setUniform(MVPMatrixUniform_, matrix); return *this; } PTexMeshShader& PTexMeshShader::setExposure(float exposure) { - setUniform(uniformLocation("exposure"), exposure); + setUniform(exposureUniform_, exposure); return *this; } PTexMeshShader& PTexMeshShader::setGamma(float gamma) { - setUniform(uniformLocation("gamma"), gamma); + setUniform(gammaUniform_, gamma); return *this; } PTexMeshShader& PTexMeshShader::setSaturation(float saturation) { - setUniform(uniformLocation("saturation"), saturation); + setUniform(saturationUniform_, saturation); return *this; } PTexMeshShader& PTexMeshShader::setClipPlane(const Magnum::Vector4& clipPlane) { - setUniform(uniformLocation("clipPlane"), clipPlane); + setUniform(clipPlaneUniform_, clipPlane); return *this; } PTexMeshShader& PTexMeshShader::setAtlasTextureSize(Magnum::GL::Texture2D& tex, uint32_t tileSize) { - setUniform(uniformLocation("tileSize"), (int)tileSize); + setUniform(tileSizeUniform_, (int)tileSize); // Image size in given mip level 0 int mipLevel = 0; int widthEntry = 0; const auto width = tex.imageSize(mipLevel)[widthEntry]; - setUniform(uniformLocation("widthInTiles"), int(width / tileSize)); + setUniform(widthInTilesUniform_, int(width / tileSize)); return *this; } diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index 364aa868fd..400da7ebfe 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -43,6 +43,17 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { PTexMeshShader& setClipPlane(const Magnum::Vector4& clipPlane); PTexMeshShader& setAtlasTextureSize(Magnum::GL::Texture2D& texture, uint32_t tileSize); + + protected: + // it hurts the performance to call glGetUniformLocation() every frame. + // therefore, cache the locations in the constructor + int MVPMatrixUniform_; + int exposureUniform_; + int gammaUniform_; + int saturationUniform_; + int clipPlaneUniform_; + int tileSizeUniform_; + int widthInTilesUniform_; }; } // namespace gfx From 62029e339acdb57dfc8e1514d449d5760a7edf46 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Thu, 15 Aug 2019 17:43:09 -0700 Subject: [PATCH 15/24] fix - fix the parameters setCount() which is to set the index count (solves the segfault); - fix the gamma; --- src/esp/assets/PTexMeshData.cpp | 3 +-- src/esp/assets/PTexMeshData.h | 7 ++++--- src/esp/gfx/PTexMeshDrawable.cpp | 1 + src/esp/gfx/PTexMeshShader.cpp | 4 +++- src/esp/gfx/TextureBindingPointIndex.h | 6 +++--- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 602fb68603..b52bb683b0 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -689,10 +689,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { currentMesh->abo.setData(adjFaces[iMesh], Magnum::GL::BufferUsage::StaticDraw); - // experiment code (may not work): // using GL_LINES_ADJACENCY here to send quads to geometry shader currentMesh->mesh.setPrimitive(Magnum::GL::MeshPrimitive::LinesAdjacency) - .setCount(currentMesh->ibo.size()) + .setCount(submeshes_[iMesh].ibo.size()) .addVertexBuffer(currentMesh->vbo, 0, gfx::PTexMeshShader::Position{}) .setIndexBuffer(currentMesh->ibo, 0, Magnum::GL::MeshIndexType::UnsignedInt); diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index d60aa5b490..6042ef0b4a 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -81,9 +81,10 @@ class PTexMeshData : public BaseMesh { float splitSize_ = 0.0f; uint32_t tileSize_ = 0; - float exposure_ = 1.0f; - float gamma_ = 1.0f; - float saturation_ = 1.0f; + // based on ReplicaSDK + float exposure_ = 0.025f; + float gamma_ = 1.6969f; + float saturation_ = 1.5f; std::string atlasFolder_; diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index af4396a704..0c6a4bd62f 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -39,6 +39,7 @@ void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, .bindAtlasTexture(tex_) .bindAdjFacesBufferTexture(adjFaces_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); + mesh_.draw(ptexMeshShader); } diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 65d5d8b1e3..03b50feee4 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -60,6 +60,7 @@ PTexMeshShader::PTexMeshShader() { setUniform(uniformLocation("meshAdjFaces"), TextureBindingPointIndex::adjFaces); + // cache the uniform locations MVPMatrixUniform_ = uniformLocation("MVP"); exposureUniform_ = uniformLocation("exposure"); gammaUniform_ = uniformLocation("gamma"); @@ -91,7 +92,8 @@ PTexMeshShader& PTexMeshShader::setExposure(float exposure) { return *this; } PTexMeshShader& PTexMeshShader::setGamma(float gamma) { - setUniform(gammaUniform_, gamma); + // Careful: we set its inverse, not gamma directly + setUniform(gammaUniform_, 1.0f / gamma); return *this; } diff --git a/src/esp/gfx/TextureBindingPointIndex.h b/src/esp/gfx/TextureBindingPointIndex.h index e9a0ab2525..b58dc5a493 100644 --- a/src/esp/gfx/TextureBindingPointIndex.h +++ b/src/esp/gfx/TextureBindingPointIndex.h @@ -6,9 +6,9 @@ namespace esp { namespace gfx { -enum TextureBindingPointIndex { - atlas = 1, - adjFaces = 2, +enum TextureBindingPointIndex : uint8_t { + atlas = 0, + adjFaces = 1, }; } // namespace gfx } // namespace esp From 0948307cbc424c9dfc518f7c771cb5803f40301f Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Fri, 16 Aug 2019 15:12:59 -0700 Subject: [PATCH 16/24] merge --- src/deps/corrade | 2 +- src/deps/magnum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deps/corrade b/src/deps/corrade index 361f1aca0e..10e8830de8 160000 --- a/src/deps/corrade +++ b/src/deps/corrade @@ -1 +1 @@ -Subproject commit 361f1aca0ea74d9d596cb9745c7c020b2a77ffc8 +Subproject commit 10e8830de85d8a82dffaaf928b2ed236eb1bc3b5 diff --git a/src/deps/magnum b/src/deps/magnum index e8a715f54d..e2610bff18 160000 --- a/src/deps/magnum +++ b/src/deps/magnum @@ -1 +1 @@ -Subproject commit e8a715f54dc84633175f3dc8c8d27a1c51e4205b +Subproject commit e2610bff18fec836ed2e93942a0b312244e413bf From fc9246767d49e99ff3367502ed70dd9f1c905f60 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Fri, 16 Aug 2019 16:01:09 -0700 Subject: [PATCH 17/24] Revert "merge" This reverts commit 0948307cbc424c9dfc518f7c771cb5803f40301f. --- src/deps/corrade | 2 +- src/deps/magnum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deps/corrade b/src/deps/corrade index 10e8830de8..361f1aca0e 160000 --- a/src/deps/corrade +++ b/src/deps/corrade @@ -1 +1 @@ -Subproject commit 10e8830de85d8a82dffaaf928b2ed236eb1bc3b5 +Subproject commit 361f1aca0ea74d9d596cb9745c7c020b2a77ffc8 diff --git a/src/deps/magnum b/src/deps/magnum index e2610bff18..e8a715f54d 160000 --- a/src/deps/magnum +++ b/src/deps/magnum @@ -1 +1 @@ -Subproject commit e2610bff18fec836ed2e93942a0b312244e413bf +Subproject commit e8a715f54dc84633175f3dc8c8d27a1c51e4205b From 92b35ea9c7e8045d54a6c5e3c8c24716f7fdefa1 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Mon, 19 Aug 2019 21:00:27 -0700 Subject: [PATCH 18/24] merge --- src/deps/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deps/googletest b/src/deps/googletest index 00938b2b22..28b71e444c 160000 --- a/src/deps/googletest +++ b/src/deps/googletest @@ -1 +1 @@ -Subproject commit 00938b2b228f3b70d3d9e51f29a1505bdad43f1e +Subproject commit 28b71e444c41ad93225145e029db4957f15aaae6 From d66a5d5b8ec1a8e9139d8f19e35b07b582834939 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Fri, 23 Aug 2019 17:46:57 -0700 Subject: [PATCH 19/24] Almost there: -) dumped out the face sequence from replicaSDK, and imported it to the simulator; -) set proper transformation to make the model from Z-up to Y-up; TODO: -) debug: "Fish net", the artifacts at the boundary of each quad; -) remove the debug output; --- src/esp/assets/Asset.cpp | 1 + src/esp/assets/PTexMeshData.cpp | 237 +++++++++++++++++++------ src/esp/assets/PTexMeshData.h | 1 + src/esp/assets/ResourceManager.cpp | 2 + src/esp/gfx/PTexMeshDrawable.cpp | 1 - src/esp/gfx/PTexMeshShader.cpp | 10 +- src/esp/gfx/PTexMeshShader.h | 3 +- src/esp/gfx/TextureBindingPointIndex.h | 14 -- src/esp/gfx/Viewer.cpp | 15 +- src/shaders/ptex-default-gl410.geom | 53 +++--- 10 files changed, 237 insertions(+), 100 deletions(-) delete mode 100644 src/esp/gfx/TextureBindingPointIndex.h diff --git a/src/esp/assets/Asset.cpp b/src/esp/assets/Asset.cpp index c752173323..fa51f9c50f 100644 --- a/src/esp/assets/Asset.cpp +++ b/src/esp/assets/Asset.cpp @@ -18,6 +18,7 @@ AssetInfo AssetInfo::fromPath(const std::string& path) { info.type = AssetType::INSTANCE_MESH; } else if (endsWith(path, "mesh.ply")) { info.type = AssetType::FRL_PTEX_MESH; + info.frame = {quatf::FromTwoVectors(geo::ESP_GRAVITY, -vec3f::UnitZ())}; } else if (endsWith(path, "house.json")) { info.type = AssetType::SUNCG_SCENE; } else if (endsWith(path, ".glb")) { diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index f5d03d7193..1e846696cd 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -5,6 +5,7 @@ #include "PTexMeshData.h" #include +#include // XXX #include #include #include @@ -80,39 +81,49 @@ std::string PTexMeshData::atlasFolder() const { return atlasFolder_; } +// split the original ptex mesh into pieces. +// +// WARNING: +// +// user MUST provide the binary file, named "sortedFaces.bin", that +// contains the sorted faces in current version. +// +// the file format is as follows: +// a uinit64_t, N, which is the number of faces in the original mesh. +// it follows by N chunks, each of which is an object of: +// struct SortFace { +// uint32_t index[4]; +// uint32_t code; +// size_t originalFace; // unsigned int +// }; +// which is defined in the splitMesh(). +// +// this binary file, "sortedFaces.bin" can be generated by modifying the +// splitMesh() in file PTexLib.cpp in ReplicaSDK. +// Put it a level higher than the "atlasFolder_" (usually the same level as +// the mesh.ply). + +// Why? +// +// the original mesh is cut into pieces (submeshes), each of which contains +// a number of faces. A key step of the algorithm is to sort them based on a +// code. ReplicaSDK uses std::sort to do this job, where the original relative +// order of the semantically equivalent values are *not* preserved. +// (ideally, std::stable_sort should be applied here.) +// +// the consequence is we cannot reproduce such face order in our simulator +// using std::sort. (clang and gcc may have different implementations of +// std::sort). + std::vector splitMesh( const PTexMeshData::MeshData& mesh, - const float splitSize) { - std::vector verts; - verts.resize(mesh.vbo.size()); - - auto Part1By2 = [](uint64_t x) { - x &= 0x1fffff; // mask off lower 21 bits - x = (x | (x << 32)) & 0x1f00000000ffff; - x = (x | (x << 16)) & 0x1f0000ff0000ff; - x = (x | (x << 8)) & 0x100f00f00f00f00f; - x = (x | (x << 4)) & 0x10c30c30c30c30c3; - x = (x | (x << 2)) & 0x1249249249249249; - return x; - }; - - auto EncodeMorton3 = [&Part1By2](const vec3i& v) { - return (Part1By2(v(2)) << 2) + (Part1By2(v(1)) << 1) + Part1By2(v(0)); - }; - - box3f boundingBox; - - for (size_t i = 0; i < mesh.vbo.size(); i++) { - boundingBox.extend(mesh.vbo[i].head<3>()); - } - -// calculate vertex grid position and code -#pragma omp parallel for - for (size_t i = 0; i < mesh.vbo.size(); i++) { - const vec3f p = mesh.vbo[i].head<3>(); - vec3f pi = (p - boundingBox.min()) / splitSize; - verts[i] = EncodeMorton3(pi.cast()); - } + const float splitSize, + std::string sortedFacesFilename = "") { + // TODO: + // remove this ASSERT when the code can generate the same order of faces + // as the ReplicaSDK does in linux, when the meshes are textured + ASSERT(!sortedFacesFilename.empty(), + "Error: user must provide the file that contains the sorted faces."); // data structure for sorting faces struct SortFace { @@ -121,28 +132,109 @@ std::vector splitMesh( size_t originalFace; }; - // fill per-face data structures (including codes) - size_t numFaces = mesh.ibo.size() / 4; std::vector faces; - faces.resize(numFaces); + if (!sortedFacesFilename.empty()) { + // load the info about the sorted faces + std::ifstream file; + file.open(sortedFacesFilename, std::ios::in | std::ios::binary); + ASSERT(file.good(), + "Error: cannot open the file to read the sorted faces."); + + uint64_t numFaces = 0; + file.read((char*)&numFaces, sizeof(uint64_t)); + ASSERT(numFaces = mesh.ibo.size() / 4, + "Error: the numFaces from the file is not a quarter of the index " + "array size"); + faces.resize(numFaces); + file.read((char*)faces.data(), sizeof(SortFace) * numFaces); + file.close(); + } else { + std::vector verts; + verts.resize(mesh.vbo.size()); + + auto Part1By2 = [](uint64_t x) { + x &= 0x1fffff; // mask off lower 21 bits + x = (x | (x << 32)) & 0x1f00000000ffff; + x = (x | (x << 16)) & 0x1f0000ff0000ff; + x = (x | (x << 8)) & 0x100f00f00f00f00f; + x = (x | (x << 4)) & 0x10c30c30c30c30c3; + x = (x | (x << 2)) & 0x1249249249249249; + return x; + }; + + auto EncodeMorton3 = [&Part1By2](const vec3i& v) { + return (Part1By2(v(2)) << 2) + (Part1By2(v(1)) << 1) + Part1By2(v(0)); + }; + + box3f boundingBox; + + for (size_t i = 0; i < mesh.vbo.size(); i++) { + boundingBox.extend(mesh.vbo[i].head<3>()); + } + + /* + XXX + std::cout << "box: " << std::endl + << boundingBox.min() << std::endl + << boundingBox.max() << std::endl; + exit(-1); + */ + + std::cout << "pos and code: " << std::endl; +// calculate vertex grid position and code #pragma omp parallel for - for (size_t i = 0; i < numFaces; i++) { - faces[i].originalFace = i; - faces[i].code = std::numeric_limits::max(); - for (int j = 0; j < 4; j++) { - faces[i].index[j] = mesh.ibo[i * 4 + j]; + for (size_t i = 0; i < mesh.vbo.size(); i++) { + const vec3f p = mesh.vbo[i].head<3>(); + vec3f pi = (p - boundingBox.min()) / splitSize; + verts[i] = EncodeMorton3(pi.cast()); + // if (i > 300 && i <= 400) + // std::cout << verts[i] << ", "; + } - // face code is minimum of referenced vertices codes - faces[i].code = std::min(faces[i].code, verts[faces[i].index[j]]); + // fill per-face data structures (including codes) + size_t numFaces = mesh.ibo.size() / 4; + std::vector faces; + faces.resize(numFaces); + +#pragma omp parallel for + for (size_t i = 0; i < numFaces; i++) { + faces[i].originalFace = i; + faces[i].code = std::numeric_limits::max(); + for (int j = 0; j < 4; j++) { + faces[i].index[j] = mesh.ibo[i * 4 + j]; + + // face code is minimum of referenced vertices codes + faces[i].code = std::min(faces[i].code, verts[faces[i].index[j]]); + } } - } - // sort faces by code - std::sort(faces.begin(), faces.end(), - [](const SortFace& f1, const SortFace& f2) -> bool { - return (f1.code < f2.code); - }); + // XXX + /* + std::cout << "code: " << std::endl; + for (size_t i = 0; i < numFaces; i++) { + std::cout << faces[i].code << ", "; + } + std::cout << std::endl; + exit(-1); + */ + + // sort faces by code + std::sort(faces.begin(), faces.end(), + [](const SortFace& f1, const SortFace& f2) -> bool { + return (f1.code < f2.code); + }); + } // else + + // XXX + + /* + std::cout << "originalFace" << std::endl; + for (int i = 0; i < 100; i++) + std::cout << faces[i].originalFace << ", "; + exit(-1); + */ + // find face chunk start indices std::vector chunkStart; @@ -299,15 +391,35 @@ void PTexMeshData::calculateAdjacency(const PTexMeshData::MeshData& mesh, void PTexMeshData::loadMeshData(const std::string& meshFile) { PTexMeshData::MeshData originalMesh; - LOG(INFO) << "Start parsing PLY... "; + LOG(INFO) << "parsing PLY: " << meshFile; parsePLY(meshFile, originalMesh); - LOG(INFO) << "Parsing PLY: Done"; + LOG(INFO) << "Original mesh Info: "; + + LOG(INFO) << "number of vertices: " << originalMesh.vbo.size(); + LOG(INFO) << "number of indices: " << originalMesh.ibo.size(); + LOG(INFO) << "number of normals: " << originalMesh.nbo.size(); + LOG(INFO) << "number of colors: " << originalMesh.cbo.size(); submeshes_.clear(); if (splitSize_ > 0.0f) { LOG(INFO) << "Splitting mesh... "; - submeshes_ = splitMesh(originalMesh, splitSize_); - LOG(INFO) << "Splitting mesh: Done"; + + // In this version, sortedFacesFilename is a MUST have. + // See the comments on top of the splitMesh() + std::string sortedFacesFilename = + Corrade::Utility::Directory::join(atlasFolder_, "../sortedFaces.bin"); + submeshes_ = splitMesh(originalMesh, splitSize_, sortedFacesFilename); + + /* + LOG(INFO) << "number of splitted meshes: " << submeshes_.size(); + for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { + LOG(INFO) << "mesh " << iMesh; + LOG(INFO) << "number of vertices: " << submeshes_[iMesh].vbo.size(); + LOG(INFO) << "number of indices: " << submeshes_[iMesh].ibo.size(); + LOG(INFO) << "number of normals: " << submeshes_[iMesh].nbo.size(); + LOG(INFO) << "number of colors: " << submeshes_[iMesh].cbo.size(); + } + */ } else { submeshes_.emplace_back(std::move(originalMesh)); } @@ -682,6 +794,8 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { LOG(INFO) << "Done: Loaded it from " << adjFaceFilename; } + // exit(-1); + for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; @@ -697,6 +811,20 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { .setIndexBuffer(currentMesh->ibo, 0, Magnum::GL::MeshIndexType::UnsignedInt); } + { + std::ofstream file; + const std::string filename = + Corrade::Utility::Directory::join(atlasFolder_, "../indices.bin"); + file.open(filename, std::ios::out | std::ios::binary); + for(int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { + auto& currentMesh = submeshes_[iMesh]; + file.write((char*)(currentMesh.ibo.data()), sizeof(uint32_t) * currentMesh.ibo.size()); + file.write((char*)(currentMesh.vbo.data()), sizeof(vec4f) * currentMesh.vbo.size()); + } + LOG(INFO) << "Indices and vertices are saved to indices.bin"; + file.close(); + } + //exit(-1); // load atlas data and upload them to GPU LOG(INFO) << "loading atlas textures: "; @@ -722,9 +850,10 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { Magnum::ImageView2D image(Magnum::PixelFormat::RGB16F, {dim, dim}, data); const int mipLevelCount = 1; renderingBuffers_[iMesh] - ->tex.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) - .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) - .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) + ->tex + //.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) + //.setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) + //.setMinificationFilter(Magnum::GL::SamplerFilter::Linear) .setStorage(mipLevelCount, Magnum::GL::TextureFormat::RGB16F, image.size()) .setSubImage(0, {}, image); diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index ae95ca28fa..e3f2041363 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -52,6 +52,7 @@ class PTexMeshData : public BaseMesh { int getSize() { return submeshes_.size(); } static void parsePLY(const std::string& filename, MeshData& meshData); + static void calculateAdjacency(const MeshData& mesh, std::vector& adjFaces); diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index 11bbc2fdfd..15165ef2e3 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -721,6 +721,8 @@ bool ResourceManager::loadPTexMeshData(const AssetInfo& info, for (int jSubmesh = 0; jSubmesh < pTexMeshData->getSize(); ++jSubmesh) { scene::SceneNode& node = parent->createChild(); + const quatf transform = info.frame.rotationFrameToWorld(); + node.setRotation(Magnum::Quaternion(transform)); new gfx::PTexMeshDrawable{node, *ptexShader, *pTexMeshData, jSubmesh, drawables}; } diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index 0c6a4bd62f..af4396a704 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -39,7 +39,6 @@ void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, .bindAtlasTexture(tex_) .bindAdjFacesBufferTexture(adjFaces_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); - mesh_.draw(ptexMeshShader); } diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 03b50feee4..18c3416801 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -12,7 +12,6 @@ #include #include #include "PTexMeshShader.h" -#include "TextureBindingPointIndex.h" #include "esp/assets/PTexMeshData.h" #include "esp/core/esp.h" @@ -30,6 +29,13 @@ using namespace Magnum; namespace esp { namespace gfx { +namespace { +enum TextureBindingPointIndex : uint8_t { + atlas = 0, + adjFaces = 1, +}; +} + PTexMeshShader::PTexMeshShader() { MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL410); @@ -63,7 +69,7 @@ PTexMeshShader::PTexMeshShader() { // cache the uniform locations MVPMatrixUniform_ = uniformLocation("MVP"); exposureUniform_ = uniformLocation("exposure"); - gammaUniform_ = uniformLocation("gamma"); + gammaUniform_ = uniformLocation("gamma"); saturationUniform_ = uniformLocation("saturation"); clipPlaneUniform_ = uniformLocation("clipPlane"); tileSizeUniform_ = uniformLocation("tileSize"); diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index 400da7ebfe..0b2572726d 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -28,8 +28,7 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { explicit PTexMeshShader(); // ======== texture binding ======== - // Note: the texture binding points are explicitly specified - // in TextureBindingPointIndex.h + // Note: the texture binding points are explicitly specified in .cpp // Cannot use "explicit uniform location" directly in shader since // it requires GL4.3 (We stick to GL4.1 for MacOS). PTexMeshShader& bindAtlasTexture(Magnum::GL::Texture2D& texture); diff --git a/src/esp/gfx/TextureBindingPointIndex.h b/src/esp/gfx/TextureBindingPointIndex.h deleted file mode 100644 index b58dc5a493..0000000000 --- a/src/esp/gfx/TextureBindingPointIndex.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. -// This source code is licensed under the MIT license found in the -// LICENSE file in the root directory of this source tree. - -#pragma once - -namespace esp { -namespace gfx { -enum TextureBindingPointIndex : uint8_t { - atlas = 0, - adjFaces = 1, -}; -} // namespace gfx -} // namespace esp diff --git a/src/esp/gfx/Viewer.cpp b/src/esp/gfx/Viewer.cpp index bfc3942451..d25f25b2ba 100644 --- a/src/esp/gfx/Viewer.cpp +++ b/src/esp/gfx/Viewer.cpp @@ -49,6 +49,9 @@ Viewer::Viewer(const Arguments& arguments) .addBooleanOption("enable-physics") .addOption("physicsConfig", "./data/default.phys_scene_config.json") .setHelp("physicsConfig", "physics scene config file") +// .addOption("lookAt", "0.0f,1.5f,0.0f,1.5f,1.0f,0.0f,1.0f,0.0f") +// .setHelp("lookAt", +// "set initial eye, target and up dirction for the camera") .parse(arguments.argc, arguments.argv); const auto viewportSize = GL::defaultFramebuffer.viewport().size(); @@ -87,8 +90,17 @@ Viewer::Viewer(const Arguments& arguments) agentBodyNode_ = &rootNode_->createChild(); cameraNode_ = &agentBodyNode_->createChild(); + /* cameraNode_->translate({0.0f, cameraHeight, 0.0f}); agentBodyNode_->translate({0.0f, 0.0f, 5.0f}); + */ + + vec3f eye(0.0f, 0.0f, 1.0f); + vec3f target(0.0f, 0.0f, 0.0f); + vec3f up(0.0f, 1.0f, 0.0f); + + cameraNode_->setTransformation( + Matrix4::lookAt(Vector3{eye}, Vector3{target}, Vector3{up})); float hfov = 90.0f; int width = viewportSize[0]; @@ -99,6 +111,7 @@ Viewer::Viewer(const Arguments& arguments) renderCamera_->setProjectionMatrix(width, height, znear, zfar, hfov); // Load navmesh if available + vec3f position(0.0f, 0.0f, 0.0f); const std::string navmeshFilename = io::changeExtension(file, ".navmesh"); if (io::exists(navmeshFilename)) { LOG(INFO) << "Loading navmesh from " << navmeshFilename; @@ -107,7 +120,6 @@ Viewer::Viewer(const Arguments& arguments) const vec3f position = pathfinder_->getRandomNavigablePoint(); agentBodyNode_->setTranslation(Vector3(position)); } - // connect controls to navmesh if loaded /* if (pathfinder_->isLoaded()) { @@ -126,7 +138,6 @@ Viewer::Viewer(const Arguments& arguments) cameraNode_->absoluteTransformation()); timeline_.start(); - } // end Viewer::Viewer void Viewer::addObject(std::string configFile) { diff --git a/src/shaders/ptex-default-gl410.geom b/src/shaders/ptex-default-gl410.geom index 67cd349064..3857247b93 100644 --- a/src/shaders/ptex-default-gl410.geom +++ b/src/shaders/ptex-default-gl410.geom @@ -5,29 +5,32 @@ layout(triangle_strip, max_vertices = 4) out; out vec2 uv; -void main() -{ - gl_PrimitiveID = gl_PrimitiveIDIn; - - uv = vec2(1.0, 0.0); - gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0]; - gl_Position = gl_in[1].gl_Position; - EmitVertex(); - - uv = vec2(0.0, 0.0); - gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0]; - gl_Position = gl_in[0].gl_Position; - EmitVertex(); - - uv = vec2(1.0, 1.0); - gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0]; - gl_Position = gl_in[2].gl_Position; - EmitVertex(); - - uv = vec2(0.0, 1.0); - gl_ClipDistance[0] = gl_in[3].gl_ClipDistance[0]; - gl_Position = gl_in[3].gl_Position; - EmitVertex(); - - EndPrimitive(); +void main() { + gl_PrimitiveID = gl_PrimitiveIDIn; + + // the triangle trip generated is (3, 0, 2, 1), + // which is is different from replicaSDK. + // The winding of the two triangles (3, 0, 2) and (2, 0, 1) + // is CCW. + uv = vec2(0.0, 1.0); + gl_ClipDistance[0] = gl_in[3].gl_ClipDistance[0]; + gl_Position = gl_in[3].gl_Position; + EmitVertex(); + + uv = vec2(0.0, 0.0); + gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0]; + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + + uv = vec2(1.0, 1.0); + gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0]; + gl_Position = gl_in[2].gl_Position; + EmitVertex(); + + uv = vec2(1.0, 0.0); + gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0]; + gl_Position = gl_in[1].gl_Position; + EmitVertex(); + + EndPrimitive(); } From 3c7c963e764d5a5e4560cb84604f39d6d3683d49 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Sun, 25 Aug 2019 20:30:40 -0700 Subject: [PATCH 20/24] minor --- src/esp/assets/PTexMeshData.cpp | 48 +++++++++++++++++++++------------ src/esp/assets/PTexMeshData.h | 6 ++--- src/esp/gfx/Viewer.cpp | 24 ++++++++++++----- src/esp/gfx/Viewer.h | 9 +++++++ 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index 1e846696cd..c4ff8aff82 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -235,7 +235,6 @@ std::vector splitMesh( exit(-1); */ - // find face chunk start indices std::vector chunkStart; chunkStart.push_back(0); @@ -768,10 +767,10 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { std::make_unique()); auto& currentMesh = renderingBuffers_.back(); - currentMesh->vbo.setData(submeshes_[iMesh].vbo, - Magnum::GL::BufferUsage::StaticDraw); - currentMesh->ibo.setData(submeshes_[iMesh].ibo, - Magnum::GL::BufferUsage::StaticDraw); + currentMesh->vertexBuffer.setData(submeshes_[iMesh].vbo, + Magnum::GL::BufferUsage::StaticDraw); + currentMesh->indexBuffer.setData(submeshes_[iMesh].ibo, + Magnum::GL::BufferUsage::StaticDraw); } LOG(INFO) << "Calculating mesh adjacency... "; @@ -796,35 +795,50 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // exit(-1); + int maxBufferTextureTexels = 0; + glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxBufferTextureTexels); + for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; + ASSERT(maxBufferTextureTexels >= adjFaces[iMesh].size(), + "Error: the number of adjacent faces is larger than the allowed " + "number of texels"); currentMesh->adjFaces.setBuffer(Magnum::GL::BufferTextureFormat::R32UI, - currentMesh->abo); - currentMesh->abo.setData(adjFaces[iMesh], - Magnum::GL::BufferUsage::StaticDraw); + currentMesh->adjFacesBuffer); + currentMesh->adjFacesBuffer.setData(adjFaces[iMesh], + Magnum::GL::BufferUsage::StaticDraw); // using GL_LINES_ADJACENCY here to send quads to geometry shader - currentMesh->mesh.setPrimitive(Magnum::GL::MeshPrimitive::LinesAdjacency) + GLintptr offset = 0; + currentMesh->mesh + .setPrimitive(Magnum::GL::MeshPrimitive::LinesAdjacency) + // Warning: + // CANNOT use currentMesh.indexBuffer.size() when calling + // setCount because that returns the number of bytes of the buffer, NOT + // the index counts .setCount(submeshes_[iMesh].ibo.size()) - .addVertexBuffer(currentMesh->vbo, 0, gfx::PTexMeshShader::Position{}) - .setIndexBuffer(currentMesh->ibo, 0, + .addVertexBuffer(currentMesh->vertexBuffer, offset, + gfx::PTexMeshShader::Position{}) + .setIndexBuffer(currentMesh->indexBuffer, offset, Magnum::GL::MeshIndexType::UnsignedInt); } { std::ofstream file; const std::string filename = - Corrade::Utility::Directory::join(atlasFolder_, "../indices.bin"); + Corrade::Utility::Directory::join(atlasFolder_, "../indices.bin"); file.open(filename, std::ios::out | std::ios::binary); - for(int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { + for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = submeshes_[iMesh]; - file.write((char*)(currentMesh.ibo.data()), sizeof(uint32_t) * currentMesh.ibo.size()); - file.write((char*)(currentMesh.vbo.data()), sizeof(vec4f) * currentMesh.vbo.size()); + file.write((char*)(currentMesh.ibo.data()), + sizeof(uint32_t) * currentMesh.ibo.size()); + file.write((char*)(currentMesh.vbo.data()), + sizeof(vec4f) * currentMesh.vbo.size()); } LOG(INFO) << "Indices and vertices are saved to indices.bin"; file.close(); } - //exit(-1); + // exit(-1); // load atlas data and upload them to GPU LOG(INFO) << "loading atlas textures: "; @@ -850,7 +864,7 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { Magnum::ImageView2D image(Magnum::PixelFormat::RGB16F, {dim, dim}, data); const int mipLevelCount = 1; renderingBuffers_[iMesh] - ->tex + ->tex //.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) //.setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) //.setMinificationFilter(Magnum::GL::SamplerFilter::Linear) diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index e3f2041363..5b57a8467f 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -31,9 +31,9 @@ class PTexMeshData : public BaseMesh { struct RenderingBuffer { Magnum::GL::Mesh mesh; Magnum::GL::Texture2D tex; - Magnum::GL::Buffer vbo; - Magnum::GL::Buffer ibo; - Magnum::GL::Buffer abo; + Magnum::GL::Buffer vertexBuffer; + Magnum::GL::Buffer indexBuffer; + Magnum::GL::Buffer adjFacesBuffer; Magnum::GL::BufferTexture adjFaces; }; diff --git a/src/esp/gfx/Viewer.cpp b/src/esp/gfx/Viewer.cpp index d25f25b2ba..3c38bd1ed2 100644 --- a/src/esp/gfx/Viewer.cpp +++ b/src/esp/gfx/Viewer.cpp @@ -49,9 +49,9 @@ Viewer::Viewer(const Arguments& arguments) .addBooleanOption("enable-physics") .addOption("physicsConfig", "./data/default.phys_scene_config.json") .setHelp("physicsConfig", "physics scene config file") -// .addOption("lookAt", "0.0f,1.5f,0.0f,1.5f,1.0f,0.0f,1.0f,0.0f") -// .setHelp("lookAt", -// "set initial eye, target and up dirction for the camera") + // .addOption("lookAt", "0.0f,1.5f,0.0f,1.5f,1.0f,0.0f,1.0f,0.0f") + // .setHelp("lookAt", + // "set initial eye, target and up dirction for the camera") .parse(arguments.argc, arguments.argv); const auto viewportSize = GL::defaultFramebuffer.viewport().size(); @@ -359,28 +359,38 @@ void Viewer::keyPressEvent(KeyEvent& event) { case KeyEvent::Key::A: controls_(*agentBodyNode_, "moveLeft", moveSensitivity); LOG(INFO) << "Agent position " - << Eigen::Map(agentBodyNode_->translation().data()); + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::D: controls_(*agentBodyNode_, "moveRight", moveSensitivity); LOG(INFO) << "Agent position " - << Eigen::Map(agentBodyNode_->translation().data()); + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::S: controls_(*agentBodyNode_, "moveBackward", moveSensitivity); LOG(INFO) << "Agent position " - << Eigen::Map(agentBodyNode_->translation().data()); + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::W: controls_(*agentBodyNode_, "moveForward", moveSensitivity); LOG(INFO) << "Agent position " - << Eigen::Map(agentBodyNode_->translation().data()); + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::X: controls_(*agentBodyNode_, "moveDown", moveSensitivity, false); + LOG(INFO) << "Agent position " + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::Z: controls_(*agentBodyNode_, "moveUp", moveSensitivity, false); + LOG(INFO) << "Agent position " + << Eigen::Map(agentBodyNode_->translation().data()) + .format(eigenFlatFormat_); break; case KeyEvent::Key::O: { if (physicsManager_ != nullptr) { diff --git a/src/esp/gfx/Viewer.h b/src/esp/gfx/Viewer.h index dc4298eb7e..09793bc4de 100644 --- a/src/esp/gfx/Viewer.h +++ b/src/esp/gfx/Viewer.h @@ -82,6 +82,15 @@ class Viewer : public Magnum::Platform::Application { std::vector objectIDs_; Magnum::Timeline timeline_; + + const Eigen::IOFormat eigenFlatFormat_{Eigen::StreamPrecision, + Eigen::DontAlignCols, + ", ", // coef separator + ", ", // row separator + "", // row prefix + "", // col prefix + "[", // mat prefix + "]"}; // mat suffix }; } // namespace gfx From 48e00ebdb4e61a732a7e29338772a352212afa34 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Sun, 25 Aug 2019 21:10:31 -0700 Subject: [PATCH 21/24] use map to cache the uniform locations --- src/esp/gfx/PTexMeshShader.cpp | 29 +++++++++++++++-------------- src/esp/gfx/PTexMeshShader.h | 8 +------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 18c3416801..12b118687d 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -67,13 +67,14 @@ PTexMeshShader::PTexMeshShader() { TextureBindingPointIndex::adjFaces); // cache the uniform locations - MVPMatrixUniform_ = uniformLocation("MVP"); - exposureUniform_ = uniformLocation("exposure"); - gammaUniform_ = uniformLocation("gamma"); - saturationUniform_ = uniformLocation("saturation"); - clipPlaneUniform_ = uniformLocation("clipPlane"); - tileSizeUniform_ = uniformLocation("tileSize"); - widthInTilesUniform_ = uniformLocation("widthInTiles"); + // std::map uniformLocations; + uniformLocations_["MVP"] = uniformLocation("MVP"); + uniformLocations_["exposure"] = uniformLocation("exposure"); + uniformLocations_["gamma"] = uniformLocation("gamma"); + uniformLocations_["saturation"] = uniformLocation("saturation"); + uniformLocations_["clipPlane"] = uniformLocation("clipPlane"); + uniformLocations_["tileSize"] = uniformLocation("tileSize"); + uniformLocations_["widthInTiles"] = uniformLocation("widthInTiles"); } PTexMeshShader& PTexMeshShader::bindAtlasTexture( @@ -89,39 +90,39 @@ PTexMeshShader& PTexMeshShader::bindAdjFacesBufferTexture( } PTexMeshShader& PTexMeshShader::setMVPMatrix(const Magnum::Matrix4& matrix) { - setUniform(MVPMatrixUniform_, matrix); + setUniform(uniformLocations_["MVP"], matrix); return *this; } PTexMeshShader& PTexMeshShader::setExposure(float exposure) { - setUniform(exposureUniform_, exposure); + setUniform(uniformLocations_["exposure"], exposure); return *this; } PTexMeshShader& PTexMeshShader::setGamma(float gamma) { // Careful: we set its inverse, not gamma directly - setUniform(gammaUniform_, 1.0f / gamma); + setUniform(uniformLocations_["gamma"], 1.0f / gamma); return *this; } PTexMeshShader& PTexMeshShader::setSaturation(float saturation) { - setUniform(saturationUniform_, saturation); + setUniform(uniformLocations_["saturation"], saturation); return *this; } PTexMeshShader& PTexMeshShader::setClipPlane(const Magnum::Vector4& clipPlane) { - setUniform(clipPlaneUniform_, clipPlane); + setUniform(uniformLocations_["clipPlane"], clipPlane); return *this; } PTexMeshShader& PTexMeshShader::setAtlasTextureSize(Magnum::GL::Texture2D& tex, uint32_t tileSize) { - setUniform(tileSizeUniform_, (int)tileSize); + setUniform(uniformLocations_["tileSize"], (int)tileSize); // Image size in given mip level 0 int mipLevel = 0; int widthEntry = 0; const auto width = tex.imageSize(mipLevel)[widthEntry]; - setUniform(widthInTilesUniform_, int(width / tileSize)); + setUniform(uniformLocations_["widthInTiles"], int(width / tileSize)); return *this; } diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index 0b2572726d..14cf806e71 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -46,13 +46,7 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { protected: // it hurts the performance to call glGetUniformLocation() every frame. // therefore, cache the locations in the constructor - int MVPMatrixUniform_; - int exposureUniform_; - int gammaUniform_; - int saturationUniform_; - int clipPlaneUniform_; - int tileSizeUniform_; - int widthInTilesUniform_; + std::map uniformLocations_; }; } // namespace gfx From a2ee4a9f80d1a36578e9b192b149c5cac8a68680 Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Mon, 26 Aug 2019 11:03:02 -0700 Subject: [PATCH 22/24] Revert "use map to cache the uniform locations" This reverts commit 48e00ebdb4e61a732a7e29338772a352212afa34. --- src/esp/gfx/PTexMeshShader.cpp | 29 ++++++++++++++--------------- src/esp/gfx/PTexMeshShader.h | 8 +++++++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/esp/gfx/PTexMeshShader.cpp b/src/esp/gfx/PTexMeshShader.cpp index 12b118687d..18c3416801 100644 --- a/src/esp/gfx/PTexMeshShader.cpp +++ b/src/esp/gfx/PTexMeshShader.cpp @@ -67,14 +67,13 @@ PTexMeshShader::PTexMeshShader() { TextureBindingPointIndex::adjFaces); // cache the uniform locations - // std::map uniformLocations; - uniformLocations_["MVP"] = uniformLocation("MVP"); - uniformLocations_["exposure"] = uniformLocation("exposure"); - uniformLocations_["gamma"] = uniformLocation("gamma"); - uniformLocations_["saturation"] = uniformLocation("saturation"); - uniformLocations_["clipPlane"] = uniformLocation("clipPlane"); - uniformLocations_["tileSize"] = uniformLocation("tileSize"); - uniformLocations_["widthInTiles"] = uniformLocation("widthInTiles"); + MVPMatrixUniform_ = uniformLocation("MVP"); + exposureUniform_ = uniformLocation("exposure"); + gammaUniform_ = uniformLocation("gamma"); + saturationUniform_ = uniformLocation("saturation"); + clipPlaneUniform_ = uniformLocation("clipPlane"); + tileSizeUniform_ = uniformLocation("tileSize"); + widthInTilesUniform_ = uniformLocation("widthInTiles"); } PTexMeshShader& PTexMeshShader::bindAtlasTexture( @@ -90,39 +89,39 @@ PTexMeshShader& PTexMeshShader::bindAdjFacesBufferTexture( } PTexMeshShader& PTexMeshShader::setMVPMatrix(const Magnum::Matrix4& matrix) { - setUniform(uniformLocations_["MVP"], matrix); + setUniform(MVPMatrixUniform_, matrix); return *this; } PTexMeshShader& PTexMeshShader::setExposure(float exposure) { - setUniform(uniformLocations_["exposure"], exposure); + setUniform(exposureUniform_, exposure); return *this; } PTexMeshShader& PTexMeshShader::setGamma(float gamma) { // Careful: we set its inverse, not gamma directly - setUniform(uniformLocations_["gamma"], 1.0f / gamma); + setUniform(gammaUniform_, 1.0f / gamma); return *this; } PTexMeshShader& PTexMeshShader::setSaturation(float saturation) { - setUniform(uniformLocations_["saturation"], saturation); + setUniform(saturationUniform_, saturation); return *this; } PTexMeshShader& PTexMeshShader::setClipPlane(const Magnum::Vector4& clipPlane) { - setUniform(uniformLocations_["clipPlane"], clipPlane); + setUniform(clipPlaneUniform_, clipPlane); return *this; } PTexMeshShader& PTexMeshShader::setAtlasTextureSize(Magnum::GL::Texture2D& tex, uint32_t tileSize) { - setUniform(uniformLocations_["tileSize"], (int)tileSize); + setUniform(tileSizeUniform_, (int)tileSize); // Image size in given mip level 0 int mipLevel = 0; int widthEntry = 0; const auto width = tex.imageSize(mipLevel)[widthEntry]; - setUniform(uniformLocations_["widthInTiles"], int(width / tileSize)); + setUniform(widthInTilesUniform_, int(width / tileSize)); return *this; } diff --git a/src/esp/gfx/PTexMeshShader.h b/src/esp/gfx/PTexMeshShader.h index 14cf806e71..0b2572726d 100644 --- a/src/esp/gfx/PTexMeshShader.h +++ b/src/esp/gfx/PTexMeshShader.h @@ -46,7 +46,13 @@ class PTexMeshShader : public Magnum::GL::AbstractShaderProgram { protected: // it hurts the performance to call glGetUniformLocation() every frame. // therefore, cache the locations in the constructor - std::map uniformLocations_; + int MVPMatrixUniform_; + int exposureUniform_; + int gammaUniform_; + int saturationUniform_; + int clipPlaneUniform_; + int tileSizeUniform_; + int widthInTilesUniform_; }; } // namespace gfx From 77ccc258a7838ba4c09830d8322ba131908f930d Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Tue, 27 Aug 2019 14:39:18 -0700 Subject: [PATCH 23/24] debug on macOS --- src/esp/assets/PTexMeshData.cpp | 6 +++--- src/esp/gfx/PTexMeshDrawable.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index c4ff8aff82..bd52e0418c 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -865,9 +865,9 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { const int mipLevelCount = 1; renderingBuffers_[iMesh] ->tex - //.setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) - //.setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) - //.setMinificationFilter(Magnum::GL::SamplerFilter::Linear) + .setWrapping(Magnum::GL::SamplerWrapping::ClampToEdge) + .setMagnificationFilter(Magnum::GL::SamplerFilter::Linear) + .setMinificationFilter(Magnum::GL::SamplerFilter::Linear) .setStorage(mipLevelCount, Magnum::GL::TextureFormat::RGB16F, image.size()) .setSubImage(0, {}, image); diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index af4396a704..ac218c9518 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -4,6 +4,8 @@ #include "PTexMeshDrawable.h" +#include + #include "esp/assets/PTexMeshData.h" namespace esp { @@ -40,6 +42,23 @@ void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, .bindAdjFacesBufferTexture(adjFaces_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); mesh_.draw(ptexMeshShader); + + //XXX + // ASSERT(Magnum::GL::Renderer::Error::NoError == Magnum::GL::Renderer::error()); + switch (Magnum::GL::Renderer::error()) { + case Magnum::GL::Renderer::Error::NoError: + LOG(INFO) << "No error"; + break; + case Magnum::GL::Renderer::Error::InvalidValue: + LOG(INFO) << "InvalidValue"; + break; + case Magnum::GL::Renderer::Error::InvalidOperation: + LOG(INFO) << "InvalidOperation"; + break; + default: + LOG(INFO) << "some other errors"; + break; + } } } // namespace gfx From 6ee58daf10310fd371082d3be2a0b02950126e9d Mon Sep 17 00:00:00 2001 From: Yili Zhao Date: Wed, 4 Sep 2019 14:58:19 -0700 Subject: [PATCH 24/24] debug --- src/esp/assets/PTexMeshData.cpp | 76 +++++++++++++++++++++++++++-- src/esp/assets/PTexMeshData.h | 4 +- src/esp/gfx/PTexMeshDrawable.cpp | 20 +------- src/shaders/ptex-default-gl410.frag | 16 +++++- 4 files changed, 93 insertions(+), 23 deletions(-) diff --git a/src/esp/assets/PTexMeshData.cpp b/src/esp/assets/PTexMeshData.cpp index bd52e0418c..8f3452d751 100644 --- a/src/esp/assets/PTexMeshData.cpp +++ b/src/esp/assets/PTexMeshData.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -795,8 +796,12 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { // exit(-1); + //XXX int maxBufferTextureTexels = 0; glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxBufferTextureTexels); + //int maxUniformBlockSize = 0; + //glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize); + //LOG(INFO) << "Max uniform block size: " << maxUniformBlockSize; for (int iMesh = 0; iMesh < submeshes_.size(); ++iMesh) { auto& currentMesh = renderingBuffers_[iMesh]; @@ -804,10 +809,75 @@ void PTexMeshData::uploadBuffersToGPU(bool forceReload) { "Error: the number of adjacent faces is larger than the allowed " "number of texels"); - currentMesh->adjFaces.setBuffer(Magnum::GL::BufferTextureFormat::R32UI, + glBindBuffer(GL_TEXTURE_BUFFER, currentMesh->adjFacesBuffer.id()); + //glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, currentMesh->adjFacesBuffer.id()); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, currentMesh->adjFacesBuffer.id()); + //glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, currentMesh->adjFacesBuffer.id()); + //currentMesh->adjFacesBufferTexture.setBuffer(Magnum::GL::BufferTextureFormat::R32F, + //currentMesh->adjFacesBufferTexture.setBuffer(Magnum::GL::BufferTextureFormat::R32UI, + currentMesh->adjFacesBufferTexture.setBuffer(Magnum::GL::BufferTextureFormat::RGBA32UI, currentMesh->adjFacesBuffer); - currentMesh->adjFacesBuffer.setData(adjFaces[iMesh], - Magnum::GL::BufferUsage::StaticDraw); + + LOG(INFO) << "After setBuffer ^^^^^^^^^^^^^^"; + switch (Magnum::GL::Renderer::error()) { + case Magnum::GL::Renderer::Error::NoError: + LOG(INFO) << "No error"; + break; + case Magnum::GL::Renderer::Error::InvalidValue: + LOG(INFO) << "InvalidValue"; + break; + case Magnum::GL::Renderer::Error::InvalidOperation: + LOG(INFO) << "InvalidOperation"; + break; + default: + LOG(INFO) << "some other errors"; + break; + } + /* + LOG(INFO) << "ID = " << currentMesh->adjFacesBuffer.id(); + GLuint tempBuffer; + glGenBuffers(1, &tempBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, tempBuffer); + uint32_t* tempPtr = new uint32_t[adjFaces[iMesh].size()]; + for(int i=0; i< adjFaces[iMesh].size(); ++i) { + tempPtr[i] = adjFaces[iMesh][i]; + } + */ + // glBufferData(GL_TEXTURE_BUFFER, sizeof(uint32_t) * adjFaces[iMesh].size(), (void*)adjFaces[iMesh].data(), GL_STATIC_DRAW); + //glBufferData(GL_TEXTURE_BUFFER, sizeof(uint32_t) * adjFaces[iMesh].size(), (void*)tempPtr, GL_STATIC_DRAW); + //delete []tempPtr; + + //glBindBuffer(GL_TEXTURE_BUFFER, currentMesh->adjFacesBuffer.id()); + { + std::vector adj; + int rgba = 4; + adj.resize(adjFaces[iMesh].size() * rgba); + for (int i = 0; i < adjFaces[iMesh].size() * rgba; ++i) { + if (i % 4 == 0) { + adj[i] = adjFaces[iMesh][i / 4]; + } else { + adj[i] = 0; + } + } + //currentMesh->adjFacesBuffer.setData(adjFaces[iMesh], + currentMesh->adjFacesBuffer.setData(adj, + Magnum::GL::BufferUsage::StaticDraw); + } + LOG(INFO) << " After setData ++++++++++++++"; + switch (Magnum::GL::Renderer::error()) { + case Magnum::GL::Renderer::Error::NoError: + LOG(INFO) << "No error"; + break; + case Magnum::GL::Renderer::Error::InvalidValue: + LOG(INFO) << "InvalidValue"; + break; + case Magnum::GL::Renderer::Error::InvalidOperation: + LOG(INFO) << "InvalidOperation"; + break; + default: + LOG(INFO) << "some other errors"; + break; + } // using GL_LINES_ADJACENCY here to send quads to geometry shader GLintptr offset = 0; diff --git a/src/esp/assets/PTexMeshData.h b/src/esp/assets/PTexMeshData.h index 5b57a8467f..da26009afd 100644 --- a/src/esp/assets/PTexMeshData.h +++ b/src/esp/assets/PTexMeshData.h @@ -34,7 +34,9 @@ class PTexMeshData : public BaseMesh { Magnum::GL::Buffer vertexBuffer; Magnum::GL::Buffer indexBuffer; Magnum::GL::Buffer adjFacesBuffer; - Magnum::GL::BufferTexture adjFaces; + Magnum::GL::BufferTexture adjFacesBufferTexture; + RenderingBuffer():adjFacesBuffer{Magnum::GL::Buffer::TargetHint::Texture} { + } }; PTexMeshData() : BaseMesh(SupportedMeshType::PTEX_MESH) {} diff --git a/src/esp/gfx/PTexMeshDrawable.cpp b/src/esp/gfx/PTexMeshDrawable.cpp index ac218c9518..73a3e83fbe 100644 --- a/src/esp/gfx/PTexMeshDrawable.cpp +++ b/src/esp/gfx/PTexMeshDrawable.cpp @@ -20,7 +20,8 @@ PTexMeshDrawable::PTexMeshDrawable( : Drawable{node, shader, ptexMeshData.getRenderingBuffer(submeshID)->mesh, group}, tex_(ptexMeshData.getRenderingBuffer(submeshID)->tex), - adjFaces_(ptexMeshData.getRenderingBuffer(submeshID)->adjFaces), + adjFaces_( + ptexMeshData.getRenderingBuffer(submeshID)->adjFacesBufferTexture), tileSize_(ptexMeshData.tileSize()), exposure_(ptexMeshData.exposure()), gamma_(ptexMeshData.gamma()), @@ -42,23 +43,6 @@ void PTexMeshDrawable::draw(const Magnum::Matrix4& transformationMatrix, .bindAdjFacesBufferTexture(adjFaces_) .setMVPMatrix(camera.projectionMatrix() * transformationMatrix); mesh_.draw(ptexMeshShader); - - //XXX - // ASSERT(Magnum::GL::Renderer::Error::NoError == Magnum::GL::Renderer::error()); - switch (Magnum::GL::Renderer::error()) { - case Magnum::GL::Renderer::Error::NoError: - LOG(INFO) << "No error"; - break; - case Magnum::GL::Renderer::Error::InvalidValue: - LOG(INFO) << "InvalidValue"; - break; - case Magnum::GL::Renderer::Error::InvalidOperation: - LOG(INFO) << "InvalidOperation"; - break; - default: - LOG(INFO) << "some other errors"; - break; - } } } // namespace gfx diff --git a/src/shaders/ptex-default-gl410.frag b/src/shaders/ptex-default-gl410.frag index 2ed9f77cd7..a41ae36000 100644 --- a/src/shaders/ptex-default-gl410.frag +++ b/src/shaders/ptex-default-gl410.frag @@ -23,6 +23,20 @@ ivec2 RotateUVs(ivec2 p, int rot, int size) { return ivec2((size - 1) - p.y, p.x); } } +/* +ivec2 RotateUVs(ivec2 p, int rot, int size) { + switch (rot) { + case 0: + return p; + case 1: + return ivec2((size - 1) - p.y, p.x); + case 2: + return ivec2((size - 1) - p.x, (size - 1) - p.y); + case 3: + return ivec2(p.y, (size - 1) - p.x); + } +} +*/ const uint ROTATION_SHIFT = 30; const uint FACE_MASK = 0x3FFFFFFF; @@ -132,7 +146,7 @@ vec4 texelFetchAtlasAdj(sampler2D tex, int faceID, ivec2 p, int level) { int tsize = tileSize >> level; // fetch from adjacent face if necessary - faceID = indexAdjacentFaces(faceID, p, tsize); + // faceID = indexAdjacentFaces(faceID, p, tsize); // clamp to tile edge p = clamp(p, ivec2(0, 0), ivec2(tsize - 1, tsize - 1));