feat: refactor to move more elements to the scripting layer
CI / build-and-test (push) Successful in 2m13s
CI / build-and-test (push) Successful in 2m13s
This commit is contained in:
+69
-1
@@ -69,6 +69,59 @@ namespace ECS {
|
||||
void SetTag(uint entity, const string &in name);
|
||||
bool HasTag(uint entity);
|
||||
void RemoveTag(uint entity);
|
||||
|
||||
// Camera3D component
|
||||
void AddCamera3D(uint entity, float px, float py, float pz, float tx, float ty, float tz, float fovy);
|
||||
void SetCameraPosition(uint entity, float x, float y, float z);
|
||||
void SetCameraTarget(uint entity, float x, float y, float z);
|
||||
void SetCameraFovy(uint entity, float fovy);
|
||||
bool HasCamera3D(uint entity);
|
||||
void RemoveCamera3D(uint entity);
|
||||
|
||||
// Light component
|
||||
void AddLight(uint entity, float dx, float dy, float dz, float intensity = 1.0f);
|
||||
void SetLightDirection(uint entity, float x, float y, float z);
|
||||
void SetLightIntensity(uint entity, float intensity);
|
||||
void SetLightColor(uint entity, uint color);
|
||||
bool HasLight(uint entity);
|
||||
void RemoveLight(uint entity);
|
||||
|
||||
// Material component
|
||||
void AddMaterial(uint entity, uint materialId);
|
||||
void SetMaterialId(uint entity, uint materialId);
|
||||
uint GetMaterialId(uint entity);
|
||||
bool HasMaterial(uint entity);
|
||||
void RemoveMaterial(uint entity);
|
||||
|
||||
// RenderPass component
|
||||
void AddRenderPass(uint entity, int order, bool depthTest, bool depthWrite, uint shaderId);
|
||||
void SetRenderPassOrder(uint entity, int order);
|
||||
void SetRenderPassShader(uint entity, uint shaderId);
|
||||
bool HasRenderPass(uint entity);
|
||||
void RemoveRenderPass(uint entity);
|
||||
}
|
||||
|
||||
// Shader resource management
|
||||
namespace Shader {
|
||||
uint Load(const string &in vsPath, const string &in fsPath);
|
||||
void Unload(uint id);
|
||||
}
|
||||
|
||||
// Model resource management
|
||||
namespace Model {
|
||||
uint Load(const string &in path);
|
||||
uint LoadCube(float width, float height, float length);
|
||||
uint LoadSphere(float radius, int rings, int slices);
|
||||
uint LoadPlane(float width, float length, int resX, int resZ);
|
||||
void Unload(uint id);
|
||||
}
|
||||
|
||||
// Material resource management
|
||||
namespace Material {
|
||||
uint Create(uint shaderId, uint8 r, uint8 g, uint8 b, uint8 a);
|
||||
void Remove(uint id);
|
||||
void SetShader(uint id, uint shaderId);
|
||||
void SetAlbedo(uint id, uint8 r, uint8 g, uint8 b, uint8 a);
|
||||
}
|
||||
|
||||
namespace Texture {
|
||||
@@ -110,4 +163,19 @@ namespace Math {
|
||||
float Ceil(float value);
|
||||
float Modf(float x, float y);
|
||||
float Abs(float value);
|
||||
}
|
||||
}
|
||||
|
||||
// Raylib input and timing functions
|
||||
float GetTime();
|
||||
bool IsKeyPressed(int key);
|
||||
|
||||
// Raylib key constants
|
||||
const int KEY_SPACE = 32;
|
||||
const int KEY_ESCAPE = 256;
|
||||
const int KEY_ENTER = 257;
|
||||
const int KEY_TAB = 258;
|
||||
const int KEY_BACKSPACE = 259;
|
||||
const int KEY_RIGHT = 262;
|
||||
const int KEY_LEFT = 263;
|
||||
const int KEY_DOWN = 264;
|
||||
const int KEY_UP = 265;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// Example script showing how to use the new script-driven rendering system
|
||||
|
||||
// Global variables to track our resources
|
||||
uint g_toonShader = 0;
|
||||
uint g_outlineShader = 0;
|
||||
uint g_cubeModel = 0;
|
||||
uint g_sphereModel = 0;
|
||||
uint g_redMaterial = 0;
|
||||
uint g_blueMaterial = 0;
|
||||
|
||||
// Entities
|
||||
uint g_camera = 0;
|
||||
uint g_light = 0;
|
||||
uint g_cube = 0;
|
||||
uint g_sphere = 0;
|
||||
|
||||
void Init() {
|
||||
Toast::Info("Initializing script-driven rendering...");
|
||||
|
||||
// === Load Shaders ===
|
||||
g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs");
|
||||
g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs");
|
||||
|
||||
if (g_toonShader == 0 || g_outlineShader == 0) {
|
||||
Toast::Error("Failed to load shaders!");
|
||||
return;
|
||||
}
|
||||
|
||||
// === Load Models ===
|
||||
g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0);
|
||||
g_sphereModel = Model::LoadSphere(0.5, 16, 16);
|
||||
|
||||
// === Create Materials ===
|
||||
// Red material with toon shader
|
||||
g_redMaterial = Material::Create(g_toonShader, 255, 100, 100, 255);
|
||||
|
||||
// Blue material with toon shader
|
||||
g_blueMaterial = Material::Create(g_toonShader, 100, 100, 255, 255);
|
||||
|
||||
// === Set up Camera ===
|
||||
g_camera = ECS::CreateEntity();
|
||||
ECS::AddCamera3D(g_camera,
|
||||
5.0, 5.0, 5.0, // position
|
||||
0.0, 0.0, 0.0, // target
|
||||
45.0); // fovy
|
||||
ECS::AddTag(g_camera, "MainCamera");
|
||||
|
||||
// === Set up Light ===
|
||||
g_light = ECS::CreateEntity();
|
||||
ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity
|
||||
ECS::AddTag(g_light, "MainLight");
|
||||
|
||||
// === Create Cube with Outline ===
|
||||
g_cube = ECS::CreateEntity();
|
||||
ECS::AddTransform(g_cube, -1.5, 0.5, 0.0);
|
||||
ECS::AddSprite(g_cube, g_cubeModel, 0xFFFFFFFF, 0.0);
|
||||
ECS::AddMaterial(g_cube, g_redMaterial);
|
||||
ECS::AddTag(g_cube, "Cube");
|
||||
ECS::AddVelocity(g_cube, 0.0, 0.0, 0.0, 1.0); // rotating
|
||||
|
||||
// Add outline render pass (order 0 = first)
|
||||
ECS::AddRenderPass(g_cube, 0, false, true, g_outlineShader); // order=0, no depth test
|
||||
|
||||
// === Create Sphere ===
|
||||
g_sphere = ECS::CreateEntity();
|
||||
ECS::AddTransform(g_sphere, 1.5, 0.5, 0.0);
|
||||
ECS::AddSprite(g_sphere, g_sphereModel, 0xFFFFFFFF, 0.0);
|
||||
ECS::AddMaterial(g_sphere, g_blueMaterial);
|
||||
ECS::AddTag(g_sphere, "Sphere");
|
||||
ECS::AddVelocity(g_sphere, 0.5, 0.0, 0.2, 0.5); // moving and rotating
|
||||
|
||||
// Add main render pass (order 1 = second, after outlines)
|
||||
ECS::AddRenderPass(g_sphere, 1, true, true, 0); // order=1, with depth test
|
||||
|
||||
Toast::Success("Script-driven rendering initialized!");
|
||||
}
|
||||
bool lightToggle = false;
|
||||
void Update(float dt) {
|
||||
// Camera orbital movement
|
||||
if (ECS::HasCamera3D(g_camera)) {
|
||||
float angle = GetTime() * 0.3;
|
||||
float radius = 7.0;
|
||||
float x = Math::Cos(angle) * radius;
|
||||
float z = Math::Sin(angle) * radius;
|
||||
ECS::SetCameraPosition(g_camera, x, 5.0, z);
|
||||
}
|
||||
|
||||
// Example: Toggle light direction with space
|
||||
if (IsKeyPressed(KEY_SPACE)) {
|
||||
|
||||
lightToggle = !lightToggle;
|
||||
|
||||
if (lightToggle) {
|
||||
ECS::SetLightDirection(g_light, -0.5, 0.7, -0.3);
|
||||
Toast::Info("Light direction changed!");
|
||||
} else {
|
||||
ECS::SetLightDirection(g_light, 0.5, 0.7, 0.3);
|
||||
Toast::Info("Light direction reset!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+89
-18
@@ -1,5 +1,16 @@
|
||||
// ECS-based game script demo
|
||||
// This demonstrates creating entities with various components
|
||||
// ECS-based game script demo with script-driven rendering
|
||||
// This demonstrates creating entities with various components and managing rendering
|
||||
|
||||
// Resource IDs
|
||||
uint g_toonShader = 0;
|
||||
uint g_outlineShader = 0;
|
||||
uint g_cubeModel = 0;
|
||||
uint g_sphereModel = 0;
|
||||
uint g_defaultMaterial = 0;
|
||||
|
||||
// Scene entities
|
||||
uint g_camera = 0;
|
||||
uint g_light = 0;
|
||||
|
||||
// Store entity IDs for manipulation
|
||||
array<uint> entities;
|
||||
@@ -8,25 +19,67 @@ uint spinningCube;
|
||||
float time = 0.0f;
|
||||
|
||||
void Init() {
|
||||
Log(LOG_TRACE, "Initialization complete - ECS Demo!");
|
||||
Log(LOG_TRACE, "Initialization complete - ECS Demo with Script-Driven Rendering!");
|
||||
Toast::Success("ECS Script initialized successfully!");
|
||||
|
||||
// Create a player entity at origin
|
||||
// === Load shaders ===
|
||||
g_toonShader = Shader::Load("shaders/toon.vs", "shaders/toon.fs");
|
||||
g_outlineShader = Shader::Load("shaders/outline.vs", "shaders/outline.fs");
|
||||
|
||||
if (g_toonShader == 0 || g_outlineShader == 0) {
|
||||
Toast::Error("Failed to load shaders!");
|
||||
return;
|
||||
}
|
||||
|
||||
// === Load models ===
|
||||
g_cubeModel = Model::LoadCube(1.0, 1.0, 1.0);
|
||||
g_sphereModel = Model::LoadSphere(0.5, 16, 16);
|
||||
|
||||
// === Create default material ===
|
||||
g_defaultMaterial = Material::Create(g_toonShader, 255, 255, 255, 255);
|
||||
|
||||
// === Set up camera ===
|
||||
g_camera = ECS::CreateEntity();
|
||||
ECS::AddCamera3D(g_camera,
|
||||
5.0, 5.0, 5.0, // position
|
||||
0.0, 0.0, 0.0, // target
|
||||
45.0); // fovy
|
||||
ECS::AddTag(g_camera, "MainCamera");
|
||||
|
||||
// === Set up light ===
|
||||
g_light = ECS::CreateEntity();
|
||||
ECS::AddLight(g_light, 0.5, 0.7, 0.3, 1.0); // direction + intensity
|
||||
ECS::AddTag(g_light, "MainLight");
|
||||
|
||||
// === Create player entity at origin with outline ===
|
||||
player = ECS::CreateEntity();
|
||||
ECS::AddTransform(player, 0.0f, 0.0f, 0.0f);
|
||||
ECS::AddSprite(player, 1, 0xFF0000FF, 0.0f); // Red cube, model 0
|
||||
ECS::AddSprite(player, g_sphereModel, 0xFF0000FF, 0.0f); // Red sphere
|
||||
|
||||
// Create material for player
|
||||
uint playerMat = Material::Create(g_toonShader, 255, 0, 0, 255);
|
||||
ECS::AddMaterial(player, playerMat);
|
||||
|
||||
// Add outline pass (order=0) and main pass (order=1)
|
||||
ECS::AddRenderPass(player, 0, false, true, g_outlineShader);
|
||||
|
||||
ECS::AddTag(player, "Player");
|
||||
Log(LOG_INFO, "Created player entity: " + player);
|
||||
|
||||
// Create a spinning cube
|
||||
// === Create a spinning cube ===
|
||||
spinningCube = ECS::CreateEntity();
|
||||
ECS::AddTransform(spinningCube, 2.0f, 0.0f, 0.0f);
|
||||
ECS::AddSprite(spinningCube, 0, 0x00FF00FF, 0.0f); // Green cube
|
||||
ECS::AddSprite(spinningCube, g_cubeModel, 0x00FF00FF, 0.0f); // Green cube
|
||||
ECS::AddVelocity(spinningCube, 0.0f, 0.0f, 0.0f, 2.0f); // Angular velocity
|
||||
|
||||
uint greenMat = Material::Create(g_toonShader, 0, 255, 0, 255);
|
||||
ECS::AddMaterial(spinningCube, greenMat);
|
||||
ECS::AddRenderPass(spinningCube, 1, true, true, 0); // Main pass
|
||||
|
||||
ECS::AddTag(spinningCube, "Spinner");
|
||||
Log(LOG_INFO, "Created spinning cube: " + spinningCube);
|
||||
|
||||
// Create orbiting entities
|
||||
// === Create orbiting entities ===
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint entity = ECS::CreateEntity();
|
||||
|
||||
@@ -39,27 +92,36 @@ void Init() {
|
||||
|
||||
// Different colors for each
|
||||
uint color = 0;
|
||||
if (i == 0) color = 0xFFFF00FF; // Yellow
|
||||
else if (i == 1) color = 0xFF00FFFF; // Magenta
|
||||
else if (i == 2) color = 0x00FFFFFF; // Cyan
|
||||
else if (i == 3) color = 0xFFA500FF; // Orange
|
||||
else color = 0xFF69B4FF; // Pink
|
||||
uint8 r = 255, g = 255, b = 255;
|
||||
if (i == 0) { color = 0xFFFF00FF; r = 255; g = 255; b = 0; } // Yellow
|
||||
else if (i == 1) { color = 0xFF00FFFF; r = 255; g = 0; b = 255; } // Magenta
|
||||
else if (i == 2) { color = 0x00FFFFFF; r = 0; g = 255; b = 255; } // Cyan
|
||||
else if (i == 3) { color = 0xFFA500FF; r = 255; g = 165; b = 0; } // Orange
|
||||
else { color = 0xFF69B4FF; r = 255; g = 105; b = 180; } // Pink
|
||||
|
||||
ECS::AddSprite(entity, g_sphereModel, color, 0.0f);
|
||||
|
||||
uint mat = Material::Create(g_toonShader, r, g, b, 255);
|
||||
ECS::AddMaterial(entity, mat);
|
||||
ECS::AddRenderPass(entity, 1, true, true, 0);
|
||||
|
||||
ECS::AddSprite(entity, 1, color, 0.0f);
|
||||
ECS::AddTag(entity, "Orbiter" + i);
|
||||
|
||||
entities.insertLast(entity);
|
||||
}
|
||||
|
||||
// Create a moving entity
|
||||
// === Create a moving entity ===
|
||||
uint mover = ECS::CreateEntity();
|
||||
ECS::AddTransform(mover, -3.0f, 0.5f, 0.0f);
|
||||
ECS::AddSprite(mover, 0, 0xFFFFFFFF, 0.0f); // White cube
|
||||
ECS::AddSprite(mover, g_cubeModel, 0xFFFFFFFF, 0.0f); // White cube
|
||||
ECS::AddVelocity(mover, 1.0f, 0.0f, 0.5f, 0.0f); // Moving velocity
|
||||
|
||||
ECS::AddMaterial(mover, g_defaultMaterial);
|
||||
ECS::AddRenderPass(mover, 1, true, true, 0);
|
||||
|
||||
ECS::AddTag(mover, "Mover");
|
||||
entities.insertLast(mover);
|
||||
|
||||
Toast::Success("Created " + (entities.length() + 3) + " entities!");
|
||||
Toast::Success("Created " + (entities.length() + 2) + " entities with script-driven rendering!");
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
@@ -69,6 +131,15 @@ void Shutdown() {
|
||||
void Update(float dt) {
|
||||
time += dt;
|
||||
|
||||
// Update camera to orbit around the scene
|
||||
if (ECS::HasCamera3D(g_camera)) {
|
||||
float angle = time * 0.3;
|
||||
float radius = 7.0;
|
||||
float x = Math::Cos(angle) * radius;
|
||||
float z = Math::Sin(angle) * radius;
|
||||
ECS::SetCameraPosition(g_camera, x, 5.0, z);
|
||||
}
|
||||
|
||||
// Update player position - simple back and forth motion
|
||||
float playerX = Math::Sin(time) * 2.0f;
|
||||
ECS::SetPosition(player, playerX, 0.0f, 0.0f);
|
||||
|
||||
Reference in New Issue
Block a user