Skip to content

Commit

Permalink
renderer: Add drag select in HUD renderer.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Nov 25, 2023
1 parent c98933f commit 0e4c55a
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 52 deletions.
71 changes: 59 additions & 12 deletions libopenage/renderer/stages/hud/hud_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,117 @@

#include "hud_object.h"

#include "renderer/geometry.h"
#include "renderer/stages/hud/hud_render_entity.h"


namespace openage::renderer::hud {

HudObject::HudObject(const std::shared_ptr<renderer::resources::AssetManager> &asset_manager) :
HudDragObject::HudDragObject(const std::shared_ptr<renderer::resources::AssetManager> &asset_manager) :
require_renderable{true},
changed{false},
camera{nullptr},
asset_manager{asset_manager},
render_entity{nullptr},
drag_pos{nullptr, 0, "", nullptr, {0, 0}},
drag_start{0, 0},
uniforms{nullptr},
geometry{nullptr},
last_update{0.0} {
}

void HudObject::set_render_entity(const std::shared_ptr<HudRenderEntity> &entity) {
void HudDragObject::set_render_entity(const std::shared_ptr<HudDragRenderEntity> &entity) {
this->render_entity = entity;
this->fetch_updates();
}

void HudObject::set_camera(const std::shared_ptr<renderer::camera::Camera> &camera) {
void HudDragObject::set_camera(const std::shared_ptr<renderer::camera::Camera> &camera) {
this->camera = camera;
}

void HudObject::fetch_updates(const time::time_t &time) {
void HudDragObject::fetch_updates(const time::time_t &time) {
if (not this->render_entity->is_changed()) {
// exit early because there is nothing to do
return;
}

// Get data from render entity
// TODO
this->drag_start = this->render_entity->get_drag_start();
this->drag_pos.sync(this->render_entity->get_drag_pos(), this->last_update);

// Set self to changed so that world renderer can update the renderable
this->changed = true;
this->render_entity->clear_changed_flag();
this->last_update = time;
}

void HudObject::update_uniforms(const time::time_t &time) {
void HudDragObject::update_uniforms(const time::time_t & /* time */) {
// TODO: Only update uniforms that changed since last update
if (this->uniforms == nullptr) [[unlikely]] {
return;
}
// TODO

// TODO: Do something with the uniforms
}

bool HudObject::requires_renderable() {
void HudDragObject::update_geometry(const time::time_t &time) {
// TODO: Only update geometry that changed since last update
if (this->geometry == nullptr) [[unlikely]] {
return;
}

auto drag_start_ndc = this->drag_start.to_viewport(this->camera).to_ndc_space(this->camera);
auto drag_pos_ndc = this->drag_pos.get(time).to_viewport(this->camera).to_ndc_space(this->camera);

float top = std::max(drag_start_ndc.y(), drag_pos_ndc.y());
float bottom = std::min(drag_start_ndc.y(), drag_pos_ndc.y());
float left = std::min(drag_start_ndc.x(), drag_pos_ndc.x());
float right = std::max(drag_start_ndc.x(), drag_pos_ndc.x());

std::array<float, 16> quad_vertices{
top, left, 0.0f, 1.0f, // top left corner
bottom,
left,
0.0f,
0.0f, // bottom left corner
top,
right,
1.0f,
1.0f, // top right corner
bottom,
right,
1.0f,
0.0f // bottom right corner
};

std::vector<uint8_t> vertex_data(quad_vertices.size() * sizeof(float));
std::memcpy(vertex_data.data(), quad_vertices.data(), vertex_data.size());

this->geometry->update_verts(vertex_data);
}

bool HudDragObject::requires_renderable() {
return this->require_renderable;
}

void HudObject::clear_requires_renderable() {
void HudDragObject::clear_requires_renderable() {
this->require_renderable = false;
}

bool HudObject::is_changed() {
bool HudDragObject::is_changed() {
return this->changed;
}

void HudObject::clear_changed_flag() {
void HudDragObject::clear_changed_flag() {
this->changed = false;
}

void HudObject::set_uniforms(const std::shared_ptr<renderer::UniformInput> &uniforms) {
void HudDragObject::set_uniforms(const std::shared_ptr<renderer::UniformInput> &uniforms) {
this->uniforms = uniforms;
}

void HudDragObject::set_geometry(const std::shared_ptr<renderer::Geometry> &geometry) {
this->geometry = geometry;
}

} // namespace openage::renderer::hud
48 changes: 41 additions & 7 deletions libopenage/renderer/stages/hud/hud_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
#include <memory>
#include <string>

#include "coord/pixel.h"
#include "curve/continuous.h"
#include "time/time.h"


namespace openage::renderer {
class Geometry;
class UniformInput;

namespace camera {
Expand All @@ -23,19 +26,19 @@ class Animation2dInfo;
} // namespace resources

namespace hud {
class HudRenderEntity;
class HudDragRenderEntity;

class HudObject {
class HudDragObject {
public:
HudObject(const std::shared_ptr<renderer::resources::AssetManager> &asset_manager);
~HudObject() = default;
HudDragObject(const std::shared_ptr<renderer::resources::AssetManager> &asset_manager);
~HudDragObject() = default;

/**
* Set the world render entity.
*
* @param entity New world render entity.
*/
void set_render_entity(const std::shared_ptr<HudRenderEntity> &entity);
void set_render_entity(const std::shared_ptr<HudDragRenderEntity> &entity);

/**
* Set the current camera of the scene.
Expand All @@ -58,6 +61,13 @@ class HudObject {
*/
void update_uniforms(const time::time_t &time = 0.0);

/**
* Update the geometry of the renderable associated with this object.
*
* @param time Current simulation time.
*/
void update_geometry(const time::time_t &time = 0.0);

/**
* Check whether a new renderable needs to be created for this mesh.
*
Expand Down Expand Up @@ -95,6 +105,15 @@ class HudObject {
*/
void set_uniforms(const std::shared_ptr<renderer::UniformInput> &uniforms);

/**
* Set the geometry of the renderable associated with this object.
*
* The geometry is updated when calling \p update().
*
* @param geometry Geometry of this object's renderable.
*/
void set_geometry(const std::shared_ptr<renderer::Geometry> &geometry);

private:
/**
* Stores whether a new renderable for this object needs to be created
Expand All @@ -120,13 +139,28 @@ class HudObject {
/**
* Source for positional and texture data.
*/
std::shared_ptr<HudRenderEntity> render_entity;
std::shared_ptr<HudDragRenderEntity> render_entity;

/**
* Shader uniforms for the renderable in the terrain render pass.
* Position of the dragged corner.
*/
curve::Continuous<coord::input> drag_pos;

/**
* Position of the start corner.
*/
coord::input drag_start;

/**
* Shader uniforms for the renderable in the HUD render pass.
*/
std::shared_ptr<renderer::UniformInput> uniforms;

/**
* Geometry of the renderable in the HUD render pass.
*/
std::shared_ptr<renderer::Geometry> geometry;

/**
* Time of the last update call.
*/
Expand Down
28 changes: 21 additions & 7 deletions libopenage/renderer/stages/hud/hud_render_entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,44 @@

namespace openage::renderer::hud {

HudRenderEntity::HudRenderEntity() :
HudDragRenderEntity::HudDragRenderEntity(const coord::input drag_start) :
changed{false},
last_update{0.0} {
last_update{0.0},
drag_pos{nullptr, 0, "", nullptr, drag_start},
drag_start{drag_start} {
}

void HudRenderEntity::update(const time::time_t time) {
void HudDragRenderEntity::update(const coord::input drag_pos,
const time::time_t time) {
std::unique_lock lock{this->mutex};

// TODO
this->drag_pos.set_insert(time, drag_pos);

this->last_update = time;
this->changed = true;
}

time::time_t HudRenderEntity::get_update_time() {
time::time_t HudDragRenderEntity::get_update_time() {
std::shared_lock lock{this->mutex};

return this->last_update;
}

bool HudRenderEntity::is_changed() {
const curve::Continuous<coord::input> &HudDragRenderEntity::get_drag_pos() {
return this->drag_pos;
}

const coord::input &HudDragRenderEntity::get_drag_start() {
return this->drag_start;
}

bool HudDragRenderEntity::is_changed() {
std::shared_lock lock{this->mutex};

return this->changed;
}

void HudRenderEntity::clear_changed_flag() {
void HudDragRenderEntity::clear_changed_flag() {
std::unique_lock lock{this->mutex};

this->changed = false;
Expand Down
46 changes: 40 additions & 6 deletions libopenage/renderer/stages/hud/hud_render_entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,34 @@
#pragma once

#include <cstdint>
#include <list>
#include <shared_mutex>
#include <string>

#include "coord/pixel.h"
#include "curve/continuous.h"
#include "time/time.h"


namespace openage::renderer::hud {

class HudRenderEntity {
class HudDragRenderEntity {
public:
HudRenderEntity();
~HudRenderEntity() = default;
/**
* Create a new render entity for drag selection in the HUD.
*
* @param drag_start Position of the start corner.
*/
HudDragRenderEntity(const coord::input drag_start);
~HudDragRenderEntity() = default;

/**
* TODO: Update the render entity with information from the gamestate.
* Update the render entity with information from the gamestate.
*
* @param drag_pos Position of the dragged corner.
* @param time Current simulation time.
*/
void update(const time::time_t time = 0.0);
void update(const coord::input drag_pos,
const time::time_t time = 0.0);

/**
* Get the time of the last update.
Expand All @@ -29,6 +39,20 @@ class HudRenderEntity {
*/
time::time_t get_update_time();

/**
* Get the position of the dragged corner.
*
* @return Coordinates of the dragged corner.
*/
const curve::Continuous<coord::input> &get_drag_pos();

/**
* Get the position of the start corner.
*
* @return Coordinates of the start corner.
*/
const coord::input &get_drag_start();

/**
* Check whether the render entity has received new updates from the
* gamestate.
Expand All @@ -55,6 +79,16 @@ class HudRenderEntity {
*/
time::time_t last_update;

/**
* Position of the dragged corner.
*/
curve::Continuous<coord::input> drag_pos;

/**
* Position of the start corner.
*/
coord::input drag_start;

/**
* Mutex for protecting threaded access.
*/
Expand Down
Loading

0 comments on commit 0e4c55a

Please sign in to comment.