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

Layer support in renderer #1645

Merged
merged 28 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ae6c34f
renderer: Store terrain tiles in render entity.
heinezen Apr 28, 2024
56994af
renderer: Don't use curve for terrain mesh.
heinezen May 1, 2024
8604027
renderer: Create mesh for individual terrain textures.
heinezen May 1, 2024
2233c71
renderer: Remove old terrain paths from render entity.
heinezen May 1, 2024
fc44940
assets: Add second test terrain asset.
heinezen May 1, 2024
2f20f31
gamestate: Use tile's asset path when updating renderer.
heinezen May 1, 2024
7a02427
gamestate: Add more choices to terrain examples.
heinezen May 1, 2024
8734667
gamestate: Add terrain test layouts to terrain factory.
heinezen May 1, 2024
a46451e
renderer: Fix vertex generation from tiles.
heinezen May 1, 2024
9329095
renderer: Order tayers by position.
heinezen May 3, 2024
f517790
renderer: Remove camera from world object.
heinezen May 3, 2024
fcfc596
renderer: Store uniforms for multiple layers in world object.
heinezen May 3, 2024
b576532
renderer: Draw multiple layers per animation.
heinezen May 3, 2024
d11e926
renderer: Split renderer.h into more source files.
heinezen May 3, 2024
253f94b
renderer: Remove unused variable.
heinezen May 3, 2024
85c4787
renderer: Priority sorting in render pass.
heinezen May 3, 2024
e33d481
renderer: Remove code duplication in render pass operations.
heinezen May 7, 2024
2b3262d
renderer: Autosort renderables into layers on insert.
heinezen May 8, 2024
10140c8
renderer: Make inserion by priority the default.
heinezen May 8, 2024
bf9b2f2
renderer: Move sorting of renderables to render pass.
heinezen May 8, 2024
b328def
renderer: Add more functions for optimization to GLRenderPass.
heinezen May 8, 2024
017c3be
renderer: Turn off optimization for OpenGL.
heinezen May 8, 2024
5746a5b
renderer: Use move semantics for adding renderables to pass.
heinezen May 8, 2024
fb93335
renderer: Add more comments to explain render pass logic.
heinezen May 8, 2024
82356fd
renderer: Revere ordering of layers in pass.
heinezen May 8, 2024
5f74b72
renderer: Allow configuring depth of added layers.
heinezen May 8, 2024
ac1be0f
doc: Document layer usage in level 1 renderer.
heinezen May 8, 2024
52663d6
renderer: Use vector of vectors for storing renderables.
heinezen May 8, 2024
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
Prev Previous commit
Next Next commit
renderer: Draw multiple layers per animation.
  • Loading branch information
heinezen committed May 9, 2024
commit b576532121de23b47dc1cb75e70504111065d49e
30 changes: 25 additions & 5 deletions libopenage/renderer/stages/world/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,18 @@ void WorldObject::set_render_entity(const std::shared_ptr<WorldRenderEntity> &en
}

void WorldObject::fetch_updates(const time::time_t &time) {
// TODO: Calling this once per frame is very expensive
auto layer_count = this->get_required_layer_count(time);
if (this->layer_uniforms.size() != layer_count) {
// The number of layers changed, so we need to update the renderables
this->require_renderable = true;
}

if (not this->render_entity->is_changed()) {
// exit early because there is nothing to do
// exit early because there is nothing to update
return;
}

// Get data from render entity
this->ref_id = this->render_entity->get_id();
this->position.sync(this->render_entity->get_position());
Expand Down Expand Up @@ -168,14 +176,27 @@ const renderer::resources::MeshData WorldObject::get_mesh() {
return resources::MeshData::make_quad();
}

bool WorldObject::requires_renderable() {
const Eigen::Matrix4f WorldObject::get_model_matrix() {
return Eigen::Matrix4f::Identity();
}

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

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

size_t WorldObject::get_required_layer_count(const time::time_t &time) const {
auto animation_info = this->animation_info.get(time);
if (not animation_info) {
return 0;
}

return animation_info->get_layer_count();
}

bool WorldObject::is_changed() {
return this->changed;
}
Expand All @@ -184,9 +205,8 @@ void WorldObject::clear_changed_flag() {
this->changed = false;
}

void WorldObject::set_uniforms(const std::shared_ptr<renderer::UniformInput> &uniforms) {
this->layer_uniforms.clear(); // ASDF: Update instead of clear
this->layer_uniforms.push_back(uniforms);
void WorldObject::set_uniforms(std::vector<std::shared_ptr<renderer::UniformInput>> &&uniforms) {
this->layer_uniforms = std::move(uniforms);
}

} // namespace openage::renderer::world
31 changes: 21 additions & 10 deletions libopenage/renderer/stages/world/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,19 @@ class WorldObject {
/**
* Get the quad for creating the geometry.
*
* Since the object is a bunch of sprite layers, the mesh is always a quad.
*
* @return Mesh for creating a renderer geometry object.
*/
static const renderer::resources::MeshData get_mesh();

/**
* Get the model matrix for the uniform input of a layer.
*
* @return Model matrix.
*/
static const Eigen::Matrix4f get_model_matrix();

/**
* Check whether a new renderable needs to be created for this mesh.
*
Expand All @@ -88,13 +97,20 @@ class WorldObject {
*
* @return true if a new renderable is required, else false.
*/
bool requires_renderable();
bool requires_renderable() const;

/**
* Indicate to this mesh that a new renderable has been created.
*/
void clear_requires_renderable();

/**
* Get the number of layers required by this object.
*
* @return Number of layers.
*/
size_t get_required_layer_count(const time::time_t &time) const;

/**
* Check whether the object was changed by \p update().
*
Expand All @@ -108,13 +124,12 @@ class WorldObject {
void clear_changed_flag();

/**
* Set the reference to the uniform inputs of the renderable
* associated with this object. Relevant uniforms are updated
* when calling \p update().
* Set the uniform inputs for the layers of this object.
* Layer uniforms are updated on every update call.
*
* @param uniforms Uniform inputs of this object's renderable.
* @param uniforms Uniform inputs of this object's layers.
*/
void set_uniforms(const std::shared_ptr<renderer::UniformInput> &uniforms);
void set_uniforms(std::vector<std::shared_ptr<renderer::UniformInput>> &&uniforms);

/**
* Shader uniform IDs for setting uniform values.
Expand Down Expand Up @@ -175,10 +190,6 @@ class WorldObject {
/**
* Shader uniforms for the layers of the object. Each layer corresponds to a
* renderable in the render pass.
*
* Since all layers are sprites and share the same geometry, we can reuse the layer uniforms and
* their renderables even if the animation changes. Therefore, we only need to add/remove
* layers when the _number_ of layers in the animation changes.
*/
std::vector<std::shared_ptr<renderer::UniformInput>> layer_uniforms;

Expand Down
49 changes: 27 additions & 22 deletions libopenage/renderer/stages/world/render_stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,36 @@ void WorldRenderStage::update() {
obj->fetch_updates(current_time);
if (obj->is_changed()) {
if (obj->requires_renderable()) {
Eigen::Matrix4f model_m = Eigen::Matrix4f::Identity();

// Set uniforms that don't change or are not changed often
auto transform_unifs = this->display_shader->new_uniform_input(
"model",
model_m,
"flip_x",
false,
"flip_y",
false,
"u_id",
obj->get_id());

Renderable display_obj{
transform_unifs,
this->default_geometry,
true,
true,
};

this->render_pass->add_renderables(display_obj);
auto layer_count = obj->get_required_layer_count(current_time);
Eigen::Matrix4f model_m = obj->get_model_matrix();

std::vector<std::shared_ptr<renderer::UniformInput>> transform_unifs;
for (size_t i = 0; i < layer_count; i++) {
// Set uniforms that don't change or are not changed often
auto layer_unifs = this->display_shader->new_uniform_input(
"model",
model_m,
"flip_x",
false,
"flip_y",
false,
"u_id",
obj->get_id());

Renderable display_obj{
layer_unifs,
this->default_geometry,
true,
true,
};
this->render_pass->add_renderables(display_obj);
transform_unifs.push_back(layer_unifs);
}

obj->clear_requires_renderable();

// update remaining uniforms for the object
obj->set_uniforms(transform_unifs);
obj->set_uniforms(std::move(transform_unifs));
}
}
obj->update_uniforms(current_time);
Expand Down