Skip to content

Commit

Permalink
add demo7 to test shader command
Browse files Browse the repository at this point in the history
  • Loading branch information
ZzzhHe committed Jan 23, 2025
1 parent 8cda18b commit 84abb5d
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 1 deletion.
34 changes: 34 additions & 0 deletions assets/test/shaders/demo_7_world.frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#version 330

in vec2 vert_uv;

layout(location = 0) out vec4 col;
layout(location = 1) out uint id;

uniform sampler2D tex;
uniform uint u_id;

// position (top left corner) and size: (x, y, width, height)
uniform vec4 tile_params;

vec2 uv = vec2(
vert_uv.x * tile_params.z + tile_params.x,
vert_uv.y *tile_params.w + tile_params.y);

void main() {
vec4 tex_val = texture(tex, uv);
int alpha = int(round(tex_val.a * 255));
switch (alpha) {
case 0:
col = tex_val;
discard;

// do not save the ID
return;
//@COMMAND_SWITCH@
default:
col = tex_val;
break;
}
id = u_id;
}
101 changes: 101 additions & 0 deletions assets/test/shaders/demo_7_world.vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#version 330

layout(location=0) in vec2 v_position;
layout(location=1) in vec2 uv;

out vec2 vert_uv;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
// view matrix (world to view space)
mat4 view;
// projection matrix (view to clip space)
mat4 proj;
// inverse zoom factor (1.0 / zoom)
// high zoom = upscale subtex
// low zoom = downscale subtex
float inv_zoom;
// inverse viewport size (1.0 / viewport size)
vec2 inv_viewport_size;
};

// can be used to move the object position in world space _before_
// it's transformed to clip space
// this is usually unnecessary because we want to draw the
// subtex where the object is, so this can be set to the identity matrix
uniform mat4 model;

// position of the object in world space
uniform vec3 obj_world_position;

// flip the subtexture horizontally/vertically
uniform bool flip_x;
uniform bool flip_y;

// parameters for scaling and moving the subtex
// to the correct position in clip space

// animation scalefactor
// scales the vertex positions so that they
// match the subtex dimensions
//
// high animation scale = downscale subtex
// low animation scale = upscale subtex
uniform float scale;

// size of the subtex (in pixels)
uniform vec2 subtex_size;

// offset of the subtex anchor point
// from the subtex center (in pixels)
// used to move the subtex so that the anchor point
// is at the object position
uniform vec2 anchor_offset;

void main() {
// translate the position of the object from world space to clip space
// this is the position where we want to draw the subtex in 2D
vec4 obj_clip_pos = proj * view * model * vec4(obj_world_position, 1.0);

// subtex has to be scaled to account for the zoom factor
// and the animation scale factor. essentially this is (animation scale / zoom).
float zoom_scale = scale * inv_zoom;

// Scale the subtex vertices
// we have to account for the viewport size to get the correct dimensions
// and then scale the subtex to the zoom factor to get the correct size
vec2 vert_scale = zoom_scale * subtex_size * inv_viewport_size;

// Scale the anchor offset with the same method as above
// to get the correct anchor position in the viewport
vec2 anchor_scale = zoom_scale * anchor_offset * inv_viewport_size;

// if the subtex is flipped, we also need to flip the anchor offset
// essentially, we invert the coordinates for the flipped axis
float anchor_x = float(flip_x) * -1.0 * anchor_scale.x + float(!flip_x) * anchor_scale.x;
float anchor_y = float(flip_y) * -1.0 * anchor_scale.y + float(!flip_y) * anchor_scale.y;

// offset the clip position by the offset of the subtex anchor
// imagine this as pinning the subtex to the object position at the subtex anchor point
obj_clip_pos += vec4(anchor_x, anchor_y, 0.0, 0.0);

// create a move matrix for positioning the vertices
// uses the vert scale and the transformed object position in clip space
mat4 move = mat4(vert_scale.x, 0.0, 0.0, 0.0,
0.0, vert_scale.y, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
obj_clip_pos.x, obj_clip_pos.y, obj_clip_pos.z, 1.0);

// calculate the final vertex position
gl_Position = move * vec4(v_position, 0.0, 1.0);

// if the subtex is flipped, we also need to flip the uv tex coordinates
// essentially, we invert the coordinates for the flipped axis

// !flip_x is default because OpenGL uses bottom-left as its origin
float uv_x = float(!flip_x) * uv.x + float(flip_x) * (1.0 - uv.x);
float uv_y = float(flip_y) * uv.y + float(!flip_y) * (1.0 - uv.y);

vert_uv = vec2(uv_x, uv_y);
}
23 changes: 23 additions & 0 deletions assets/test/shaders/world_commands.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[COMMAND]
placeholder=COMMAND_SWITCH
alpha=254
description=Red tint
code={
col = vec4(1.0, 0.0, 0.0, 1.0) * tex_val;
}

[COMMAND]
placeholder=COMMAND_SWITCH
alpha=252
description=Green tint
code={
col = vec4(0.0, 1.0, 0.0, 1.0) * tex_val;
}

[COMMAND]
placeholder=COMMAND_SWITCH
alpha=250
description=Blue tint
code={
col = vec4(0.0, 0.0, 1.0, 1.0) * tex_val;
}
1 change: 1 addition & 0 deletions libopenage/renderer/demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_sources(libopenage
demo_4.cpp
demo_5.cpp
demo_6.cpp
demo_7.cpp
stresstest_0.cpp
stresstest_1.cpp
tests.cpp
Expand Down
106 changes: 106 additions & 0 deletions libopenage/renderer/demo/demo_7.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// demo_shader_commands.h
#pragma once

#include "util/path.h"

#include <eigen3/Eigen/Dense>
#include <QKeyEvent>

#include "coord/tile.h"
#include "renderer/camera/camera.h"
#include "renderer/gui/integration/public/gui_application_with_logger.h"
#include "renderer/opengl/window.h"
#include "renderer/render_factory.h"
#include "renderer/render_pass.h"
#include "renderer/render_target.h"
#include "renderer/resources/assets/asset_manager.h"
#include "renderer/resources/shader_source.h"
#include "renderer/stages/camera/manager.h"
#include "renderer/stages/screen/render_stage.h"
#include "renderer/stages/skybox/render_stage.h"
#include "renderer/stages/terrain/render_entity.h"
#include "renderer/stages/terrain/render_stage.h"
#include "renderer/stages/world/render_entity.h"
#include "renderer/stages/world/render_stage.h"
#include "renderer/uniform_buffer.h"
#include "time/clock.h"

namespace openage::renderer::tests {

void renderer_demo_7(const util::Path &path) {
// Basic setup
auto qtapp = std::make_shared<gui::GuiApplicationWithLogger>();
window_settings settings;
settings.width = 800;
settings.height = 600;
settings.debug = true;

auto window = std::make_shared<opengl::GlWindow>("Shader Commands Demo", settings);
auto renderer = window->make_renderer();
auto camera = std::make_shared<renderer::camera::Camera>(renderer, window->get_size());
auto clock = std::make_shared<time::Clock>();
auto asset_manager = std::make_shared<renderer::resources::AssetManager>(
renderer,
path["assets"]["test"]);
auto cam_manager = std::make_shared<renderer::camera::CameraManager>(camera);

auto shaderdir = path / "assets" / "test" / "shaders";

std::vector<std::shared_ptr<RenderPass>>
render_passes{};

// Initialize world renderer with shader commands
auto world_renderer = std::make_shared<renderer::world::WorldRenderStage>(
window,
renderer,
camera,
shaderdir,
shaderdir, // Temporarily, Shader commands config has the same path with shaders for this demo
asset_manager,
clock);

render_passes.push_back(world_renderer->get_render_pass());

auto screen_renderer = std::make_shared<renderer::screen::ScreenRenderStage>(
window,
renderer,
path["assets"]["shaders"]);
std::vector<std::shared_ptr<renderer::RenderTarget>> targets{};
for (auto &pass : render_passes) {
targets.push_back(pass->get_target());
}
screen_renderer->set_render_targets(targets);

render_passes.push_back(screen_renderer->get_render_pass());

auto render_factory = std::make_shared<RenderFactory>(nullptr, world_renderer);

auto entity1 = render_factory->add_world_render_entity();
entity1->update(0, coord::phys3(0.0f, 0.0f, 0.0f), "./textures/test_gaben.sprite");

auto entity2 = render_factory->add_world_render_entity();
entity2->update(1, coord::phys3(3.0f, 0.0f, 0.0f), "./textures/test_gaben.sprite");

auto entity3 = render_factory->add_world_render_entity();
entity3->update(2, coord::phys3(-3.0f, 0.0f, 0.0f), "./textures/test_gaben.sprite");

// Main loop
while (not window->should_close()) {
qtapp->process_events();

// Update camera matrices
cam_manager->update();

world_renderer->update();

for (auto &pass : render_passes) {
renderer->render(pass);
}

renderer->check_error();

window->update();
}
}

} // namespace openage::renderer::tests
22 changes: 22 additions & 0 deletions libopenage/renderer/demo/demo_7.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2025-2025 the openage authors. See copying.md for legal info.

#pragma once

#include "util/path.h"

namespace openage::renderer::tests {

/**
* Show off the render stages in the level 2 renderer and the camera
* system.
* - Window creation
* - Creating a camera
* - Initializing the level 2 render stages: skybox, terrain, world, screen
* - Adding renderables to the render stages via the render factory
* - Moving camera with mouse/keyboard callbacks
*
* @param path Path to the project rootdir.
*/
void renderer_demo_7(const util::Path &path);

} // namespace openage::renderer::tests
7 changes: 6 additions & 1 deletion libopenage/renderer/demo/tests.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015-2024 the openage authors. See copying.md for legal info.
// Copyright 2015-2025 the openage authors. See copying.md for legal info.

#include "tests.h"

Expand All @@ -12,6 +12,7 @@
#include "renderer/demo/demo_4.h"
#include "renderer/demo/demo_5.h"
#include "renderer/demo/demo_6.h"
#include "renderer/demo/demo_7.h"
#include "renderer/demo/stresstest_0.h"
#include "renderer/demo/stresstest_1.h"

Expand Down Expand Up @@ -47,6 +48,10 @@ void renderer_demo(int demo_id, const util::Path &path) {
renderer_demo_6(path);
break;

case 7:
renderer_demo_7(path);
break;

default:
log::log(MSG(err) << "Unknown renderer demo requested: " << demo_id << ".");
break;
Expand Down

0 comments on commit 84abb5d

Please sign in to comment.