Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
78a42f5
cooking v9 - shader and small update
vsaint1 Oct 29, 2025
2f28c9b
included nuklear lib
vsaint1 Oct 31, 2025
446015e
assimp and nuklear
vsaint1 Oct 31, 2025
d73a2a0
nuklear UI and some improvements
vsaint1 Nov 1, 2025
e856aad
default shader 2d
vsaint1 Nov 2, 2025
b43d161
renderer 2d
vsaint1 Nov 2, 2025
126d917
2d/3d renderer
vsaint1 Nov 3, 2025
73b9258
resizing window
vsaint1 Nov 6, 2025
579f7cc
ogl renderer impl rendering 2d/3d composition
vsaint1 Nov 6, 2025
c7fe081
components refactor
vsaint1 Nov 6, 2025
e4b5c50
fix: ogl state change
vsaint1 Nov 6, 2025
1dc6c8b
clang formating and gpu_image struct
vsaint1 Nov 6, 2025
7bdaa71
feat: transparent/opaque pass 🔥
vsaint1 Nov 6, 2025
d479460
feat: transparent obj test
vsaint1 Nov 6, 2025
6099a4e
sla
vsaint1 Nov 6, 2025
1189847
fix shader compilation
vsaint1 Nov 8, 2025
c251e5b
stb img write dependency
vsaint1 Nov 9, 2025
94a6379
stb img write dependency
vsaint1 Nov 9, 2025
997e378
define MAX_LIGHT
vsaint1 Nov 9, 2025
9516570
engine 3d api
vsaint1 Nov 9, 2025
e3b33c9
removed useless shader calc
vsaint1 Nov 14, 2025
79e52cb
refactor (later remove the WorldEnvironment3D from rendering api) to …
vsaint1 Nov 14, 2025
762b0f4
making engine api cooking v12
vsaint1 Nov 14, 2025
404c0e1
game objects refactor
vsaint1 Nov 16, 2025
e00d3a2
fix: defining release assertions
vsaint1 Nov 16, 2025
5068ce4
refactor: common libs ios/osx
vsaint1 Nov 17, 2025
fed826e
project config
vsaint1 Nov 17, 2025
2a707fe
fix: shadow artifacts and acne
vsaint1 Nov 17, 2025
6423cd4
refactoring api
vsaint1 Nov 17, 2025
a676e1e
cooking v13: changes on api, gpu textures and many more
vsaint1 Nov 17, 2025
55e5263
some code
vsaint1 Nov 22, 2025
880eb4c
some code
vsaint1 Nov 22, 2025
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
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ IndentCaseBlocks: true
# IndentCaseLabels: false
# IndentExternBlock: AfterExternBlock
# IndentGotoLabels: true
# IndentPPDirectives: None
IndentPPDirectives: BeforeHash
# IndentRequiresClause: true
# IndentWidth: 2
IndentWidth: 4
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ powerful**.
- [x] **PBR (Physically Based Rendering)** `SIMPLIFIED`
- [x] **Blinn-Phong Shading Model**
- [ ] **Skybox Reflections** IBL (Image Based Lighting)
- [ ] Frustrum Culling
- [ ] Frustum Culling
- [x] **Normal mapping** (TBN calculated per fragment)
- [ ] **3D Physics** (Jolt Physics Engine)
- [x] **Lighting System**
- [x] **Directional Light**
- [ ] **Point Light**
- [ ] **Spotlight**
- [x] **Spotlight**
- [x] **Shadow Mapping**
- [ ] **CSM** (Cascaded Shadow Maps) for Directional Lights
- [ ] **Post-Processing Effects** (Bloom, HDR, SSAO, Motion Blur, etc.)
Expand Down
213 changes: 183 additions & 30 deletions engine/private/core/api/engine_api.cpp
Original file line number Diff line number Diff line change
@@ -1,68 +1,221 @@
#pragma once
#include "core/api/engine_api.h"

void generate_unique_name(flecs::entity& e, const char* default_name, const char* custom_name) {
if (custom_name) {
e.set_name(custom_name);
} else {
std::string unique_name = std::string(default_name) + "_" + std::to_string(e.id());
e.set_name(unique_name.c_str());
}
}

void create_mesh_entity(
const char* name,
const char* path,
const glm::vec3& position,
const glm::vec3& rotation,
const glm::vec3& scale,
const char* material_tag) {
GameObject create_camera_3d_entity(const char* name, const glm::vec3& position, const glm::vec3& rotation, float fov, float near_plane,
float far_plane) {

auto renderer = GEngine->get_renderer();

const auto& world = GEngine->get_world();

flecs::entity e = world.entity().add<Camera3D>().set<Transform3D>({position, rotation});

generate_unique_name(e, "Camera3D", name);

const GameObject go(e);

return go;
}

GameObject create_directional_light_3d_entity(const char* name, const glm::vec3& direction, const glm::vec3& color, float intensity,
bool cast_shadows, float shadow_distance, float shadow_near, float shadow_far) {
const auto& world = GEngine->get_world();

flecs::entity e = world.entity().set<Transform3D>({}).set<DirectionalLight3D>(
{glm::normalize(direction), glm::vec3(color), intensity, cast_shadows, shadow_distance, shadow_near, shadow_far});

generate_unique_name(e, "DirectionalLight3D", name);

const GameObject go(e);

return go;
}

GameObject create_spot_light_3d_entity(const char* name, const glm::vec3& position, const glm::vec3& direction, const glm::vec3& color,
float inner_cutoff, float outer_cutoff, float intensity) {
const auto& world = GEngine->get_world();

flecs::entity entity = world.entity()
.set<Transform3D>({position})
.set<SpotLight3D>({glm::vec3(direction), glm::vec3(color), intensity, inner_cutoff, outer_cutoff});

generate_unique_name(entity, "SpotLight3D", name);

const GameObject go(entity);
return go;
}

GameObject create_mesh_3d_entity(const char* name, const char* path, const glm::vec3& position, const glm::vec3& rotation,
const glm::vec3& scale, const char* material_tag) {

const auto renderer = GEngine->get_renderer();

if (!renderer->_meshes.contains(path)) {
MeshInstance3D mesh = ObjectLoader::load_mesh(path);
MeshInstance3D mesh = AssimpLoader::load_mesh(path);
renderer->_meshes[path] = {mesh};
}

if (!renderer->_materials.contains(material_tag)) {
spdlog::error("Material '{}' not registered!", material_tag);
return;
return GameObject{};
}

GEngine->get_world().entity(name)
.set(Transform3D{position, rotation, scale})
.set(MeshRef{&renderer->_meshes[path][0]})
.set(MaterialRef{&renderer->_materials[material_tag][0]});
auto entity = GEngine->get_world()
.entity()
.set(Transform3D{position, rotation, scale})
.set(MeshRef{&renderer->_meshes[path][0]})
.set(MaterialRef{&renderer->_materials[material_tag][0]});

generate_unique_name(entity, "MeshInstance3D", name);

spdlog::info("MeshInstance3D entity '{}' created with material '{}'.", name, material_tag);

const GameObject go(entity);

return go;
}


void create_model_entity(
const char* name,
const char* path,
const glm::vec3& position,
const glm::vec3& rotation,
const glm::vec3& scale) {
GameObject create_model_3d_entity(const char* name, const char* path, BlendMode blend_mode, const glm::vec3& position,
const glm::vec3& rotation, const glm::vec3& scale) {

auto renderer = GEngine->get_renderer();


if (!renderer->_meshes.contains(path) || !renderer->_materials.contains(path)) {
Model model = ObjectLoader::load_model(path);
if (!renderer->_meshes.contains(path) || !renderer->_materials.contains(path)) {
Model model = AssimpLoader::load_model(path);

if (model.meshes.empty() || model.materials.empty()) {
spdlog::error("Failed to load model from path: {}", path);
return GameObject{};
}

renderer->_meshes[path] = model.meshes;
renderer->_materials[path] = model.materials;
}

const auto& meshes = renderer->_meshes[path];
const auto& materials = renderer->_materials[path];
const auto& meshes = renderer->_meshes[path];
auto& materials = renderer->_materials[path];

for (auto& material : materials) {
material.blend_mode = blend_mode;
material.update_feature_flags(); // Update flags after changing blend_mode
spdlog::debug("Material blend mode set to: {}, IBL enabled: {}", static_cast<int>(blend_mode), material.use_ibl);
}

auto entity = GEngine->get_world().entity(name);

for (size_t i = 0; i < meshes.size(); ++i) {
entity.child()
.set(Transform3D{position, rotation, scale})
.set(MeshRef{&meshes[i]})
.set(MaterialRef{&materials[i]});
entity.child().set(Transform3D{position, rotation, scale}).set(MeshRef{&meshes[i]}).set(MaterialRef{&materials[i]});
}

spdlog::info("MeshInstance3D entity '{}' created with {} mesh parts.", name, meshes.size());
const GameObject go(entity);

return go;
}


GameObject create_camera_2d_entity(const char* name, const glm::vec2& position, float rotation, float zoom) {

const auto& world = GEngine->get_world();

Camera2D camera;
camera.zoom = zoom;

flecs::entity e = world.entity().set(camera).set(Transform2D{position, glm::vec2(1.0f), rotation});

generate_unique_name(e, "Camera2D", name);

const GameObject go(e);

return go;
}

GameObject create_rectangle_2d_entity(const char* name, const glm::vec2& position, const glm::vec2& size, const glm::vec4& color,
bool filled) {
const auto& world = GEngine->get_world();

flecs::entity e = world.entity().set(Transform2D{position}).set(Rectangle2D{size, color, filled});

generate_unique_name(e, "Rectangle2D", name);

return GameObject(e);
}

GameObject create_circle_2d_entity(const char* name, const glm::vec2& position, float radius, const glm::vec4& color, bool filled,
float thickness, int segments) {
const auto& world = GEngine->get_world();

flecs::entity e = world.entity().set(Transform2D{position}).set(Circle2D{radius, color, filled, thickness, segments});

generate_unique_name(e, "Circle2D", name);


return GameObject(e);
}

GameObject create_line_2d_entity(const char* name, const glm::vec2& start, const glm::vec2& end, const glm::vec4& color,
float thickness) {
const auto& world = GEngine->get_world();

glm::vec2 relative_end = end - start;
flecs::entity e = world.entity().set(Transform2D{start}).set(Line2D{relative_end, color, thickness});

generate_unique_name(e, "Line2D", name);

return GameObject(e);
}

GameObject create_triangle_2d_entity(const char* name, const glm::vec2& p1, const glm::vec2& p2, const glm::vec2& p3,
const glm::vec4& color, bool filled) {
const auto& world = GEngine->get_world();

glm::vec2 relative_p2 = p2 - p1;
glm::vec2 relative_p3 = p3 - p1;
flecs::entity e = world.entity().set(Transform2D{p1}).set(Triangle2D{relative_p2, relative_p3, color, filled});

generate_unique_name(e, "Triangle2D", name);

return GameObject(e);
}

GameObject create_label_2d_entity(const char* name, const std::string& text, const glm::vec2& position, const glm::vec4& color,
float scale) {
const auto& world = GEngine->get_world();

flecs::entity e = world.entity().set(Transform2D{position}).set(Label2D{text, color, scale, "default"});

generate_unique_name(e, "Label2D", name);

return GameObject(e);
}

GameObject create_sprite_2d_entity(const char* name, const std::string& texture_path, const glm::vec2& position, const glm::vec2& size,
const glm::vec4& color) {
const auto& world = GEngine->get_world();

flecs::entity e = world.entity().set(Transform2D{position}).set(Sprite2D{texture_path, color, size});

generate_unique_name(e, "Sprite2D", name);

spdlog::info("Sprite2D entity '{}' created with texture '{}'.", name, texture_path);

return GameObject(e);
}



void create_material(const char* name, const Material& material) {
GEngine->get_renderer()->register_material(name,material);
void create_material(const char* name, Material material) {
material.update_feature_flags();
GEngine->get_renderer()->_materials[name] = {material};
spdlog::info("Material '{}' created and registered.", name);
}
Loading