Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loading and rendering optimizations #21

Merged
merged 15 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ if (WIN32)
find_package(nlohmann_json CONFIG REQUIRED)
endif()

# eigen
find_package(Eigen3 CONFIG REQUIRED)

# tracy
if(WIN32 AND NOT SHIPPING)
find_package(Tracy CONFIG REQUIRED)
Expand All @@ -56,6 +59,7 @@ find_package(OpenXR CONFIG REQUIRED)
# src
include_directories(src)
add_executable(${PROJECT_NAME}
src/core/binaryattribute.cpp
src/core/debugrenderer.cpp
src/core/framebuffer.cpp
src/core/image.cpp
Expand Down Expand Up @@ -99,6 +103,7 @@ if(WIN32)
glm::glm
PNG::PNG
nlohmann_json::nlohmann_json
Eigen3::Eigen
OpenXR::headers
OpenXR::openxr_loader
)
Expand All @@ -111,6 +116,7 @@ if(WIN32)
glm::glm
PNG::PNG
nlohmann_json::nlohmann_json
Eigen3::Eigen
Tracy::TracyClient
OpenXR::headers
OpenXR::openxr_loader
Expand All @@ -125,6 +131,7 @@ else()
glm::glm
PNG::PNG
# nlohmann_json::nlohmann_json
Eigen3::Eigen
OpenXR::headers
OpenXR::openxr_loader
${X11_LIBRARIES}
Expand Down
47 changes: 27 additions & 20 deletions src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
#include <filesystem>
#include <thread>

#ifdef TRACY_ENABLE
#include <tracy/Tracy.hpp>
#else
#define ZoneScoped
#define ZoneScopedNC(NAME, COLOR)
#endif

#include "core/framebuffer.h"
#include "core/log.h"
#include "core/debugrenderer.h"
Expand Down Expand Up @@ -45,7 +52,8 @@ enum optionIndex
DEBUG,
HELP,
FP16,
FP32
FP32,
NOSH,
};

const option::Descriptor usage[] =
Expand All @@ -57,6 +65,7 @@ const option::Descriptor usage[] =
{ DEBUG, 0, "d", "debug", option::Arg::None, " -d, --debug Enable verbose debug logging." },
{ FP16, 0, "", "fp16", option::Arg::None, " --fp16 Use 16-bit half-precision floating frame buffer, to reduce color banding artifacts" },
{ FP32, 0, "", "fp32", option::Arg::None, " --fp32 Use 32-bit floating point frame buffer, to reduce color banding even more" },
{ NOSH, 0, "", "nosh", option::Arg::None, " --nosh Don't load/render full sh, this will reduce memory usage and higher performance" },
{ UNKNOWN, 0, "", "", option::Arg::None, "\nExamples:\n splataplut data/test.ply\n splatapult -v data/test.ply" },
{ 0, 0, 0, 0, 0, 0}
};
Expand Down Expand Up @@ -152,13 +161,6 @@ static void Clear(glm::ivec2 windowSize, bool setViewport = true)

// NOTE: if depth buffer has less then 24 bits, it can mess up splat rendering.
glEnable(GL_DEPTH_TEST);

#ifndef __ANDROID__
// AJT: ANDROID: TODO: implement this in fragment shader, for OpenGLES I guess.
// enable alpha test
//glEnable(GL_ALPHA_TEST);
//glAlphaFunc(GL_GREATER, 1.0f / 256.0f);
#endif
}

// Draw a textured quad over the entire screen.
Expand Down Expand Up @@ -209,10 +211,9 @@ static void RenderDesktop(glm::ivec2 windowSize, std::shared_ptr<Program> deskto
}
}

// AJT: TODO this wrapper func is not needed anymore
static std::shared_ptr<PointCloud> LoadPointCloud(const std::string& plyFilename)
static std::shared_ptr<PointCloud> LoadPointCloud(const std::string& plyFilename, bool useLinearColors)
{
auto pointCloud = std::make_shared<PointCloud>();
auto pointCloud = std::make_shared<PointCloud>(useLinearColors);

if (!pointCloud->ImportPly(plyFilename))
{
Expand All @@ -222,11 +223,17 @@ static std::shared_ptr<PointCloud> LoadPointCloud(const std::string& plyFilename
return pointCloud;
}

// AJT: TODO this wrapper func is not needed anymore
static std::shared_ptr<GaussianCloud> LoadGaussianCloud(const std::string& plyFilename)
static std::shared_ptr<GaussianCloud> LoadGaussianCloud(const std::string& plyFilename, const App::Options& opt)
{
auto gaussianCloud = std::make_shared<GaussianCloud>();

GaussianCloud::Options options = {0};
#ifdef __ANDROID__
options.importFullSH = false;
options.exportFullSH = false;
#else
options.importFullSH = opt.importFullSH;
options.exportFullSH = true;
#endif
auto gaussianCloud = std::make_shared<GaussianCloud>(options);
if (!gaussianCloud->ImportPly(plyFilename))
{
Log::E("Error loading GaussianCloud!\n");
Expand Down Expand Up @@ -325,6 +332,8 @@ App::ParseResult App::ParseArguments(int argc, const char* argv[])
opt.frameBuffer = Options::FrameBuffer::HalfFloat;
}

opt.importFullSH = options[NOSH] ? false : true;

bool unknownOptionFound = false;
for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())
{
Expand Down Expand Up @@ -504,7 +513,7 @@ bool App::Init()
std::string pointCloudFilename = FindConfigFile(plyFilename, "input.ply");
if (!pointCloudFilename.empty())
{
pointCloud = LoadPointCloud(pointCloudFilename);
pointCloud = LoadPointCloud(pointCloudFilename, isFramebufferSRGBEnabled);
if (!pointCloud)
{
Log::E("Error loading PointCloud\n");
Expand All @@ -523,7 +532,7 @@ bool App::Init()
Log::D("Could not find input.ply\n");
}

gaussianCloud = LoadGaussianCloud(plyFilename);
gaussianCloud = LoadGaussianCloud(plyFilename, opt);
if (!gaussianCloud)
{
Log::E("Error loading GaussianCloud\n");
Expand All @@ -539,13 +548,11 @@ bool App::Init()

splatRenderer = std::make_shared<SplatRenderer>();
#if __ANDROID__
bool useFullSH = false;
bool useRgcSortOverride = true;
#else
bool useFullSH = true;
bool useRgcSortOverride = false;
#endif
if (!splatRenderer->Init(gaussianCloud, isFramebufferSRGBEnabled, useFullSH, useRgcSortOverride))
if (!splatRenderer->Init(gaussianCloud, isFramebufferSRGBEnabled, useRgcSortOverride))
{
Log::E("Error initializing splat renderer!\n");
return false;
Expand Down
3 changes: 2 additions & 1 deletion src/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ class App
using ResizeCallback = std::function<void(int, int)>;
void OnResize(const ResizeCallback& cb);

protected:
struct Options
{
enum class FrameBuffer
Expand All @@ -76,8 +75,10 @@ class App
bool drawFps = true;
bool drawCameraFrustums = false;
bool drawCameraPath = false;
bool importFullSH = true;
};

protected:
MainContext& mainContext;
Options opt;
std::string plyFilename;
Expand Down
26 changes: 26 additions & 0 deletions src/core/binaryattribute.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright (c) 2024 Anthony J. Thibault
This software is licensed under the MIT License. See LICENSE for more details.
*/

#include "binaryattribute.h"

static uint32_t propertyTypeSizeArr[(size_t)BinaryAttribute::Type::NumTypes] = {
0, // Unknown
sizeof(int8_t), // Char
sizeof(uint8_t), // UChar
sizeof(int16_t), // Short
sizeof(uint16_t), // UShort
sizeof(int32_t), // Int
sizeof(uint32_t), // UInt
sizeof(float), // Float
sizeof(double) // Double
};

BinaryAttribute::BinaryAttribute(Type typeIn, size_t offsetIn) :
type(typeIn),
size(propertyTypeSizeArr[(uint32_t)typeIn]),
offset(offsetIn)
{
;
}
111 changes: 111 additions & 0 deletions src/core/binaryattribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
Copyright (c) 2024 Anthony J. Thibault
This software is licensed under the MIT License. See LICENSE for more details.
*/

#pragma once

#include <cassert>
#include <cstdint>
#include <functional>

class BinaryAttribute
{
public:
enum class Type
{
Unknown,
Char,
UChar,
Short,
UShort,
Int,
UInt,
Float,
Double,
NumTypes
};

BinaryAttribute() : type(Type::Unknown), size(0), offset(0) {}
BinaryAttribute(Type typeIn, size_t offsetIn);

template <typename T>
const T* Get(const void* data) const
{
if (type == Type::Unknown)
{
return nullptr;
}
else
{
assert(size == sizeof(T));
return reinterpret_cast<const T*>(static_cast<const uint8_t*>(data) + offset);
}
}

template <typename T>
T* Get(void* data)
{
if (type == Type::Unknown)
{
return nullptr;
}
else
{
assert(size == sizeof(T));
return reinterpret_cast<T*>(static_cast<uint8_t*>(data) + offset);
}
}

template <typename T>
const T Read(const void* data) const
{
const T* ptr = Get<T>(data);
return ptr ? *ptr : 0;
}

template <typename T>
bool Write(void* data, const T& val)
{
T* ptr = Get<T>(data);
if (ptr)
{
*ptr = val;
return true;
}
else
{
return false;
}
}

template<typename T>
void ForEachMut(void* data, size_t stride, size_t count, const std::function<void(T*)>& cb)
{
assert(type != Type::Unknown);
assert(data);
uint8_t* ptr = (uint8_t*)data;
for (size_t i = 0; i < count; i++)
{
cb((T*)(ptr + offset));
ptr += stride;
}
}

template<typename T>
void ForEach(const void* data, size_t stride, size_t count, const std::function<void(const T*)>& cb) const
{
assert(type != Type::Unknown);
assert(data);
const uint8_t* ptr = (const uint8_t*)data;
for (size_t i = 0; i < count; i++)
{
cb((const T*)(ptr + offset));
ptr += stride;
}
}

Type type;
size_t size;
size_t offset;
};
11 changes: 11 additions & 0 deletions src/core/vertexbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ static void glBufferStorage(GLenum target, GLsizeiptr size, const void* data, GL
}
#endif

BufferObject::BufferObject(int targetIn, void* data, size_t size, unsigned int flags)
{
target = targetIn;
glGenBuffers(1, &obj);
Bind();
glBufferStorage(target, size, data, flags);
Unbind();
elementSize = 0;
numElements = 0;
}

BufferObject::BufferObject(int targetIn, const std::vector<float>& data, unsigned int flags)
{
target = targetIn;
Expand Down
1 change: 1 addition & 0 deletions src/core/vertexbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class BufferObject
// flags can one of the following bitfields.
// GL_DYNAMIC_STORAGE_BIT, GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_PERSISTENT_BIT
// GL_MAP_COHERENT_BIT, GL_CLIENT_STORAGE_BIT
BufferObject(int targetIn, void* data, size_t size, unsigned int flags = 0);
BufferObject(int targetIn, const std::vector<float>& data, unsigned int flags = 0);
BufferObject(int targetIn, const std::vector<glm::vec2>& data, unsigned int flags = 0);
BufferObject(int targetIn, const std::vector<glm::vec3>& data, unsigned int flags = 0);
Expand Down
Loading