| Line |
Branch |
Exec |
Source |
| 1 |
|
|
#include <utility> |
| 2 |
|
|
|
| 3 |
|
|
// todo(Gustav): look into glad support |
| 4 |
|
|
#define SDL_FUNCTION_POINTER_IS_VOID_POINTER |
| 5 |
|
|
|
| 6 |
|
|
#include "SDL.h" |
| 7 |
|
|
|
| 8 |
|
|
// #include <string> |
| 9 |
|
|
|
| 10 |
|
|
#include "eu/log/log.h" |
| 11 |
|
|
|
| 12 |
|
|
#include "eu/core/geom.builder.h" |
| 13 |
|
|
#include "eu/core/geom.h" |
| 14 |
|
|
|
| 15 |
|
|
#include "eu/io/file.h" |
| 16 |
|
|
#include "eu/io/mesh.h" |
| 17 |
|
|
|
| 18 |
|
|
#include "eu/render/canvas.h" |
| 19 |
|
|
#include "eu/render/state.h" |
| 20 |
|
|
#include "eu/render/font.h" |
| 21 |
|
|
#include "eu/render/opengl_utils.h" |
| 22 |
|
|
#include "eu/render/texture.io.h" |
| 23 |
|
|
#include "eu/render/camera.h" |
| 24 |
|
|
#include "eu/render/compiledmesh.h" |
| 25 |
|
|
#include "eu/render/enable_high_performance_graphics.h" |
| 26 |
|
|
#include "eu/render/postproc.h" |
| 27 |
|
|
#include "eu/render/renderer.h" |
| 28 |
|
|
#include "eu/render/world.h" |
| 29 |
|
|
|
| 30 |
|
|
#include "eu/runner/script.h" |
| 31 |
|
|
#include "eu/runner/input.h" |
| 32 |
|
|
#include "eu/runner/entity.h" |
| 33 |
|
|
|
| 34 |
|
|
#include "eu/kdl/kdl.h" |
| 35 |
|
|
|
| 36 |
|
|
|
| 37 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 38 |
|
|
#include "eu/imgui/ui.h" |
| 39 |
|
|
#include "eu/imgui/init.h" |
| 40 |
|
|
#include "eu/imgui/debug.h" |
| 41 |
|
|
|
| 42 |
|
|
#include "dear_imgui/imgui.h" |
| 43 |
|
|
#include "dear_imgui/backends/imgui_impl_sdl3.h" |
| 44 |
|
|
#include "dear_imgui/backends/imgui_impl_opengl3.h" |
| 45 |
|
|
#endif |
| 46 |
|
|
|
| 47 |
|
|
|
| 48 |
|
|
ENABLE_HIGH_PERFORMANCE_GRAPHICS |
| 49 |
|
|
|
| 50 |
|
|
using namespace eu; |
| 51 |
|
|
using namespace std::string_view_literals; |
| 52 |
|
|
|
| 53 |
|
|
// todo(Gustav): move to io |
| 54 |
|
✗ |
eu::render::ShaderSource load_shader(const std::string& name) |
| 55 |
|
|
{ |
| 56 |
|
|
return { |
| 57 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 21 not taken.
|
✗ |
.vertex = eu::io::string_from_file(name + ".vert.glsl"), |
| 58 |
|
✗ |
.fragment = eu::io::string_from_file(name + ".frag.glsl") |
| 59 |
|
✗ |
}; |
| 60 |
0/10
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 19 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 15 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 13 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
|
✗ |
} |
| 61 |
|
|
|
| 62 |
|
✗ |
eu::Size size_from_v2(const eu::v2& v) |
| 63 |
|
|
{ |
| 64 |
|
✗ |
return eu::Size{ .width = eu::int_from_float(v.x), .height = eu::int_from_float(v.y) }; |
| 65 |
|
|
} |
| 66 |
|
|
|
| 67 |
|
✗ |
std::shared_ptr<eu::render::Texture2d> load_texture(const std::string& path, eu::render::ColorData cd, |
| 68 |
|
|
eu::render::TextureEdge texture_edge = eu::render::TextureEdge::repeat, |
| 69 |
|
|
eu::render::Transparency transparency = eu::render::Transparency::exclude) |
| 70 |
|
|
{ |
| 71 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 19 not taken.
|
✗ |
const auto bin = eu::io::bytes_from_file(path); |
| 72 |
|
|
return std::make_shared<eu::render::Texture2d>( |
| 73 |
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 15 not taken.
|
✗ |
load_image_from_embedded(SEND_DEBUG_LABEL_MANY(path) embedded_binary { reinterpret_cast<const unsigned int*>(bin.data()), static_cast<unsigned int>(bin.size()) }, texture_edge, eu::render::TextureRenderStyle::mipmap, transparency, cd) |
| 74 |
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 13 not taken.
|
✗ |
); |
| 75 |
|
✗ |
} |
| 76 |
|
|
|
| 77 |
|
✗ |
std::shared_ptr<eu::render::Texture2d> create_texture(DEBUG_LABEL_ARG_MANY eu::core::SingleColor pixel_color, eu::render::ColorData cd) |
| 78 |
|
|
{ |
| 79 |
|
|
return std::make_shared<eu::render::Texture2d>( |
| 80 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 10 not taken.
|
✗ |
load_image_from_color(SEND_DEBUG_LABEL_MANY(debug_label) pixel_color, eu::render::TextureEdge::repeat, eu::render::TextureRenderStyle::pixel, eu::render::Transparency::exclude, cd) |
| 81 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 8 not taken.
|
✗ |
); |
| 82 |
|
|
} |
| 83 |
|
|
|
| 84 |
|
|
enum class RotationType |
| 85 |
|
|
{ |
| 86 |
|
|
a, b, c, d |
| 87 |
|
|
}; |
| 88 |
|
|
|
| 89 |
|
✗ |
RotationType ypr_from_kdl_rotation(int rot) |
| 90 |
|
|
{ |
| 91 |
0/5
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 6 not taken.
✗ Branch 2 → 7 not taken.
|
✗ |
switch (rot) |
| 92 |
|
|
{ |
| 93 |
|
✗ |
case 22: // 10x |
| 94 |
|
✗ |
return RotationType::a; |
| 95 |
|
✗ |
case 10: // 104x |
| 96 |
|
✗ |
return RotationType::b; |
| 97 |
|
✗ |
case 16: // 15x |
| 98 |
|
✗ |
return RotationType::c; |
| 99 |
|
✗ |
case 0: // 25x |
| 100 |
|
✗ |
return RotationType::d; |
| 101 |
|
✗ |
default: |
| 102 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
|
✗ |
DIE("invalid rotation"); |
| 103 |
|
✗ |
return RotationType::a; |
| 104 |
|
|
} |
| 105 |
|
|
} |
| 106 |
|
|
|
| 107 |
|
|
struct TileRotation |
| 108 |
|
|
{ |
| 109 |
|
|
Ypr rotation; |
| 110 |
|
|
v3 offset; |
| 111 |
|
|
}; |
| 112 |
|
|
|
| 113 |
|
|
struct RotationData |
| 114 |
|
|
{ |
| 115 |
|
|
TileRotation a = {.rotation = {.yaw = 90_deg, .pitch = 0_deg, .roll = 0_deg }, .offset = zero3f }; |
| 116 |
|
|
TileRotation b = {.rotation = {.yaw = 180_deg, .pitch = 0_deg, .roll = 0_deg }, .offset = zero3f }; |
| 117 |
|
|
TileRotation c = {.rotation = {.yaw = -90_deg, .pitch = 0_deg, .roll = 0_deg }, .offset = zero3f }; |
| 118 |
|
|
TileRotation d = {.rotation = {.yaw = 0_deg, .pitch = 0_deg, .roll = 0_deg }, .offset = zero3f }; |
| 119 |
|
|
|
| 120 |
|
✗ |
[[nodiscard]] const TileRotation& get_rotation(RotationType type) const |
| 121 |
|
|
{ |
| 122 |
0/5
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 6 not taken.
✗ Branch 2 → 7 not taken.
|
✗ |
switch (type) |
| 123 |
|
|
{ |
| 124 |
|
✗ |
case RotationType::a: |
| 125 |
|
✗ |
return a; |
| 126 |
|
✗ |
case RotationType::b: |
| 127 |
|
✗ |
return b; |
| 128 |
|
✗ |
case RotationType::c: |
| 129 |
|
✗ |
return c; |
| 130 |
|
✗ |
case RotationType::d: |
| 131 |
|
✗ |
return d; |
| 132 |
|
✗ |
default: |
| 133 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
|
✗ |
DIE("unknown rotation type"); |
| 134 |
|
✗ |
return a; |
| 135 |
|
|
} |
| 136 |
|
|
} |
| 137 |
|
|
}; |
| 138 |
|
|
|
| 139 |
|
|
struct Tile |
| 140 |
|
|
{ |
| 141 |
|
|
RotationType type; |
| 142 |
|
|
v3 position; |
| 143 |
|
|
std::unique_ptr<render::MeshInWorld> mesh; |
| 144 |
|
|
|
| 145 |
|
✗ |
void update(const RotationData& rotation_data) |
| 146 |
|
|
{ |
| 147 |
|
✗ |
const auto& rotation = rotation_data.get_rotation(type); |
| 148 |
0/6
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 8 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 8 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
|
✗ |
mesh->set_transform(eu::render::transform_from_rotation(position + rotation.offset, rotation.rotation)); |
| 149 |
|
✗ |
} |
| 150 |
|
|
}; |
| 151 |
|
|
|
| 152 |
|
|
struct Level |
| 153 |
|
|
{ |
| 154 |
|
|
std::unordered_map<std::string, std::unique_ptr<eu::render::CompiledMesh>> meshes; |
| 155 |
|
|
std::vector<Tile> tiles; |
| 156 |
|
|
RotationData rotation_data; |
| 157 |
|
|
|
| 158 |
|
✗ |
void load(const std::string& path, render::World* world, std::shared_ptr<render::DefaultMaterial> material, const core::CompiledGeomVertexAttributes& layout) |
| 159 |
|
|
{ |
| 160 |
|
|
// todo(Gustav): this is very hacky but just something so we can play a level |
| 161 |
|
✗ |
v3 offset = { 0.0f, 0.0f, 0.0f }; |
| 162 |
|
✗ |
v3 size = { 1.0f, 1.0f, 1.0f }; |
| 163 |
|
|
|
| 164 |
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 151 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 149 not taken.
|
✗ |
const auto parsed = kdl::parse(eu::io::string_from_file(path)); |
| 165 |
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 13 not taken.
|
✗ |
if (parsed.document.has_value() == false) |
| 166 |
|
|
{ |
| 167 |
0/6
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 209 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 154 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 152 not taken.
|
✗ |
LOG_WARN("Failed to parse '{}': {}", path, parsed.error); |
| 168 |
|
✗ |
return; |
| 169 |
|
|
} |
| 170 |
|
|
|
| 171 |
|
✗ |
const auto& doc = *parsed.document; |
| 172 |
|
|
|
| 173 |
0/2
✗ Branch 141 → 16 not taken.
✗ Branch 141 → 142 not taken.
|
✗ |
for (const auto& node: doc) |
| 174 |
|
|
{ |
| 175 |
0/4
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 208 not taken.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 37 not taken.
|
✗ |
if (node.name == "mesh") |
| 176 |
|
|
{ |
| 177 |
0/4
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 167 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 167 not taken.
|
✗ |
const auto key = node.args[0].as_string(); |
| 178 |
0/4
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 165 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 165 not taken.
|
✗ |
const auto file = node.args[1].as_string(); |
| 179 |
|
|
|
| 180 |
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 163 not taken.
|
✗ |
const auto mesh = eu::io::mesh_from_file(file); |
| 181 |
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 161 not taken.
|
✗ |
auto compiled = eu::render::compile_mesh(USE_DEBUG_LABEL_MANY(file) mesh, layout); |
| 182 |
|
|
|
| 183 |
0/4
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 158 not taken.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 156 not taken.
|
✗ |
meshes[key] = std::make_unique<eu::render::CompiledMesh>(compiled); |
| 184 |
|
✗ |
} |
| 185 |
0/4
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 208 not taken.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 53 not taken.
|
✗ |
else if (node.name == "offset") |
| 186 |
|
|
{ |
| 187 |
0/4
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 168 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 168 not taken.
|
✗ |
const auto x = node.args[0].as_number().as<float>().value_or(0.0f); |
| 188 |
0/4
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 169 not taken.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 169 not taken.
|
✗ |
const auto y = node.args[1].as_number().as<float>().value_or(0.0f); |
| 189 |
0/4
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 170 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 170 not taken.
|
✗ |
const auto z = node.args[2].as_number().as<float>().value_or(0.0f); |
| 190 |
|
✗ |
offset = { x, y, z }; |
| 191 |
|
|
} |
| 192 |
0/4
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 208 not taken.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 69 not taken.
|
✗ |
else if (node.name == "cell_size") |
| 193 |
|
|
{ |
| 194 |
0/4
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 171 not taken.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 171 not taken.
|
✗ |
const auto x = node.args[0].as_number().as<float>().value_or(0.0f); |
| 195 |
0/4
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 172 not taken.
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 172 not taken.
|
✗ |
const auto y = node.args[1].as_number().as<float>().value_or(0.0f); |
| 196 |
0/4
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 173 not taken.
✗ Branch 65 → 66 not taken.
✗ Branch 65 → 173 not taken.
|
✗ |
const auto z = node.args[2].as_number().as<float>().value_or(0.0f); |
| 197 |
|
✗ |
size = {x, y, z}; |
| 198 |
|
|
} |
| 199 |
0/4
✗ Branch 69 → 70 not taken.
✗ Branch 69 → 208 not taken.
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 127 not taken.
|
✗ |
else if (node.name == "item") |
| 200 |
|
|
{ |
| 201 |
0/4
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 174 not taken.
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 174 not taken.
|
✗ |
const auto x = node.args[0].as_number().as<float>().value_or(0.0f); |
| 202 |
0/4
✗ Branch 76 → 77 not taken.
✗ Branch 76 → 175 not taken.
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 175 not taken.
|
✗ |
const auto y = node.args[1].as_number().as<float>().value_or(0.0f); |
| 203 |
0/4
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 176 not taken.
✗ Branch 81 → 82 not taken.
✗ Branch 81 → 176 not taken.
|
✗ |
const auto z = node.args[2].as_number().as<float>().value_or(0.0f); |
| 204 |
0/8
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 179 not taken.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 177 not taken.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 177 not taken.
✗ Branch 88 → 89 not taken.
✗ Branch 88 → 177 not taken.
|
✗ |
const auto rotation = node.properties.at("rot").as_number().as<int>().value_or(-1); |
| 205 |
|
✗ |
const v3 pos = { x*size.x, y*size.y, z*size.z }; |
| 206 |
0/8
✗ Branch 95 → 96 not taken.
✗ Branch 95 → 186 not taken.
✗ Branch 96 → 97 not taken.
✗ Branch 96 → 184 not taken.
✗ Branch 97 → 98 not taken.
✗ Branch 97 → 184 not taken.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 184 not taken.
|
✗ |
const auto item = node.properties.at("item").as_string(); |
| 207 |
0/2
✗ Branch 101 → 102 not taken.
✗ Branch 101 → 201 not taken.
|
✗ |
const auto found = meshes.find(item); |
| 208 |
0/2
✗ Branch 104 → 105 not taken.
✗ Branch 104 → 120 not taken.
|
✗ |
if (found != meshes.end()) |
| 209 |
|
|
{ |
| 210 |
0/2
✗ Branch 105 → 106 not taken.
✗ Branch 105 → 196 not taken.
|
✗ |
auto mesh_in_world = std::make_unique<render::MeshInWorld>(); |
| 211 |
0/2
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 194 not taken.
|
✗ |
const auto rotation_type = ypr_from_kdl_rotation(rotation); |
| 212 |
0/2
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 190 not taken.
|
✗ |
mesh_in_world->add_to_world(found->second.get(), world, material); |
| 213 |
0/4
✗ Branch 115 → 116 not taken.
✗ Branch 115 → 193 not taken.
✗ Branch 116 → 117 not taken.
✗ Branch 116 → 193 not taken.
|
✗ |
tiles.emplace_back(rotation_type, offset + pos, std::move(mesh_in_world)) |
| 214 |
0/2
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 193 not taken.
|
✗ |
.update(rotation_data); |
| 215 |
|
✗ |
} |
| 216 |
|
|
else |
| 217 |
|
|
{ |
| 218 |
0/6
✗ Branch 120 → 121 not taken.
✗ Branch 120 → 201 not taken.
✗ Branch 121 → 122 not taken.
✗ Branch 121 → 199 not taken.
✗ Branch 122 → 123 not taken.
✗ Branch 122 → 197 not taken.
|
✗ |
LOG_WARN("Mesh '{}' not found for item in level file", item); |
| 219 |
|
|
} |
| 220 |
|
✗ |
} |
| 221 |
|
|
else |
| 222 |
|
|
{ |
| 223 |
0/6
✗ Branch 127 → 128 not taken.
✗ Branch 127 → 208 not taken.
✗ Branch 128 → 129 not taken.
✗ Branch 128 → 206 not taken.
✗ Branch 129 → 130 not taken.
✗ Branch 129 → 204 not taken.
|
✗ |
LOG_WARN("Unknown node in level file: '{}'", node.name); |
| 224 |
|
|
} |
| 225 |
|
|
} |
| 226 |
0/2
✗ Branch 144 → 145 not taken.
✗ Branch 144 → 147 not taken.
|
✗ |
} |
| 227 |
|
|
}; |
| 228 |
|
|
|
| 229 |
|
|
|
| 230 |
|
|
|
| 231 |
|
|
struct Time |
| 232 |
|
|
{ |
| 233 |
|
|
Uint64 now = SDL_GetPerformanceCounter(); |
| 234 |
|
|
Uint64 last = 0; |
| 235 |
|
|
|
| 236 |
|
|
|
| 237 |
|
✗ |
float calculate() |
| 238 |
|
|
{ |
| 239 |
|
✗ |
last = now; |
| 240 |
|
✗ |
now = SDL_GetPerformanceCounter(); |
| 241 |
|
|
|
| 242 |
|
✗ |
const auto diff = static_cast<float>(now - last); |
| 243 |
|
✗ |
const auto pfc = static_cast<float>(SDL_GetPerformanceFrequency()); |
| 244 |
|
✗ |
return diff / pfc; |
| 245 |
|
|
} |
| 246 |
|
|
}; |
| 247 |
|
|
|
| 248 |
|
|
|
| 249 |
|
|
struct MeshSpatialComponent : runner::SpatialComponent |
| 250 |
|
|
{ |
| 251 |
|
|
render::MeshInWorld car; |
| 252 |
|
|
|
| 253 |
|
|
eu::v3 position = { 0.0f, -1.8f, -10.0f }; |
| 254 |
|
|
eu::Ypr rotation = { .yaw = 30.0_deg, .pitch = 30.0_deg, .roll = 30.0_deg }; |
| 255 |
|
|
|
| 256 |
|
✗ |
const char* display() override |
| 257 |
|
|
{ |
| 258 |
|
✗ |
return "MeshSpatialComponent"; |
| 259 |
|
|
} |
| 260 |
|
|
|
| 261 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 262 |
|
|
{ |
| 263 |
|
✗ |
runner::SpatialComponent::imgui(table); |
| 264 |
|
✗ |
table.drag("Position", &position); |
| 265 |
|
✗ |
table.drag("Rotation", &rotation); |
| 266 |
|
✗ |
} |
| 267 |
|
|
|
| 268 |
|
✗ |
void update_transform() |
| 269 |
|
|
{ |
| 270 |
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 7 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 7 not taken.
|
✗ |
set_transform(eu::render::transform_from_rotation(position, rotation)); |
| 271 |
|
✗ |
car.set_transform(get_transform()); |
| 272 |
|
✗ |
} |
| 273 |
|
|
|
| 274 |
|
✗ |
MeshSpatialComponent(render::CompiledMesh* mesh, render::World* render_world, std::shared_ptr<render::Material> material) |
| 275 |
|
✗ |
{ |
| 276 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
|
✗ |
car.add_to_world(mesh, render_world, std::move(material)); |
| 277 |
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 15 not taken.
|
✗ |
update_transform(); |
| 278 |
|
✗ |
} |
| 279 |
|
|
|
| 280 |
|
|
EU_DEC_COMPONENT_TYPE(); |
| 281 |
|
|
}; |
| 282 |
|
|
|
| 283 |
0/12
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 12 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 12 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 16 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 14 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
|
✗ |
EU_IMP_COMPONENT_TYPE(MeshSpatialComponent, runner::Component) |
| 284 |
|
|
|
| 285 |
|
|
|
| 286 |
|
|
struct InputSystem : runner::EntitySystem |
| 287 |
|
|
{ |
| 288 |
|
|
runner::Input* input; |
| 289 |
|
|
MeshSpatialComponent* mesh = nullptr; |
| 290 |
|
|
|
| 291 |
|
✗ |
const char* display() override |
| 292 |
|
|
{ |
| 293 |
|
✗ |
return "Input"; |
| 294 |
|
|
} |
| 295 |
|
|
|
| 296 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 297 |
|
|
{ |
| 298 |
|
✗ |
table.display("has mesh", mesh != nullptr); |
| 299 |
|
✗ |
} |
| 300 |
|
|
|
| 301 |
|
✗ |
explicit InputSystem(runner::Input* in) : input(in) |
| 302 |
|
|
{ |
| 303 |
|
✗ |
} |
| 304 |
|
|
|
| 305 |
|
✗ |
runner::UpdateStageAndPrio get_stage() override |
| 306 |
|
|
{ |
| 307 |
|
|
return |
| 308 |
|
|
{ |
| 309 |
|
|
.stage = runner::UpdateStage::before_physics, |
| 310 |
|
|
.prio = 100 |
| 311 |
|
✗ |
}; |
| 312 |
|
|
} |
| 313 |
|
|
|
| 314 |
|
✗ |
void on_root_changed(runner::SpatialComponent*) override |
| 315 |
|
|
{ |
| 316 |
|
✗ |
} |
| 317 |
|
|
|
| 318 |
|
✗ |
void add_component(runner::Component* component) override |
| 319 |
|
|
{ |
| 320 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
|
✗ |
if (MeshSpatialComponent* mc = runner::component_cast<MeshSpatialComponent>(component); mc) |
| 321 |
|
|
{ |
| 322 |
|
✗ |
mesh = mc; |
| 323 |
|
|
} |
| 324 |
|
✗ |
} |
| 325 |
|
|
|
| 326 |
|
✗ |
void update(float dt) override |
| 327 |
|
|
{ |
| 328 |
0/14
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 8 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 8 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 18 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 11 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 15 not taken.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
|
✗ |
if (mesh && input && input->get_current_frame().binds[0].current > 0.5f) |
| 329 |
|
|
{ |
| 330 |
0/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 22 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 22 not taken.
|
✗ |
mesh->position += kk::in * dt; |
| 331 |
|
|
} |
| 332 |
|
|
|
| 333 |
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 17 not taken.
|
✗ |
if (mesh) |
| 334 |
|
|
{ |
| 335 |
|
✗ |
mesh->update_transform(); |
| 336 |
|
|
} |
| 337 |
|
✗ |
} |
| 338 |
|
|
}; |
| 339 |
|
|
|
| 340 |
|
|
struct TargetComponent : runner::Component |
| 341 |
|
|
{ |
| 342 |
|
|
m4 target = m4_identity; |
| 343 |
|
|
|
| 344 |
|
✗ |
const char* display() override |
| 345 |
|
|
{ |
| 346 |
|
✗ |
return "target"; |
| 347 |
|
|
} |
| 348 |
|
|
|
| 349 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 350 |
|
|
{ |
| 351 |
|
✗ |
table.transform(target); |
| 352 |
|
✗ |
} |
| 353 |
|
|
|
| 354 |
|
|
EU_DEC_COMPONENT_TYPE(); |
| 355 |
|
|
}; |
| 356 |
0/12
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 12 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 12 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 16 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 14 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
|
✗ |
EU_IMP_COMPONENT_TYPE(TargetComponent, runner::Component) |
| 357 |
|
|
|
| 358 |
|
|
struct CameraSpatialComponent : runner::SpatialComponent |
| 359 |
|
|
{ |
| 360 |
|
✗ |
const char* display() override |
| 361 |
|
|
{ |
| 362 |
|
✗ |
return "camera spatial"; |
| 363 |
|
|
} |
| 364 |
|
|
|
| 365 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 366 |
|
|
{ |
| 367 |
|
✗ |
runner::SpatialComponent::imgui(table); |
| 368 |
|
✗ |
} |
| 369 |
|
|
// todo(Gustav): add extra camera settings... |
| 370 |
|
|
EU_DEC_COMPONENT_TYPE(); |
| 371 |
|
|
}; |
| 372 |
0/12
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 12 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 12 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 16 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 14 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
|
✗ |
EU_IMP_COMPONENT_TYPE(CameraSpatialComponent, runner::SpatialComponent); |
| 373 |
|
|
|
| 374 |
|
|
struct FollowCameraSystem : runner::EntitySystem |
| 375 |
|
|
{ |
| 376 |
|
✗ |
runner::UpdateStageAndPrio get_stage() override |
| 377 |
|
|
{ |
| 378 |
|
|
return |
| 379 |
|
|
{ |
| 380 |
|
|
.stage = runner::UpdateStage::after_physics, |
| 381 |
|
|
.prio = 100 |
| 382 |
|
✗ |
}; |
| 383 |
|
|
} |
| 384 |
|
|
|
| 385 |
|
|
TargetComponent* target = nullptr; |
| 386 |
|
|
CameraSpatialComponent* camera = nullptr; |
| 387 |
|
|
|
| 388 |
|
✗ |
const char* display() override |
| 389 |
|
|
{ |
| 390 |
|
✗ |
return "Follow camera"; |
| 391 |
|
|
} |
| 392 |
|
|
|
| 393 |
|
|
imgui::ImLog log; |
| 394 |
|
|
imgui::ImTweak tweak; |
| 395 |
|
|
Rui offset = {.right = 0, .up = 3, .in = -10}; |
| 396 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 397 |
|
|
{ |
| 398 |
|
✗ |
table.display("Target", target != nullptr); |
| 399 |
|
✗ |
table.display("camera", camera != nullptr); |
| 400 |
|
✗ |
table.gear("Offset", &offset); |
| 401 |
|
|
|
| 402 |
|
✗ |
tweak.draw(); |
| 403 |
|
✗ |
log.draw(); |
| 404 |
|
✗ |
} |
| 405 |
|
|
|
| 406 |
|
✗ |
void on_root_changed(runner::SpatialComponent*) override |
| 407 |
|
|
{ |
| 408 |
|
✗ |
} |
| 409 |
|
|
|
| 410 |
|
✗ |
void add_component(runner::Component* component) override |
| 411 |
|
|
{ |
| 412 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 9 not taken.
|
✗ |
if (auto* tar = runner::component_cast<TargetComponent>(component)) |
| 413 |
|
|
{ |
| 414 |
|
✗ |
target = tar; |
| 415 |
0/4
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 19 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 17 not taken.
|
✗ |
LOG_INFO("Follow camera found target"); |
| 416 |
|
|
} |
| 417 |
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 16 not taken.
|
✗ |
else if (auto* cam = runner::component_cast<CameraSpatialComponent>(component)) |
| 418 |
|
|
{ |
| 419 |
|
✗ |
camera = cam; |
| 420 |
0/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 23 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 21 not taken.
|
✗ |
LOG_INFO("Follow camera found camera"); |
| 421 |
|
|
} |
| 422 |
|
✗ |
} |
| 423 |
|
✗ |
void update(float) override |
| 424 |
|
|
{ |
| 425 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 38 not taken.
|
✗ |
log.begin(); |
| 426 |
|
|
|
| 427 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
|
✗ |
if (!target) { return; } |
| 428 |
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
|
✗ |
if (!camera) { return; } |
| 429 |
|
|
|
| 430 |
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 38 not taken.
|
✗ |
const auto tr = transform_from_matrix(target->target); |
| 431 |
|
|
|
| 432 |
|
✗ |
const auto focus = tr.position; |
| 433 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 38 not taken.
|
✗ |
const auto o_rot = Ypr::from(tr.rotation); |
| 434 |
0/6
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 29 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 29 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 29 not taken.
|
✗ |
const auto pos_from_focus = m4::from(Q::from(Ypr{.yaw = o_rot.yaw})).get_transformed(offset); |
| 435 |
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 38 not taken.
|
✗ |
const auto pos = focus + pos_from_focus; |
| 436 |
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 38 not taken.
|
✗ |
const auto look_at = Q::look_at(pos, focus, kk::up); |
| 437 |
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 17 not taken.
|
✗ |
if (!look_at) |
| 438 |
|
|
{ |
| 439 |
|
✗ |
return; |
| 440 |
|
|
} |
| 441 |
0/4
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 34 not taken.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 32 not taken.
|
✗ |
log.add(fmt::format("updated rotation: {}", *look_at)); |
| 442 |
|
|
|
| 443 |
0/6
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 37 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 36 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 36 not taken.
|
✗ |
const auto mat = m4::from_translation(pos) * m4::from(*look_at); |
| 444 |
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 38 not taken.
|
✗ |
camera->set_transform(mat); |
| 445 |
|
|
} |
| 446 |
|
|
}; |
| 447 |
|
|
|
| 448 |
|
|
namespace tag |
| 449 |
|
|
{ |
| 450 |
|
|
constexpr Hsh CameraSpatialSource = "camera_spatial_src_tag"sv; |
| 451 |
|
|
constexpr Hsh CameraDestination = "camera_dst_tag"sv; |
| 452 |
|
|
} |
| 453 |
|
|
|
| 454 |
|
|
struct UpdateCameraTarget : runner::WorldSystem |
| 455 |
|
|
{ |
| 456 |
|
|
runner::SpatialComponent* src_entity = nullptr; |
| 457 |
|
|
TargetComponent* dst_entity = nullptr; |
| 458 |
|
|
|
| 459 |
|
✗ |
const char* display() override |
| 460 |
|
|
{ |
| 461 |
|
✗ |
return "Update camera target"; |
| 462 |
|
|
} |
| 463 |
|
|
|
| 464 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 465 |
|
|
{ |
| 466 |
|
✗ |
table.display("src entity", src_entity != nullptr); |
| 467 |
|
✗ |
table.display("dst entity", dst_entity != nullptr); |
| 468 |
|
✗ |
} |
| 469 |
|
|
|
| 470 |
|
✗ |
runner::UpdateStageAndPrio get_stage() override |
| 471 |
|
|
{ |
| 472 |
|
|
return { |
| 473 |
|
|
.stage = runner::UpdateStage::after_physics, |
| 474 |
|
|
.prio = 100 |
| 475 |
|
✗ |
}; |
| 476 |
|
|
} |
| 477 |
|
|
|
| 478 |
|
✗ |
void on_root_changed(runner::Entity* entity, runner::SpatialComponent* component) override |
| 479 |
|
|
{ |
| 480 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 9 not taken.
|
✗ |
if (entity->has_tag(tag::CameraSpatialSource)) |
| 481 |
|
|
{ |
| 482 |
0/4
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 12 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 10 not taken.
|
✗ |
LOG_INFO("Found spatial source"); |
| 483 |
|
✗ |
src_entity = component; |
| 484 |
|
|
} |
| 485 |
|
✗ |
} |
| 486 |
|
|
|
| 487 |
|
✗ |
void add_component(runner::Entity* entity, runner::Component* component) override |
| 488 |
|
|
{ |
| 489 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 11 not taken.
|
✗ |
if (entity->has_tag(tag::CameraDestination)) |
| 490 |
|
|
{ |
| 491 |
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
|
✗ |
if (auto* target = runner::component_cast<TargetComponent>(component)) |
| 492 |
|
|
{ |
| 493 |
0/4
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 14 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
|
✗ |
LOG_INFO("Found camera destination on {}", entity->name); |
| 494 |
|
✗ |
dst_entity = target; |
| 495 |
|
|
} |
| 496 |
|
|
} |
| 497 |
|
✗ |
} |
| 498 |
|
|
|
| 499 |
|
✗ |
void update(float) override |
| 500 |
|
|
{ |
| 501 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
|
✗ |
if (!src_entity) { return; } |
| 502 |
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
|
✗ |
if (!dst_entity) { return; } |
| 503 |
|
|
|
| 504 |
|
✗ |
dst_entity->target = src_entity->get_transform(); |
| 505 |
|
|
} |
| 506 |
|
|
}; |
| 507 |
|
|
|
| 508 |
|
|
struct CameraFetcherSystem : runner::WorldSystem |
| 509 |
|
|
{ |
| 510 |
|
✗ |
runner::UpdateStageAndPrio get_stage() override |
| 511 |
|
|
{ |
| 512 |
|
|
return { |
| 513 |
|
|
.stage = runner::UpdateStage::before_render, |
| 514 |
|
|
.prio = 100 |
| 515 |
|
✗ |
}; |
| 516 |
|
|
} |
| 517 |
|
|
|
| 518 |
|
|
CameraSpatialComponent* camera = nullptr; |
| 519 |
|
|
m4 transform = m4_identity; |
| 520 |
|
|
|
| 521 |
|
✗ |
const char* display() override |
| 522 |
|
|
{ |
| 523 |
|
✗ |
return "Camera fetcher"; |
| 524 |
|
|
} |
| 525 |
|
|
|
| 526 |
|
✗ |
void imgui(const imgui::PropTable& table) override |
| 527 |
|
|
{ |
| 528 |
|
✗ |
table.display("camera", camera != nullptr); |
| 529 |
|
✗ |
table.transform(transform); |
| 530 |
|
✗ |
} |
| 531 |
|
|
|
| 532 |
|
✗ |
void add_component(runner::Entity*, runner::Component* component) override |
| 533 |
|
|
{ |
| 534 |
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 9 not taken.
|
✗ |
if (auto cam = runner::component_cast<CameraSpatialComponent>(component)) |
| 535 |
|
|
{ |
| 536 |
0/4
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 12 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 10 not taken.
|
✗ |
LOG_INFO("Fetcher found camera"); |
| 537 |
|
✗ |
camera = cam; |
| 538 |
|
|
} |
| 539 |
|
✗ |
} |
| 540 |
|
|
|
| 541 |
|
✗ |
void on_root_changed(runner::Entity*, runner::SpatialComponent*) override |
| 542 |
|
|
{ |
| 543 |
|
✗ |
} |
| 544 |
|
|
|
| 545 |
|
✗ |
void update(float) override |
| 546 |
|
|
{ |
| 547 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
|
✗ |
if (!camera) return; |
| 548 |
|
✗ |
transform = camera->get_transform(); |
| 549 |
|
|
} |
| 550 |
|
|
|
| 551 |
|
✗ |
render::Camera fetch() const |
| 552 |
|
|
{ |
| 553 |
|
✗ |
render::Camera r; |
| 554 |
|
✗ |
r.world_from_view = transform; |
| 555 |
|
✗ |
return r; |
| 556 |
|
|
} |
| 557 |
|
|
}; |
| 558 |
|
|
|
| 559 |
|
✗ |
int main(int, char**) |
| 560 |
|
|
{ |
| 561 |
|
✗ |
const char* glsl_version = "#version 130"; |
| 562 |
|
|
|
| 563 |
|
|
// todo(Gustav): set app metadata |
| 564 |
|
|
|
| 565 |
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 816 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 10 not taken.
|
✗ |
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == false) |
| 566 |
|
|
{ |
| 567 |
0/8
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 816 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 475 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 474 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 472 not taken.
|
✗ |
LOG_ERR("Error initializing SDL: {}", SDL_GetError()); |
| 568 |
|
✗ |
return -1; |
| 569 |
|
|
} |
| 570 |
|
|
|
| 571 |
|
|
{ |
| 572 |
|
✗ |
const auto str = [](int version) |
| 573 |
|
|
{ |
| 574 |
|
✗ |
const auto major = SDL_VERSIONNUM_MAJOR(version); |
| 575 |
|
✗ |
const auto minor = SDL_VERSIONNUM_MINOR(version); |
| 576 |
|
✗ |
const auto micro = SDL_VERSIONNUM_MICRO(version); |
| 577 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 5 not taken.
|
✗ |
return fmt::format("{0}.{1}.{2}", major, minor, micro); |
| 578 |
|
|
}; |
| 579 |
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 487 not taken.
|
✗ |
const int version_loaded = SDL_GetVersion(); |
| 580 |
0/10
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 487 not taken.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 485 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 482 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 479 not taken.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 477 not taken.
|
✗ |
LOG_INFO("SDL {0} initialized with {1}", str(SDL_VERSION), str(version_loaded)); |
| 581 |
|
|
} |
| 582 |
|
|
|
| 583 |
|
|
// todo(Gustav): move to some shared sdl lib instead? as this shouldn't use dear imgui and 100% rely on sdl |
| 584 |
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 816 not taken.
|
✗ |
const auto app_scale = eu::imgui::calculate_app_scale(); |
| 585 |
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 816 not taken.
|
✗ |
auto [window_width, window_height] = eu::imgui::rescale_window(1280, 720, app_scale); |
| 586 |
|
|
|
| 587 |
|
|
#if defined(__APPLE__) |
| 588 |
|
|
// GL 3.2 Core + GLSL 150 |
| 589 |
|
|
const char* glsl_version = "#version 150"; |
| 590 |
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac |
| 591 |
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); |
| 592 |
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
| 593 |
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); |
| 594 |
|
|
#else |
| 595 |
|
|
// GL 3.0 + GLSL 130 |
| 596 |
|
|
// const char* glsl_version = "#version 130"; |
| 597 |
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); |
| 598 |
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); |
| 599 |
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); |
| 600 |
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); // was 0 in dear imgui example?? |
| 601 |
|
|
#endif |
| 602 |
|
|
|
| 603 |
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); |
| 604 |
0/2
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); |
| 605 |
|
|
|
| 606 |
0/2
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
| 607 |
0/2
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); |
| 608 |
|
|
|
| 609 |
0/2
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); |
| 610 |
0/2
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); |
| 611 |
0/2
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); |
| 612 |
0/2
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 816 not taken.
|
✗ |
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); |
| 613 |
|
|
|
| 614 |
0/2
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 816 not taken.
|
✗ |
SDL_Window* window = SDL_CreateWindow("Runner", |
| 615 |
|
|
window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE); |
| 616 |
0/2
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 43 not taken.
|
✗ |
if (!window) { |
| 617 |
0/8
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 816 not taken.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 491 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 490 not taken.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 488 not taken.
|
✗ |
LOG_ERR("Error creating window: {}", SDL_GetError()); |
| 618 |
|
✗ |
return -1; |
| 619 |
|
|
} |
| 620 |
|
|
|
| 621 |
0/2
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 816 not taken.
|
✗ |
auto* glContext = SDL_GL_CreateContext(window); |
| 622 |
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 816 not taken.
|
✗ |
SDL_GetWindowSize(window, &window_width, &window_height); |
| 623 |
0/2
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 52 not taken.
|
✗ |
if (!glContext) { |
| 624 |
0/8
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 816 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 496 not taken.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 495 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 493 not taken.
|
✗ |
LOG_ERR("Error creating gl context: {}", SDL_GetError()); |
| 625 |
|
✗ |
return -1; |
| 626 |
|
|
} |
| 627 |
|
|
|
| 628 |
|
|
/* OpenGL setup */ |
| 629 |
0/2
✗ Branch 52 → 53 not taken.
✗ Branch 52 → 816 not taken.
|
✗ |
const int glad_result = gladLoadGLLoader(SDL_GL_GetProcAddress); |
| 630 |
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 59 not taken.
|
✗ |
if (glad_result == 0) |
| 631 |
|
|
{ |
| 632 |
0/6
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 816 not taken.
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 500 not taken.
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 498 not taken.
|
✗ |
LOG_ERR("Failed to init glad, error: {0}", glad_result); |
| 633 |
|
✗ |
return -1; |
| 634 |
|
|
} |
| 635 |
|
|
|
| 636 |
|
|
{ |
| 637 |
0/2
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 91 not taken.
|
✗ |
if (GLAD_GL_VERSION_1_0) { |
| 638 |
0/4
✗ Branch 62 → 63 not taken.
✗ Branch 62 → 502 not taken.
✗ Branch 63 → 64 not taken.
✗ Branch 63 → 502 not taken.
|
✗ |
const std::string gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); |
| 639 |
0/4
✗ Branch 67 → 68 not taken.
✗ Branch 67 → 505 not taken.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 505 not taken.
|
✗ |
const std::string gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); |
| 640 |
0/4
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 508 not taken.
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 508 not taken.
|
✗ |
const std::string gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); |
| 641 |
0/6
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 523 not taken.
✗ Branch 76 → 77 not taken.
✗ Branch 76 → 513 not taken.
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 511 not taken.
|
✗ |
LOG_INFO("OpenGL Vendor: {0}", gl_vendor); |
| 642 |
0/6
✗ Branch 79 → 80 not taken.
✗ Branch 79 → 523 not taken.
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 517 not taken.
✗ Branch 81 → 82 not taken.
✗ Branch 81 → 515 not taken.
|
✗ |
LOG_INFO("OpenGL Renderer: {0}", gl_renderer); |
| 643 |
0/6
✗ Branch 83 → 84 not taken.
✗ Branch 83 → 523 not taken.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 521 not taken.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 519 not taken.
|
✗ |
LOG_INFO("OpenGL Version: {0}", gl_version); |
| 644 |
|
✗ |
} |
| 645 |
|
|
|
| 646 |
0/2
✗ Branch 91 → 92 not taken.
✗ Branch 91 → 103 not taken.
|
✗ |
if (GLAD_GL_VERSION_2_0) { |
| 647 |
0/4
✗ Branch 94 → 95 not taken.
✗ Branch 94 → 530 not taken.
✗ Branch 95 → 96 not taken.
✗ Branch 95 → 530 not taken.
|
✗ |
const std::string gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)); |
| 648 |
0/6
✗ Branch 97 → 98 not taken.
✗ Branch 97 → 537 not taken.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 535 not taken.
✗ Branch 99 → 100 not taken.
✗ Branch 99 → 533 not taken.
|
✗ |
LOG_INFO("Version GLSL: {0}", gl_shading_language_version); |
| 649 |
|
✗ |
} |
| 650 |
|
|
} |
| 651 |
|
|
|
| 652 |
0/2
✗ Branch 103 → 104 not taken.
✗ Branch 103 → 109 not taken.
|
✗ |
if (!GLAD_GL_VERSION_4_3) |
| 653 |
|
|
{ |
| 654 |
0/6
✗ Branch 104 → 105 not taken.
✗ Branch 104 → 816 not taken.
✗ Branch 105 → 106 not taken.
✗ Branch 105 → 542 not taken.
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 540 not taken.
|
✗ |
LOG_ERR("OpenGL 4.3 not supported ({0}.{1} detected), aborting...", GLVersion.major, GLVersion.minor); |
| 655 |
|
✗ |
return -1; |
| 656 |
|
|
} |
| 657 |
|
|
|
| 658 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 659 |
0/2
✗ Branch 109 → 110 not taken.
✗ Branch 109 → 816 not taken.
|
✗ |
IMGUI_CHECKVERSION(); |
| 660 |
0/2
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 816 not taken.
|
✗ |
ImGui::CreateContext(); |
| 661 |
0/2
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 816 not taken.
|
✗ |
ImGuiIO& io = ImGui::GetIO(); (void)io; |
| 662 |
0/2
✗ Branch 112 → 113 not taken.
✗ Branch 112 → 816 not taken.
|
✗ |
ImGui::StyleColorsDark(); |
| 663 |
0/2
✗ Branch 113 → 114 not taken.
✗ Branch 113 → 816 not taken.
|
✗ |
imgui::setup_colors(); |
| 664 |
0/4
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 816 not taken.
✗ Branch 115 → 116 not taken.
✗ Branch 115 → 121 not taken.
|
✗ |
if (false == ImGui_ImplSDL3_InitForOpenGL(window, glContext)) |
| 665 |
|
|
{ |
| 666 |
0/6
✗ Branch 116 → 117 not taken.
✗ Branch 116 → 816 not taken.
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 546 not taken.
✗ Branch 118 → 119 not taken.
✗ Branch 118 → 544 not taken.
|
✗ |
LOG_ERR("Failed to init ImGui SDL3 backend"); |
| 667 |
|
✗ |
return -1; |
| 668 |
|
|
} |
| 669 |
0/4
✗ Branch 121 → 122 not taken.
✗ Branch 121 → 816 not taken.
✗ Branch 122 → 123 not taken.
✗ Branch 122 → 128 not taken.
|
✗ |
if (false == ImGui_ImplOpenGL3_Init(glsl_version)) |
| 670 |
|
|
{ |
| 671 |
0/6
✗ Branch 123 → 124 not taken.
✗ Branch 123 → 816 not taken.
✗ Branch 124 → 125 not taken.
✗ Branch 124 → 550 not taken.
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 548 not taken.
|
✗ |
LOG_ERR("Failed to init ImGui OpenGL3 backend"); |
| 672 |
|
✗ |
return -1; |
| 673 |
|
|
} |
| 674 |
|
|
|
| 675 |
0/2
✗ Branch 128 → 129 not taken.
✗ Branch 128 → 816 not taken.
|
✗ |
eu::imgui::setup_scale(app_scale); |
| 676 |
|
|
|
| 677 |
|
✗ |
bool show_demo_window = true; |
| 678 |
|
|
#endif |
| 679 |
|
|
|
| 680 |
|
✗ |
eu::render::State states; |
| 681 |
0/2
✗ Branch 129 → 130 not taken.
✗ Branch 129 → 816 not taken.
|
✗ |
eu::render::Render2 render{ &states }; |
| 682 |
|
|
|
| 683 |
0/2
✗ Branch 130 → 131 not taken.
✗ Branch 130 → 814 not taken.
|
✗ |
eu::render::Assets assets; |
| 684 |
|
|
|
| 685 |
0/4
✗ Branch 134 → 135 not taken.
✗ Branch 134 → 554 not taken.
✗ Branch 135 → 136 not taken.
✗ Branch 135 → 552 not taken.
|
✗ |
assets.black = create_texture(SEND_DEBUG_LABEL_MANY("black") eu::core::color_from_rgba(0, 0, 0, 255), eu::render::ColorData::dont_care); |
| 686 |
0/4
✗ Branch 143 → 144 not taken.
✗ Branch 143 → 561 not taken.
✗ Branch 144 → 145 not taken.
✗ Branch 144 → 559 not taken.
|
✗ |
assets.white = create_texture(SEND_DEBUG_LABEL_MANY("white") eu::core::color_from_rgba(255, 255, 255, 255), eu::render::ColorData::dont_care); |
| 687 |
|
|
|
| 688 |
0/4
✗ Branch 151 → 152 not taken.
✗ Branch 151 → 568 not taken.
✗ Branch 152 → 153 not taken.
✗ Branch 152 → 566 not taken.
|
✗ |
assets.default_shader_source = load_shader("default_shader"); |
| 689 |
0/4
✗ Branch 159 → 160 not taken.
✗ Branch 159 → 575 not taken.
✗ Branch 160 → 161 not taken.
✗ Branch 160 → 573 not taken.
|
✗ |
assets.skybox_shader_source = load_shader("skybox"); |
| 690 |
|
|
|
| 691 |
0/4
✗ Branch 167 → 168 not taken.
✗ Branch 167 → 582 not taken.
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 580 not taken.
|
✗ |
assets.pp_vert_glsl = eu::io::string_from_file("pp_vert.glsl"); |
| 692 |
0/4
✗ Branch 175 → 176 not taken.
✗ Branch 175 → 589 not taken.
✗ Branch 176 → 177 not taken.
✗ Branch 176 → 587 not taken.
|
✗ |
assets.pp_realize_frag_glsl = eu::io::string_from_file("pp_realize.frag.glsl"); |
| 693 |
0/4
✗ Branch 183 → 184 not taken.
✗ Branch 183 → 596 not taken.
✗ Branch 184 → 185 not taken.
✗ Branch 184 → 594 not taken.
|
✗ |
assets.pp_extract_frag_glsl = eu::io::string_from_file("pp_extract.frag.glsl"); |
| 694 |
0/4
✗ Branch 191 → 192 not taken.
✗ Branch 191 → 603 not taken.
✗ Branch 192 → 193 not taken.
✗ Branch 192 → 601 not taken.
|
✗ |
assets.pp_ping_pong_blur_frag_glsl = eu::io::string_from_file("pp_ping_pong_blur.frag.glsl"); |
| 695 |
|
|
|
| 696 |
0/2
✗ Branch 197 → 198 not taken.
✗ Branch 197 → 608 not taken.
|
✗ |
eu::render::Renderer renderer{ &states, &assets, eu::render::RenderSettings{} }; |
| 697 |
0/4
✗ Branch 198 → 199 not taken.
✗ Branch 198 → 810 not taken.
✗ Branch 199 → 200 not taken.
✗ Branch 199 → 201 not taken.
|
✗ |
if (renderer.is_loaded() == false) |
| 698 |
|
|
{ |
| 699 |
|
✗ |
return -1; |
| 700 |
|
|
} |
| 701 |
|
|
|
| 702 |
|
✗ |
eu::runner::Input input; |
| 703 |
0/6
✗ Branch 204 → 205 not taken.
✗ Branch 204 → 611 not taken.
✗ Branch 205 → 206 not taken.
✗ Branch 205 → 609 not taken.
✗ Branch 208 → 209 not taken.
✗ Branch 208 → 210 not taken.
|
✗ |
if (false == input.load_from_file("input.kdl")) |
| 704 |
|
|
{ |
| 705 |
|
✗ |
return -1; |
| 706 |
|
|
} |
| 707 |
|
|
|
| 708 |
0/2
✗ Branch 210 → 211 not taken.
✗ Branch 210 → 808 not taken.
|
✗ |
eu::runner::Script script; |
| 709 |
0/6
✗ Branch 213 → 214 not taken.
✗ Branch 213 → 617 not taken.
✗ Branch 214 → 215 not taken.
✗ Branch 214 → 615 not taken.
✗ Branch 217 → 218 not taken.
✗ Branch 217 → 219 not taken.
|
✗ |
if (false == script.run_file("main.lax")) |
| 710 |
|
|
{ |
| 711 |
|
✗ |
return -1; |
| 712 |
|
|
} |
| 713 |
|
|
|
| 714 |
|
✗ |
eu::render::World render_world; |
| 715 |
|
✗ |
eu::render::EffectStack effects; |
| 716 |
|
|
|
| 717 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 718 |
0/2
✗ Branch 219 → 220 not taken.
✗ Branch 219 → 802 not taken.
|
✗ |
imgui::ImguiShaderCache imgui_shader_cache; |
| 719 |
|
|
#endif |
| 720 |
|
|
|
| 721 |
|
|
// add demo world |
| 722 |
|
|
{ |
| 723 |
|
✗ |
constexpr auto PLANE_SIZE = 100.0f; |
| 724 |
|
|
auto plane_geom = eu::render::compile_geom( |
| 725 |
0/2
✗ Branch 225 → 226 not taken.
✗ Branch 225 → 623 not taken.
|
✗ |
USE_DEBUG_LABEL_MANY("plane") |
| 726 |
0/4
✗ Branch 221 → 222 not taken.
✗ Branch 221 → 631 not taken.
✗ Branch 222 → 223 not taken.
✗ Branch 222 → 629 not taken.
|
✗ |
eu::core::geom::create_xz_plane(PLANE_SIZE, PLANE_SIZE, false).to_geom(), |
| 727 |
0/2
✗ Branch 220 → 221 not taken.
✗ Branch 220 → 635 not taken.
|
✗ |
renderer.default_geom_layout() |
| 728 |
0/2
✗ Branch 226 → 227 not taken.
✗ Branch 226 → 621 not taken.
|
✗ |
); |
| 729 |
|
|
|
| 730 |
0/2
✗ Branch 232 → 233 not taken.
✗ Branch 232 → 654 not taken.
|
✗ |
auto material = renderer.make_default_material(); |
| 731 |
0/4
✗ Branch 235 → 236 not taken.
✗ Branch 235 → 638 not taken.
✗ Branch 236 → 237 not taken.
✗ Branch 236 → 636 not taken.
|
✗ |
material->diffuse = load_texture("sprites/smoke.png", eu::render::ColorData::dont_care); |
| 732 |
|
✗ |
material->specular = assets.white; |
| 733 |
|
|
|
| 734 |
0/2
✗ Branch 246 → 247 not taken.
✗ Branch 246 → 643 not taken.
|
✗ |
auto plane = make_mesh_instance(plane_geom, material); |
| 735 |
0/2
✗ Branch 249 → 250 not taken.
✗ Branch 249 → 650 not taken.
|
✗ |
render_world.meshes.emplace_back(plane); |
| 736 |
0/2
✗ Branch 251 → 252 not taken.
✗ Branch 251 → 649 not taken.
|
✗ |
plane->transform = eu::m4::from_translation({ 0.0f, -3.0f, 0.0f }); |
| 737 |
|
|
|
| 738 |
0/2
✗ Branch 253 → 254 not taken.
✗ Branch 253 → 650 not taken.
|
✗ |
render_world.lights.point_lights.emplace_back(); |
| 739 |
|
✗ |
} |
| 740 |
|
|
|
| 741 |
|
|
// add demo mesh |
| 742 |
|
✗ |
eu::runner::World runner_world; |
| 743 |
|
✗ |
std::unordered_map<std::string, std::unique_ptr<render::CompiledMesh>> meshes; |
| 744 |
|
✗ |
std::unordered_map<std::string, std::shared_ptr<eu::render::Texture2d>> textures; |
| 745 |
|
|
|
| 746 |
|
✗ |
const auto load_mesh = [&](const std::string& f) -> render::CompiledMesh* |
| 747 |
|
|
{ |
| 748 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 31 not taken.
|
✗ |
const auto found = meshes.find(f); |
| 749 |
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 8 not taken.
|
✗ |
if (found != meshes.end()) |
| 750 |
|
|
{ |
| 751 |
|
✗ |
return found->second.get(); |
| 752 |
|
|
} |
| 753 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 31 not taken.
|
✗ |
const auto mesh = eu::io::mesh_from_file(f); |
| 754 |
0/4
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 24 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 22 not taken.
|
✗ |
const auto compiled = eu::render::compile_mesh(USE_DEBUG_LABEL_MANY(f) mesh, renderer.default_geom_layout()); |
| 755 |
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 27 not taken.
|
✗ |
auto data = std::make_unique<render::CompiledMesh>(compiled); |
| 756 |
|
✗ |
auto* ret = data.get(); |
| 757 |
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 25 not taken.
|
✗ |
meshes.insert_or_assign(f, std::move(data)); |
| 758 |
|
✗ |
return ret; |
| 759 |
|
✗ |
}; |
| 760 |
|
|
|
| 761 |
|
✗ |
const auto load_color_texture = [&](const std::string& f) -> std::shared_ptr<render::Texture2d> |
| 762 |
|
|
{ |
| 763 |
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 16 not taken.
|
✗ |
const auto found = textures.find(f); |
| 764 |
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 8 not taken.
|
✗ |
if (found != textures.end()) |
| 765 |
|
|
{ |
| 766 |
|
✗ |
return found->second; |
| 767 |
|
|
} |
| 768 |
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 16 not taken.
|
✗ |
const auto loaded = load_texture(f, eu::render::ColorData::color_data); |
| 769 |
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 14 not taken.
|
✗ |
textures.insert_or_assign(f, loaded); |
| 770 |
|
✗ |
return loaded; |
| 771 |
|
✗ |
}; |
| 772 |
|
|
|
| 773 |
0/4
✗ Branch 259 → 260 not taken.
✗ Branch 259 → 661 not taken.
✗ Branch 261 → 262 not taken.
✗ Branch 261 → 657 not taken.
|
✗ |
runner_world.add_system(std::make_unique<UpdateCameraTarget>()); |
| 774 |
|
|
|
| 775 |
|
|
CameraFetcherSystem* camera_fetcher; |
| 776 |
|
|
{ |
| 777 |
0/2
✗ Branch 264 → 265 not taken.
✗ Branch 264 → 668 not taken.
|
✗ |
auto fetch = std::make_unique<CameraFetcherSystem>(); |
| 778 |
|
✗ |
camera_fetcher = fetch.get(); |
| 779 |
0/2
✗ Branch 269 → 270 not taken.
✗ Branch 269 → 663 not taken.
|
✗ |
runner_world.add_system(std::move(fetch)); |
| 780 |
|
✗ |
} |
| 781 |
|
|
|
| 782 |
|
|
{ |
| 783 |
0/6
✗ Branch 274 → 275 not taken.
✗ Branch 274 → 677 not taken.
✗ Branch 277 → 278 not taken.
✗ Branch 277 → 671 not taken.
✗ Branch 278 → 279 not taken.
✗ Branch 278 → 669 not taken.
|
✗ |
auto* car = runner_world.add_entity("car", { tag::CameraSpatialSource }); |
| 784 |
|
|
|
| 785 |
|
|
// mesh component |
| 786 |
|
|
// debug/axis.glb |
| 787 |
|
|
// "models/vehicle-truck-purple.glb" |
| 788 |
|
|
// "models/textures/colormap.png" |
| 789 |
|
|
// render::CompiledMesh* mesh, render::World* render_world, std::shared_ptr<render::Material> material |
| 790 |
0/4
✗ Branch 285 → 286 not taken.
✗ Branch 285 → 684 not taken.
✗ Branch 286 → 287 not taken.
✗ Branch 286 → 682 not taken.
|
✗ |
auto* mesh = load_mesh("models/vehicle-truck-purple.glb"); |
| 791 |
0/2
✗ Branch 289 → 290 not taken.
✗ Branch 289 → 710 not taken.
|
✗ |
auto material = renderer.make_default_material(); |
| 792 |
0/4
✗ Branch 292 → 293 not taken.
✗ Branch 292 → 690 not taken.
✗ Branch 293 → 294 not taken.
✗ Branch 293 → 688 not taken.
|
✗ |
material->diffuse = load_color_texture("models/textures/colormap.png"); |
| 793 |
|
✗ |
material->specular = assets.white; |
| 794 |
0/2
✗ Branch 301 → 302 not taken.
✗ Branch 301 → 695 not taken.
|
✗ |
auto comp = std::make_unique<MeshSpatialComponent>(mesh, &render_world, material); |
| 795 |
0/2
✗ Branch 303 → 304 not taken.
✗ Branch 303 → 706 not taken.
|
✗ |
car->set_root(comp.get()); |
| 796 |
0/2
✗ Branch 307 → 308 not taken.
✗ Branch 307 → 696 not taken.
|
✗ |
car->add_component(std::move(comp)); |
| 797 |
|
|
|
| 798 |
|
|
// input component |
| 799 |
0/4
✗ Branch 309 → 310 not taken.
✗ Branch 309 → 703 not taken.
✗ Branch 311 → 312 not taken.
✗ Branch 311 → 699 not taken.
|
✗ |
car->add_system(std::make_unique<InputSystem>(&input)); |
| 800 |
|
✗ |
} |
| 801 |
|
|
{ |
| 802 |
0/6
✗ Branch 318 → 319 not taken.
✗ Branch 318 → 719 not taken.
✗ Branch 321 → 322 not taken.
✗ Branch 321 → 713 not taken.
✗ Branch 322 → 323 not taken.
✗ Branch 322 → 711 not taken.
|
✗ |
auto* cam = runner_world.add_entity("camera", { tag::CameraDestination }); |
| 803 |
|
|
|
| 804 |
0/4
✗ Branch 327 → 328 not taken.
✗ Branch 327 → 728 not taken.
✗ Branch 329 → 330 not taken.
✗ Branch 329 → 724 not taken.
|
✗ |
cam->add_component(std::make_unique<TargetComponent>()); |
| 805 |
0/2
✗ Branch 332 → 333 not taken.
✗ Branch 332 → 741 not taken.
|
✗ |
auto spat = std::make_unique<CameraSpatialComponent>(); |
| 806 |
0/2
✗ Branch 334 → 335 not taken.
✗ Branch 334 → 739 not taken.
|
✗ |
cam->set_root(spat.get()); |
| 807 |
0/2
✗ Branch 338 → 339 not taken.
✗ Branch 338 → 730 not taken.
|
✗ |
cam->add_component(std::move(spat)); |
| 808 |
0/4
✗ Branch 340 → 341 not taken.
✗ Branch 340 → 737 not taken.
✗ Branch 342 → 343 not taken.
✗ Branch 342 → 733 not taken.
|
✗ |
cam->add_system(std::make_unique<FollowCameraSystem>()); |
| 809 |
|
✗ |
} |
| 810 |
|
|
|
| 811 |
0/2
✗ Branch 346 → 347 not taken.
✗ Branch 346 → 794 not taken.
|
✗ |
Level level; |
| 812 |
|
|
{ |
| 813 |
0/2
✗ Branch 347 → 348 not taken.
✗ Branch 347 → 763 not taken.
|
✗ |
auto material = renderer.make_default_material(); |
| 814 |
0/4
✗ Branch 350 → 351 not taken.
✗ Branch 350 → 744 not taken.
✗ Branch 351 → 352 not taken.
✗ Branch 351 → 742 not taken.
|
✗ |
material->diffuse = load_color_texture("models/textures/colormap.png"); |
| 815 |
|
✗ |
material->specular = assets.white; |
| 816 |
0/6
✗ Branch 359 → 360 not taken.
✗ Branch 359 → 760 not taken.
✗ Branch 363 → 364 not taken.
✗ Branch 363 → 751 not taken.
✗ Branch 364 → 365 not taken.
✗ Branch 364 → 749 not taken.
|
✗ |
level.load("level.kdl", &render_world, material, renderer.default_geom_layout()); |
| 817 |
|
✗ |
} |
| 818 |
|
|
|
| 819 |
0/6
✗ Branch 370 → 371 not taken.
✗ Branch 370 → 792 not taken.
✗ Branch 371 → 372 not taken.
✗ Branch 371 → 766 not taken.
✗ Branch 372 → 373 not taken.
✗ Branch 372 → 764 not taken.
|
✗ |
LOG_INFO("Runner started"); |
| 820 |
|
✗ |
bool running = true; |
| 821 |
0/2
✗ Branch 374 → 375 not taken.
✗ Branch 374 → 792 not taken.
|
✗ |
Time time; |
| 822 |
0/2
✗ Branch 447 → 376 not taken.
✗ Branch 447 → 448 not taken.
|
✗ |
while (running) |
| 823 |
|
|
{ |
| 824 |
0/2
✗ Branch 376 → 377 not taken.
✗ Branch 376 → 787 not taken.
|
✗ |
const auto dt = time.calculate(); |
| 825 |
|
|
|
| 826 |
0/2
✗ Branch 377 → 378 not taken.
✗ Branch 377 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::start_frame, dt); |
| 827 |
|
|
|
| 828 |
|
|
SDL_Event e; |
| 829 |
0/2
✗ Branch 378 → 379 not taken.
✗ Branch 378 → 787 not taken.
|
✗ |
input.update(); |
| 830 |
0/4
✗ Branch 393 → 394 not taken.
✗ Branch 393 → 787 not taken.
✗ Branch 394 → 380 not taken.
✗ Branch 394 → 395 not taken.
|
✗ |
while (SDL_PollEvent(&e) != 0) |
| 831 |
|
|
{ |
| 832 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 833 |
0/2
✗ Branch 380 → 381 not taken.
✗ Branch 380 → 787 not taken.
|
✗ |
ImGui_ImplSDL3_ProcessEvent(&e); |
| 834 |
|
|
#endif |
| 835 |
|
|
|
| 836 |
0/4
✗ Branch 381 → 382 not taken.
✗ Branch 381 → 384 not taken.
✗ Branch 381 → 390 not taken.
✗ Branch 381 → 391 not taken.
|
✗ |
switch (e.type) |
| 837 |
|
|
{ |
| 838 |
|
✗ |
case SDL_EVENT_KEY_DOWN: |
| 839 |
|
|
case SDL_EVENT_KEY_UP: |
| 840 |
0/2
✗ Branch 382 → 383 not taken.
✗ Branch 382 → 787 not taken.
|
✗ |
input.on_key(e.key.key, e.type == SDL_EVENT_KEY_DOWN); |
| 841 |
|
✗ |
break; |
| 842 |
|
✗ |
case SDL_EVENT_WINDOW_RESIZED: |
| 843 |
0/6
✗ Branch 384 → 385 not taken.
✗ Branch 384 → 787 not taken.
✗ Branch 385 → 386 not taken.
✗ Branch 385 → 770 not taken.
✗ Branch 386 → 387 not taken.
✗ Branch 386 → 768 not taken.
|
✗ |
LOG_INFO("Resized"); |
| 844 |
0/2
✗ Branch 388 → 389 not taken.
✗ Branch 388 → 787 not taken.
|
✗ |
SDL_GetWindowSize(window, &window_width, &window_height); |
| 845 |
|
✗ |
break; |
| 846 |
|
✗ |
case SDL_EVENT_QUIT: running = false; break; |
| 847 |
|
✗ |
default: |
| 848 |
|
|
// ignore other events |
| 849 |
|
✗ |
break; |
| 850 |
|
|
} |
| 851 |
|
|
} |
| 852 |
|
|
|
| 853 |
|
|
// todo(Gustav): lookup unity frame, when updates are called and update stages |
| 854 |
0/2
✗ Branch 395 → 396 not taken.
✗ Branch 395 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::before_physics, dt); |
| 855 |
0/2
✗ Branch 396 → 397 not taken.
✗ Branch 396 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::physics, dt); |
| 856 |
0/2
✗ Branch 397 → 398 not taken.
✗ Branch 397 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::after_physics, dt); |
| 857 |
|
|
|
| 858 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 859 |
0/2
✗ Branch 398 → 399 not taken.
✗ Branch 398 → 787 not taken.
|
✗ |
ImGui_ImplOpenGL3_NewFrame(); |
| 860 |
0/2
✗ Branch 399 → 400 not taken.
✗ Branch 399 → 787 not taken.
|
✗ |
ImGui_ImplSDL3_NewFrame(); |
| 861 |
0/2
✗ Branch 400 → 401 not taken.
✗ Branch 400 → 787 not taken.
|
✗ |
ImGui::NewFrame(); |
| 862 |
|
|
|
| 863 |
0/2
✗ Branch 401 → 402 not taken.
✗ Branch 401 → 403 not taken.
|
✗ |
if (show_demo_window) |
| 864 |
|
|
{ |
| 865 |
0/2
✗ Branch 402 → 403 not taken.
✗ Branch 402 → 787 not taken.
|
✗ |
ImGui::ShowDemoWindow(&show_demo_window); |
| 866 |
|
|
} |
| 867 |
|
|
|
| 868 |
0/4
✗ Branch 403 → 404 not taken.
✗ Branch 403 → 787 not taken.
✗ Branch 404 → 405 not taken.
✗ Branch 404 → 417 not taken.
|
✗ |
if (ImGui::Begin("Renderer")) |
| 869 |
|
|
{ |
| 870 |
0/4
✗ Branch 405 → 406 not taken.
✗ Branch 405 → 774 not taken.
✗ Branch 407 → 408 not taken.
✗ Branch 407 → 415 not taken.
|
✗ |
if (auto prop = eu::imgui::PropTable::begin()) |
| 871 |
|
|
{ |
| 872 |
0/2
✗ Branch 408 → 409 not taken.
✗ Branch 408 → 772 not taken.
|
✗ |
prop.color("Clear color", &render_world.clear_color); |
| 873 |
0/2
✗ Branch 409 → 410 not taken.
✗ Branch 409 → 772 not taken.
|
✗ |
prop.simple_gamma_slider("Gamma/Brightness", &renderer.settings.gamma); |
| 874 |
0/2
✗ Branch 410 → 411 not taken.
✗ Branch 410 → 772 not taken.
|
✗ |
prop.check("Use bloom", &renderer.settings.use_bloom); |
| 875 |
0/2
✗ Branch 411 → 412 not taken.
✗ Branch 411 → 772 not taken.
|
✗ |
prop.drag("Bloom cutoff", &renderer.settings.bloom_cutoff, 0.001f); |
| 876 |
0/2
✗ Branch 412 → 413 not taken.
✗ Branch 412 → 772 not taken.
|
✗ |
prop.slider("Softness", &renderer.settings.bloom_softness, 0.0f, 1.0f); |
| 877 |
0/2
✗ Branch 413 → 414 not taken.
✗ Branch 413 → 772 not taken.
|
✗ |
prop.drag("Bloom blur steps", &renderer.settings.bloom_blur_steps); |
| 878 |
0/2
✗ Branch 414 → 415 not taken.
✗ Branch 414 → 772 not taken.
|
✗ |
effects.gui(&imgui_shader_cache, prop); |
| 879 |
|
✗ |
} |
| 880 |
|
|
|
| 881 |
0/2
✗ Branch 416 → 417 not taken.
✗ Branch 416 → 787 not taken.
|
✗ |
effects.gui_effects(); |
| 882 |
|
|
} |
| 883 |
0/2
✗ Branch 417 → 418 not taken.
✗ Branch 417 → 787 not taken.
|
✗ |
ImGui::End(); |
| 884 |
|
|
|
| 885 |
|
|
// todo(Gustav): add introspection ui |
| 886 |
0/4
✗ Branch 418 → 419 not taken.
✗ Branch 418 → 787 not taken.
✗ Branch 419 → 420 not taken.
✗ Branch 419 → 421 not taken.
|
✗ |
if (ImGui::Begin("Demo")) |
| 887 |
|
|
{ |
| 888 |
0/2
✗ Branch 420 → 421 not taken.
✗ Branch 420 → 787 not taken.
|
✗ |
runner_world.gui(); |
| 889 |
|
|
} |
| 890 |
0/2
✗ Branch 421 → 422 not taken.
✗ Branch 421 → 787 not taken.
|
✗ |
ImGui::End(); |
| 891 |
|
|
#endif |
| 892 |
|
|
|
| 893 |
|
✗ |
eu::render::RenderCommand cmd{ .states = &states, .render = &render, .size = {.width = window_width, .height = window_height} }; |
| 894 |
|
|
|
| 895 |
|
|
// clear |
| 896 |
|
|
{ |
| 897 |
|
|
{ |
| 898 |
|
✗ |
const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::extended, |
| 899 |
|
|
.requested_width = 800, .requested_height = 600 }; |
| 900 |
0/2
✗ Branch 422 → 423 not taken.
✗ Branch 422 → 775 not taken.
|
✗ |
cmd.clear(eu::colors::black, screen); |
| 901 |
|
|
} |
| 902 |
|
|
} |
| 903 |
|
|
|
| 904 |
0/2
✗ Branch 423 → 424 not taken.
✗ Branch 423 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::before_render, dt); |
| 905 |
|
|
|
| 906 |
|
|
// render 3d world |
| 907 |
|
|
{ |
| 908 |
|
✗ |
const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::black_bars, |
| 909 |
|
|
.requested_width = 800, .requested_height = 600 }; |
| 910 |
0/2
✗ Branch 424 → 425 not taken.
✗ Branch 424 → 778 not taken.
|
✗ |
cmd.clear(eu::colors::blue_sky, screen); |
| 911 |
0/2
✗ Branch 425 → 426 not taken.
✗ Branch 425 → 778 not taken.
|
✗ |
auto layer = eu::render::with_layer3(cmd, screen); |
| 912 |
|
|
// todo(Gustav): get transform from camera entity |
| 913 |
0/2
✗ Branch 426 → 427 not taken.
✗ Branch 426 → 778 not taken.
|
✗ |
effects.update(dt); |
| 914 |
0/2
✗ Branch 427 → 428 not taken.
✗ Branch 427 → 778 not taken.
|
✗ |
eu::render::Camera camera = camera_fetcher->fetch(); |
| 915 |
0/2
✗ Branch 430 → 431 not taken.
✗ Branch 430 → 776 not taken.
|
✗ |
effects.render(eu::render::PostProcArg{ |
| 916 |
|
|
.world = &render_world, |
| 917 |
0/2
✗ Branch 428 → 429 not taken.
✗ Branch 428 → 776 not taken.
|
✗ |
.window_size = size_from_v2(layer.screen.get_size()), |
| 918 |
|
|
.final_rect = layer.screen, |
| 919 |
|
|
.camera = &camera, |
| 920 |
|
|
.renderer = &renderer |
| 921 |
|
|
}); |
| 922 |
|
|
} |
| 923 |
|
|
|
| 924 |
|
|
// render hud |
| 925 |
|
|
{ |
| 926 |
|
✗ |
const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::black_bars, |
| 927 |
|
|
.requested_width = 1280, .requested_height = 720 }; |
| 928 |
|
|
|
| 929 |
0/2
✗ Branch 431 → 432 not taken.
✗ Branch 431 → 786 not taken.
|
✗ |
auto layer = eu::render::with_layer2(cmd, screen); |
| 930 |
|
✗ |
const float hud_size = 100.0f; |
| 931 |
0/8
✗ Branch 435 → 436 not taken.
✗ Branch 435 → 780 not taken.
✗ Branch 436 → 437 not taken.
✗ Branch 436 → 780 not taken.
✗ Branch 438 → 439 not taken.
✗ Branch 438 → 779 not taken.
✗ Branch 439 → 440 not taken.
✗ Branch 439 → 779 not taken.
|
✗ |
eu::render::Quad{ .tint = eu::colors::blue_sky }.draw(layer.batch, layer.viewport_aabb_in_worldspace.get_bottom(hud_size).get_right(hud_size).with_inset(eu::Lrtb{ 5.0f })); |
| 932 |
|
✗ |
} |
| 933 |
|
|
|
| 934 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 935 |
0/2
✗ Branch 441 → 442 not taken.
✗ Branch 441 → 787 not taken.
|
✗ |
ImGui::Render(); |
| 936 |
0/4
✗ Branch 442 → 443 not taken.
✗ Branch 442 → 787 not taken.
✗ Branch 443 → 444 not taken.
✗ Branch 443 → 787 not taken.
|
✗ |
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); |
| 937 |
|
|
#endif |
| 938 |
0/2
✗ Branch 444 → 445 not taken.
✗ Branch 444 → 787 not taken.
|
✗ |
SDL_GL_SwapWindow(window); |
| 939 |
|
|
|
| 940 |
0/2
✗ Branch 445 → 446 not taken.
✗ Branch 445 → 787 not taken.
|
✗ |
runner_world.update(runner::UpdateStage::end_frame, dt); |
| 941 |
|
|
} |
| 942 |
|
|
|
| 943 |
|
|
#if FF_HAS(EU_DEBUG_RUNNER) |
| 944 |
0/2
✗ Branch 448 → 449 not taken.
✗ Branch 448 → 792 not taken.
|
✗ |
ImGui_ImplOpenGL3_Shutdown(); |
| 945 |
0/2
✗ Branch 449 → 450 not taken.
✗ Branch 449 → 792 not taken.
|
✗ |
ImGui_ImplSDL3_Shutdown(); |
| 946 |
0/2
✗ Branch 450 → 451 not taken.
✗ Branch 450 → 792 not taken.
|
✗ |
ImGui::DestroyContext(); |
| 947 |
|
|
#endif |
| 948 |
|
|
|
| 949 |
0/6
✗ Branch 451 → 452 not taken.
✗ Branch 451 → 792 not taken.
✗ Branch 452 → 453 not taken.
✗ Branch 452 → 790 not taken.
✗ Branch 453 → 454 not taken.
✗ Branch 453 → 788 not taken.
|
✗ |
LOG_INFO("Shutting down"); |
| 950 |
0/2
✗ Branch 455 → 456 not taken.
✗ Branch 455 → 792 not taken.
|
✗ |
SDL_GL_DestroyContext(glContext); |
| 951 |
0/2
✗ Branch 456 → 457 not taken.
✗ Branch 456 → 792 not taken.
|
✗ |
SDL_DestroyWindow(window); |
| 952 |
0/2
✗ Branch 457 → 458 not taken.
✗ Branch 457 → 792 not taken.
|
✗ |
SDL_Quit(); |
| 953 |
|
|
|
| 954 |
|
✗ |
return 0; |
| 955 |
|
✗ |
} |
| 956 |
|
|
|