Skip to content

Commit

Permalink
Started Instanced Rendering. Swapped to libspng as faster...
Browse files Browse the repository at this point in the history
  • Loading branch information
WillisMedwell committed Mar 7, 2024
1 parent 244c595 commit 095c3f2
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 57 deletions.
Binary file added code/Demos/assets/texture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 26 additions & 5 deletions code/Demos/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ struct IsoData {
Core::AudioManager::SourceHandle source_handle;

Components::Spinning spinning;

Renderer::ResourceManager resource_manager;
Renderer::InstanceRenderer instance_renderer;
};
struct IsoLogic {
void init(AppRenderer& renderer, Core::AudioManager& audio, IsoData& data) {
Expand All @@ -427,14 +430,33 @@ struct IsoLogic {

data.source_handle = audio.play_sound(data.sound_buffer).on_error(print_then_quit).value();
data.start_time = std::chrono::high_resolution_clock::now();

auto model_data = std::move(
Utily::FileReader::load_entire_file("assets/teapot.obj")
.on_error(print_then_quit)
.value());
auto model = std::move(
Model::decode_as_static_model(model_data, ".obj")
.on_error(print_then_quit)
.value());

auto image_png = std::move(
Utily::FileReader::load_entire_file("assets/texture.png")
.on_error(print_then_quit)
.value());
auto image = Media::Image {};
image.init(image_png, true, false)
.on_error(print_then_quit);

data.instance_renderer.init(data.resource_manager, model, image);
}

void update(float dt, const Core::InputManager& input, Core::AudioManager& audio, AppState& state, IsoData& data) {
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - data.start_time);
if (duration > std::chrono::seconds(3) {
state.should_close = true;
}

if (duration > std::chrono::seconds(3)) {
state.should_close = true;
}

data.spinning.update(dt);
auto quat = data.spinning.calc_quat();
Expand All @@ -456,7 +478,6 @@ struct IsoLogic {
renderer.screen_frame_buffer.resize(renderer.window_width, renderer.window_height);
}
void stop(IsoData& data) {

}
};

Expand Down
7 changes: 4 additions & 3 deletions code/Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ find_package(Bullet CONFIG REQUIRED)
find_package(lodepng CONFIG REQUIRED)
find_package(Stb REQUIRED)
find_package(Freetype REQUIRED)

find_package(SPNG CONFIG REQUIRED)

include(FetchContent)

Expand All @@ -35,9 +35,10 @@ endif()

target_precompile_headers(Engine PRIVATE include/EnginePch.hpp)


if(DEFINED EMSCRIPTEN)
target_link_libraries(Engine PUBLIC
glm::glm assimp::assimp EnTT::EnTT Utily::Utily Freetype::Freetype lodepng ${BULLET_LIBRARIES}
glm::glm assimp::assimp EnTT::EnTT Utily::Utily Freetype::Freetype lodepng ${BULLET_LIBRARIES} $<IF:$<TARGET_EXISTS:spng::spng>,spng::spng,spng::spng_static>
)
target_include_directories(Engine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${Stb_INCLUDE_DIR})
target_compile_options(Engine PUBLIC
Expand All @@ -55,7 +56,7 @@ else()
find_package(GLFW3 CONFIG REQUIRED)
find_package(GLEW REQUIRED)
target_link_libraries(Engine PUBLIC
glm::glm assimp::assimp EnTT::EnTT Utily::Utily Freetype::Freetype lodepng ${BULLET_LIBRARIES}
glm::glm assimp::assimp EnTT::EnTT Utily::Utily Freetype::Freetype lodepng ${BULLET_LIBRARIES} $<IF:$<TARGET_EXISTS:spng::spng>,spng::spng,spng::spng_static>
OpenGL::GL OpenAL::OpenAL GLEW::GLEW glfw
)
if(MSVC)
Expand Down
73 changes: 63 additions & 10 deletions code/Engine/include/Core/VertexArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#include <optional>

#include "Config.hpp"
#include "Core/DebugOpRecorder.hpp"
#include "Core/IndexBuffer.hpp"
#include "Core/VertexBuffer.hpp"
#include "Core/VertexBufferLayout.hpp"
#include "Core/DebugOpRecorder.hpp"
#include <Utily/Utily.hpp>

namespace Core {
Expand All @@ -16,6 +16,8 @@ namespace Core {
{
constexpr static uint32_t INVALID_ARRAY_OBJECT_ID = 0;

using VBLMat4 = Core::VertexBufferLayout<glm::vec4, glm::vec4, glm::vec4, glm::vec4>;

public:
VertexArray() = default;
VertexArray(const VertexArray&) = delete;
Expand All @@ -24,7 +26,7 @@ namespace Core {
template <typename... Args>
[[nodiscard]] auto init(Core::VertexBufferLayout<Args...> vbl, Core::VertexBuffer& vb, Core::IndexBuffer& ib) noexcept -> Utily::Result<void, Utily::Error> {
Core::DebugOpRecorder::instance().push("Core::VertexArray", "init()");

// generation
if (_id) {
return Utily::Error { "Trying to override in-use Vertex Array Object" };
Expand All @@ -35,30 +37,81 @@ namespace Core {
_id = std::nullopt;
return Utily::Error { "Failed to create Vertex Array Object. glGenVertexArrays failed." };
}
// bind associated ib, and vb


// bind associated ib, and vb
this->bind();
ib.bind();
vb.bind();
this->bind();

constexpr static auto layout = vbl.get_layout();
constexpr static auto stride = vbl.get_stride();

uint32_t offset = 0;
for (size_t i = 0; i < layout.size(); i++) {
const auto& element = layout[i];
#if defined(CONFIG_TARGET_NATIVE)
glEnableVertexArrayAttrib(get_id().value(), i);
#elif defined(CONFIG_TARGET_WEB)
glEnableVertexAttribArray(i);
#endif
glVertexAttribPointer(i, element.count, element.type, element.normalised, stride, reinterpret_cast<const void*>(offset));
glEnableVertexAttribArray(i);
offset += element.type_size;
}
return {};
}

template <typename... Args>
[[nodiscard]] auto init(
Core::VertexBufferLayout<Args...> vbl,
Core::VertexBuffer& vb_mesh,
Core::VertexBuffer& vb_transforms,
Core::IndexBuffer& ib) noexcept -> Utily::Result<void, Utily::Error> {

Core::DebugOpRecorder::instance().push("Core::VertexArray", "init_as_instance()");
// generation
if (_id) {
return Utily::Error { "Trying to override in-use Vertex Array Object" };
}
_id = INVALID_ARRAY_OBJECT_ID;
glGenVertexArrays(1, &_id.value());
if (_id.value() == INVALID_ARRAY_OBJECT_ID) {
_id = std::nullopt;
return Utily::Error { "Failed to create Vertex Array Object. glGenVertexArrays failed." };
}

this->bind();
ib.bind();

size_t layout_index = 0;
{ // set the VA attribs for the mesh VB
vb_mesh.bind();

constexpr static auto layout = vbl.get_layout();
constexpr static auto stride = vbl.get_stride();
for (uint32_t offset = 0; layout_index < layout.size(); ++layout_index) {
const auto& element = layout[layout_index];
glVertexAttribPointer(layout_index, element.count, element.type, element.normalised, stride, reinterpret_cast<const void*>(offset));
glEnableVertexAttribArray(layout_index);
glVertexAttribDivisor(layout_index, 0);
offset += element.type_size;
}
}

{ // set the VA attribs for the instance transform VB
vb_transforms.bind();

constexpr static auto layout = VBLMat4 {}.get_layout();
constexpr static auto stride = VBLMat4 {}.get_stride();

uint32_t max_layout_index = layout_index + layout.size();

for (uint32_t i = 0, offset = 0; layout_index < max_layout_index; ++i, ++layout_index) {
const auto& element = layout[i];
glVertexAttribPointer(layout_index, element.count, element.type, element.normalised, stride, reinterpret_cast<const void*>(offset));
glEnableVertexAttribArray(layout_index);
glVertexAttribDivisor(layout_index, 1);
offset += element.type_size;
}
}
return {};
}

void stop() noexcept;

void bind() noexcept;
Expand Down
2 changes: 1 addition & 1 deletion code/Engine/include/Model/Static.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Model {

auto decode_as_static_model(
std::span<uint8_t> file_data,
Utily::StaticVector<char, 16> file_extension)
std::string_view file_extension)
-> Utily::Result<Static, Utily::Error>;

auto join(Static&& lhs, Static&& rhs) -> Model::Static;
Expand Down
2 changes: 2 additions & 0 deletions code/Engine/include/Renderer/FontBatchRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Renderer {
glm::vec4 font_colour;
};
void init(ResourceManager& resource_manager, Media::FontAtlas& font_atlas);

void begin_batch(BatchConfig&& batch_config);
void push_to_batch(std::string_view text, glm::vec2 bottom_left, float height_px);
void end_batch();
Expand All @@ -25,6 +26,7 @@ namespace Renderer {
glm::vec2 uv_coord;
using VBL = Core::VertexBufferLayout<glm::vec2, glm::vec2>;
};

std::optional<BatchConfig> _current_batch_config = std::nullopt;
std::vector<Vertex> _current_batch_vertices = {};

Expand Down
26 changes: 26 additions & 0 deletions code/Engine/include/Renderer/InstanceRenderer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "Core/Core.hpp"
#include "Media/Media.hpp"
#include "Renderer/ResourceManager.hpp"

namespace Renderer {
class InstanceRenderer
{
public:
void init(ResourceManager& resource_manager, const Model::Static& model, Media::Image& image);
void stop(ResourceManager& resource_manager);

void push_instance(const glm::mat4& instance_transformation);
void draw_instances(ResourceManager& resource_manager, glm::vec2 screen_dimensions);
private:
Renderer::ResourceHandle<Core::Shader> _s;
Renderer::ResourceHandle<Core::Texture> _t;
Renderer::ResourceHandle<Core::VertexBuffer> _vb_mesh; // the mesh of the instance.
Renderer::ResourceHandle<Core::VertexBuffer> _vb_transforms; // the matrix transformation of each instance.
Renderer::ResourceHandle<Core::IndexBuffer> _ib;
Renderer::ResourceHandle<Core::VertexArray> _va;

std::vector<glm::mat4> _current_instances;
};
}
2 changes: 1 addition & 1 deletion code/Engine/include/Renderer/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ namespace Renderer {
#include "Renderer/ResourceManager.hpp"
#include "Renderer/FontRenderer.hpp"
#include "Renderer/FontBatchRenderer.hpp"

#include "Renderer/InstanceRenderer.hpp"
20 changes: 13 additions & 7 deletions code/Engine/include/Renderer/ResourceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace Renderer {
constexpr static size_t MAX_VA = 32;
constexpr static size_t MAX_IB = 32;

#if 0
#if 1
Utily::StaticVector<Core::Shader, MAX_S> _shaders;
Utily::StaticVector<Core::Texture, MAX_T> _textures;
Utily::StaticVector<Core::VertexArray, MAX_VA> _vertex_arrays;
Expand All @@ -48,7 +48,7 @@ namespace Renderer {
std::vector<Core::VertexBuffer> _vertex_buffers;
#endif

size_t owner_id;
size_t _owner_id;

template <typename T>
inline constexpr auto& get_resource_buffer() {
Expand All @@ -68,18 +68,24 @@ namespace Renderer {
}

public:
/// @brief Allocate a Core resource and initialise it in place.
/// @tparam T Resource Type (e.g. Core::VertexBuffer, Core::Texture, ...)
/// @param ...args Parameters for when T::init() is called.
/// @return [resource_handle, resource_ref]
template <typename T, typename... Args>
[[nodiscard]] inline auto create_and_init_resource(Args&&... args) -> std::tuple<ResourceHandle<T>, T&> {
auto& resource_buffer = get_resource_buffer<T>();
ResourceHandle<T> handle { resource_buffer.size(), this->owner_id };

ResourceHandle<T> handle { resource_buffer.size(), this->_owner_id };

resource_buffer.emplace_back();

T& resource = resource_buffer[handle.id.value()];

static_assert(CanBeInitWithArgs<T, Args...>, "The Args must be params for the method T::init()");
resource.init(std::forward<Args>(args)...)
.on_error([](auto& error) {
std::cout << error.what() << std::endl;
throw std::runtime_error(std::string(error.what()));
});

Expand All @@ -89,7 +95,7 @@ namespace Renderer {
template <typename T>
[[nodiscard]] inline auto get_resource(ResourceHandle<T> handle) -> T& {
auto& resource_buffer = get_resource_buffer<T>();
assert(handle.resource_owner_id == this->owner_id);
assert(handle.resource_owner_id == this->_owner_id);
if (handle.id) {
return resource_buffer[handle.id.value()];
} else {
Expand All @@ -105,7 +111,7 @@ namespace Renderer {
template <typename T>
inline void free_resource(ResourceHandle<T> handle) {
auto& resource_buffer = get_resource_buffer<T>();
assert(handle.resource_owner_id == this->owner_id);
assert(handle.resource_owner_id == this->_owner_id);
if (handle.id) {
resource_buffer[handle.id.value()].stop();
}
Expand All @@ -119,7 +125,7 @@ namespace Renderer {
ResourceManager() {
static std::mt19937 rng(std::random_device {}());
static std::uniform_int_distribution<size_t> dist { 0, std::numeric_limits<size_t>::max() };
owner_id = dist(rng);
_owner_id = dist(rng);
}
};
}
3 changes: 2 additions & 1 deletion code/Engine/src/Core/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ namespace Core {
bytes_per_pixel = 1;
gl_format = GL_RED;
} else {
gl_format = GL_RGBA8;
gl_format = GL_RGBA;
bytes_per_pixel = 4;
}
const void* img_data = reinterpret_cast<const void*>(image.raw_bytes().data());
glPixelStorei(GL_UNPACK_ALIGNMENT, bytes_per_pixel);

glTexImage2D(GL_TEXTURE_2D, 0, (GLint)image.format(), image.dimensions().x, image.dimensions().y, 0, gl_format, GL_UNSIGNED_BYTE, img_data);

if (offload_image_on_success) {
Expand Down
13 changes: 0 additions & 13 deletions code/Engine/src/Core/VertexArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,6 @@ namespace Core {
: _id(std::exchange(other._id, std::nullopt)) {
}

// auto VertexArray::init() noexcept -> Utily::Result<void, Utily::Error> {
// if (_id) {
// return Utily::Error { "Trying to override in-use Vertex Array Object" };
// }
// _id = INVALID_ARRAY_OBJECT_ID;
// glGenVertexArrays(1, &_id.value());
// if (_id.value() == INVALID_ARRAY_OBJECT_ID) {
// _id = std::nullopt;
// return Utily::Error { "Failed to create Vertex Array Object. glGenVertexArrays failed." };
// }
// return {};
// }

void VertexArray::stop() noexcept {
Core::DebugOpRecorder::instance().push("Core::VertexArray", "stop()");

Expand Down
Loading

0 comments on commit 095c3f2

Please sign in to comment.