Skip to content

Commit

Permalink
feat(rendering): add RenderPicker plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas7770 committed Apr 4, 2024
1 parent 38fb934 commit 73a4587
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Addition and removal of resources through Commands (#325, **@RiscadoA**).
- Access to unscaled delta time for utilities like the debug camera (#1020, **@RiscadoA**).
- RenderTarget plugin (#1059, **@tomas7770**).
- RenderPicker plugin (#1060, **@tomas7770**).

### Changed

Expand Down
3 changes: 3 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ set(CUBOS_ENGINE_SOURCE

"src/render/target/plugin.cpp"
"src/render/target/target.cpp"

"src/render/picker/plugin.cpp"
"src/render/picker/picker.cpp"
)

# Create cubos engine
Expand Down
33 changes: 33 additions & 0 deletions engine/include/cubos/engine/render/picker/picker.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/// @file
/// @brief Component @ref cubos::engine::RenderPicker.
/// @ingroup render-picker-plugin

#pragma once

#include <glm/vec2.hpp>

#include <cubos/core/gl/render_device.hpp>
#include <cubos/core/reflection/reflect.hpp>

namespace cubos::engine
{
/// @brief Component which provides a texture to store entity/gizmo ids, for selection with a mouse.
/// @ingroup render-picker-plugin
struct RenderPicker
{
CUBOS_REFLECT;

/// @brief Size of the RenderPicker textures, in pixels.
glm::uvec2 size = {0, 0};

/// @brief Picking back texture, stores entity/gizmo ids for each pixel on the screen. Access to the
/// picker results should be made through this texture, to ensure the CPU doesn't wait for the current frame
/// to finish.
core::gl::Texture2D backTexture{nullptr};

/// @brief Picking front texture, stores entity/gizmo ids for each pixel on the screen. This is the texture
/// used by the renderer to write ids. It is automatically swapped with the back texture by the
/// renderPickerPlugin.
core::gl::Texture2D frontTexture{nullptr};
};
} // namespace cubos::engine
32 changes: 32 additions & 0 deletions engine/include/cubos/engine/render/picker/plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/// @dir
/// @brief @ref render-picker-plugin plugin directory.

/// @file
/// @brief Plugin entry point.
/// @ingroup render-picker-plugin

#pragma once

#include <cubos/engine/prelude.hpp>

namespace cubos::engine
{
/// @defgroup render-picker-plugin RenderPicker
/// @ingroup render-plugins
/// @brief Adds and manages @ref RenderPicker components.
///
/// ## Dependencies
/// - @ref window-plugin
/// - @ref render-target-plugin

/// @brief Recreates the RenderPicker if necessary - for example, due to a render target resize.
extern Tag createRenderPickerTag;

/// @brief Systems which draw to RenderPicker textures should be tagged with this.
extern Tag drawToRenderPickerTag;

/// @brief Plugin entry function.
/// @param cubos @b CUBOS. main class.
/// @ingroup render-picker-plugin
void renderPickerPlugin(Cubos& cubos);
} // namespace cubos::engine
12 changes: 12 additions & 0 deletions engine/src/render/picker/picker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <cubos/core/ecs/reflection.hpp>
#include <cubos/core/reflection/external/glm.hpp>
#include <cubos/core/reflection/external/primitives.hpp>

#include <cubos/engine/render/picker/picker.hpp>

CUBOS_REFLECT_IMPL(cubos::engine::RenderPicker)
{
return core::ecs::TypeBuilder<RenderPicker>("cubos::engine::RenderPicker")
.withField("size", &RenderPicker::size)
.build();
}
56 changes: 56 additions & 0 deletions engine/src/render/picker/plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <cubos/core/io/window.hpp>
#include <cubos/core/reflection/external/primitives.hpp>

#include <cubos/engine/render/picker/picker.hpp>
#include <cubos/engine/render/picker/plugin.hpp>
#include <cubos/engine/render/target/plugin.hpp>
#include <cubos/engine/render/target/target.hpp>
#include <cubos/engine/window/plugin.hpp>

using cubos::core::gl::Texture2DDesc;
using cubos::core::gl::TextureFormat;
using cubos::core::gl::Usage;
using cubos::core::io::Window;

CUBOS_DEFINE_TAG(cubos::engine::createRenderPickerTag);
CUBOS_DEFINE_TAG(cubos::engine::drawToRenderPickerTag);

void cubos::engine::renderPickerPlugin(Cubos& cubos)
{
cubos.depends(windowPlugin);
cubos.depends(renderTargetPlugin);

cubos.component<RenderPicker>();

cubos.tag(createRenderPickerTag).after(resizeRenderTargetTag);
cubos.tag(drawToRenderPickerTag).after(createRenderPickerTag);

cubos.system("resize RenderPickers")
.tagged(createRenderPickerTag)
.call([](const Window& window, Query<const RenderTarget&, RenderPicker&> query) {
for (auto [target, renderPicker] : query)
{
if (target.size != renderPicker.size)
{
renderPicker.size = target.size;

// Prepare common texture description.
Texture2DDesc desc{};
desc.width = renderPicker.size.x;
desc.height = renderPicker.size.y;
desc.usage = Usage::Dynamic;
desc.format = TextureFormat::RG16UInt;

auto& rd = window->renderDevice();

renderPicker.backTexture = rd.createTexture2D(desc);
renderPicker.frontTexture = rd.createTexture2D(desc);

CUBOS_INFO("Resized RenderPicker to {}x{}", renderPicker.size.x, renderPicker.size.y);
}

// Swap textures
std::swap(renderPicker.backTexture, renderPicker.frontTexture);
}
});
}

0 comments on commit 73a4587

Please sign in to comment.