Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f7bafb43f | |||
| fc4489d211 | |||
| 10f6df42c6 |
@@ -128,3 +128,4 @@ cd ../.. && git add external/raylib external/angelscript && git commit -m "Updat
|
||||
* Raylib: Zlib License (see https://github.com/raysan5/raylib#license)
|
||||
* AngelScript: MIT License (see https://github.com/angelcode/angelscript/blob/master/license.txt)
|
||||
* Simian: Not open source (yet)
|
||||
* Entt: MIT License (see https://github.com/skypjack/entt/blob/main/LICENSE)
|
||||
|
||||
@@ -10,15 +10,15 @@ Collapsed=0
|
||||
|
||||
[Window][Game Window]
|
||||
Pos=8,28
|
||||
Size=1264,684
|
||||
Size=1264,580
|
||||
Collapsed=0
|
||||
DockId=0x9076BACA,0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Window][Log Viewer]
|
||||
Pos=8,28
|
||||
Size=1264,684
|
||||
Pos=8,610
|
||||
Size=1264,102
|
||||
Collapsed=0
|
||||
DockId=0x9076BACA,1
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][##TOAST0]
|
||||
Pos=1007,637
|
||||
@@ -45,6 +45,33 @@ Pos=1048,375
|
||||
Size=212,57
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 CentralNode=1 Selected=0x27A02DAA
|
||||
[Window][Scene (0 entities)]
|
||||
Pos=60,60
|
||||
Size=32,36
|
||||
Collapsed=1
|
||||
|
||||
[Window][Comic Engine]
|
||||
Pos=60,60
|
||||
Size=387,337
|
||||
Collapsed=0
|
||||
|
||||
[Window][Scene (1 entities)]
|
||||
Pos=60,60
|
||||
Size=71,56
|
||||
Collapsed=0
|
||||
|
||||
[Window][Scene (2 entities)]
|
||||
Pos=60,60
|
||||
Size=71,82
|
||||
Collapsed=0
|
||||
|
||||
[Window][Scene (3 entities)]
|
||||
Pos=60,60
|
||||
Size=71,108
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,28 Size=1264,684 Split=Y Selected=0x27A02DAA
|
||||
DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,580 CentralNode=1 Selected=0x27A02DAA
|
||||
DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,102 Selected=0xBEDDA0C1
|
||||
|
||||
|
||||
@@ -35,4 +35,6 @@ private:
|
||||
|
||||
void Update(float deltaTime);
|
||||
void Draw();
|
||||
|
||||
void SpawnCube();
|
||||
};
|
||||
+95903
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
#version 330
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec2 textureSize;
|
||||
uniform int outlineSize = 2;
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
out vec4 finalColor;
|
||||
|
||||
void main() {
|
||||
vec2 texel = 1.0 / textureSize;
|
||||
float center = texture(texture0, fragTexCoord).r;
|
||||
|
||||
if (center < 0.5) {
|
||||
discard; // Transparent, show scene underneath
|
||||
return;
|
||||
}
|
||||
|
||||
// Edge detection
|
||||
bool edge = false;
|
||||
for (int y = -outlineSize; y <= outlineSize; y++) {
|
||||
for (int x = -outlineSize; x <= outlineSize; x++) {
|
||||
vec2 offset = vec2(float(x), float(y)) * texel;
|
||||
if (texture(texture0, fragTexCoord + offset).r < 0.5) {
|
||||
edge = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (edge) break;
|
||||
}
|
||||
|
||||
if (edge) {
|
||||
finalColor = vec4(0, 0, 0, 1); // Black outline
|
||||
} else {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#version 330
|
||||
|
||||
in vec3 fragNormal;
|
||||
in vec3 fragPosition;
|
||||
|
||||
uniform vec3 lightDir;
|
||||
uniform float bandCount;
|
||||
uniform vec4 albedo;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
// Normalize the normal and light direction
|
||||
vec3 normal = normalize(fragNormal);
|
||||
vec3 light = normalize(lightDir);
|
||||
|
||||
// Calculate the dot product for lighting
|
||||
float intensity = max(dot(normal, light), 0.0);
|
||||
|
||||
// Quantize the intensity for toon shading
|
||||
intensity = floor(intensity * bandCount) / bandCount;
|
||||
|
||||
// Set the fragment color
|
||||
//fragColor = vec4(vec3(intensity), 1.0);
|
||||
fragColor = vec4(albedo.rgb , albedo.a);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#version 330
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec3 fragNormal;
|
||||
out vec3 fragPosition;
|
||||
|
||||
void main() {
|
||||
fragPosition = vec3(model * vec4(vertexPosition, 1.0));
|
||||
fragNormal = mat3(transpose(inverse(model))) * vertexNormal; // Transform normals
|
||||
gl_Position = projection * view * vec4(fragPosition, 1.0);
|
||||
}
|
||||
+169
-38
@@ -4,6 +4,7 @@
|
||||
#include <thread>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <entt.hpp>
|
||||
#include "log/log.h"
|
||||
|
||||
#include "rlImGui.h"
|
||||
@@ -31,6 +32,36 @@ Application::~Application()
|
||||
// Shutdown();
|
||||
}
|
||||
|
||||
/// Shader and rendering data for the demo scene
|
||||
Camera3D camera;
|
||||
RenderTexture2D sceneRT, maskRT;
|
||||
Shader toonShader, outlineShader;
|
||||
Model cube;
|
||||
|
||||
float globalBandCount = 3.0f;
|
||||
Vector3 lightDir = {0.5f, 0.7f, 0.3f};
|
||||
bool showEditor = true;
|
||||
bool dayMode = true;
|
||||
entt::registry ecs;
|
||||
std::vector<Model> models;
|
||||
struct ECS_Transform
|
||||
{
|
||||
Vector3 pos, scale;
|
||||
float rot;
|
||||
};
|
||||
struct Render
|
||||
{
|
||||
int modelId;
|
||||
float outlineSize;
|
||||
Color color;
|
||||
};
|
||||
struct ECS_Material
|
||||
{
|
||||
Shader shader;
|
||||
int lightLoc, bandLoc;
|
||||
};
|
||||
/// ======
|
||||
|
||||
bool Application::Initialize(int argc, char *argv[])
|
||||
{
|
||||
if (fopen_s(&logFile, "log.txt", "w") != 0)
|
||||
@@ -55,6 +86,7 @@ bool Application::Initialize(int argc, char *argv[])
|
||||
enableEditor = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize Raylib
|
||||
InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE);
|
||||
SetTargetFPS(TARGET_FPS);
|
||||
@@ -87,9 +119,38 @@ bool Application::Initialize(int argc, char *argv[])
|
||||
renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
}
|
||||
|
||||
camera.position = {5, 5, 5};
|
||||
camera.target = {0, 0, 0};
|
||||
camera.up = {0, 1, 0};
|
||||
camera.fovy = 45;
|
||||
|
||||
// Assets
|
||||
cube = LoadModelFromMesh(GenMeshCube(1, 1, 1));
|
||||
models.push_back(cube);
|
||||
// Shaders (toon + outline)
|
||||
toonShader = LoadShader(0, "shaders/toon.fs");
|
||||
outlineShader = LoadShader(0, "shaders/outline.fs");
|
||||
|
||||
// Render textures
|
||||
sceneRT = LoadRenderTexture(1280, 720);
|
||||
maskRT = LoadRenderTexture(1280, 720);
|
||||
|
||||
// Cache uniform locations
|
||||
cube.materials[0].shader = toonShader;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::SpawnCube()
|
||||
{
|
||||
auto e = ecs.create();
|
||||
ecs.emplace<ECS_Transform>(
|
||||
e,
|
||||
Vector3{static_cast<float>(rand() % 3 - 1), 0.0f, static_cast<float>(rand() % 3 - 1)}, // Position
|
||||
Vector3{1.0f, 1.0f, 1.0f}, // Scale
|
||||
0.0f // Rotation
|
||||
);
|
||||
ecs.emplace<Render>(e, 0, 2.0f, YELLOW);
|
||||
}
|
||||
void Application::Run()
|
||||
{
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction());
|
||||
@@ -116,62 +177,125 @@ void Application::Update(float deltaTime)
|
||||
{
|
||||
log_warn("Script compilation failed - keeping previous version");
|
||||
Toast::Warning("Script compilation failed - check console for details.");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast::Success("Script reloaded successfully.");
|
||||
//Should call init function again or things don't work
|
||||
// Should call init function again or things don't work
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetInitFunction());
|
||||
}
|
||||
}
|
||||
|
||||
// Call script Update function
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime);
|
||||
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
// Day/night toggle
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
dayMode = !dayMode;
|
||||
globalBandCount = dayMode ? 3.0f : 2.0f;
|
||||
|
||||
// F1 editor toggle
|
||||
if (IsKeyPressed(KEY_F1))
|
||||
showEditor = !showEditor;
|
||||
|
||||
if (IsKeyPressed(KEY_F2))
|
||||
SpawnCube();
|
||||
}
|
||||
|
||||
void Application::Draw()
|
||||
{
|
||||
|
||||
int screenWidth = GetScreenWidth();
|
||||
int screenHeight = GetScreenHeight();
|
||||
|
||||
// Fallback to default values if screen dimensions are invalid
|
||||
if (screenWidth <= 0 || screenHeight <= 0)
|
||||
{
|
||||
log_warn("Invalid screen dimensions: %d x %d. Using default values.", screenWidth, screenHeight);
|
||||
screenWidth = 800;
|
||||
screenHeight = 600;
|
||||
}
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); // Set DisplaySize
|
||||
|
||||
BeginTextureMode(renderTexture);
|
||||
|
||||
ClearBackground(SKYBLUE);
|
||||
BeginMode3D(camera);
|
||||
DrawGrid(10, 1);
|
||||
DrawLine3D(Vector3{0, 0, 0}, Vector3{lightDir.x * 5.0f, lightDir.y * 5.0f, lightDir.z * 5.0f}, RED);
|
||||
BeginShaderMode(toonShader);
|
||||
SetShaderValue(toonShader, GetShaderLocation(toonShader, "lightDir"), &lightDir, SHADER_UNIFORM_VEC3);
|
||||
SetShaderValue(toonShader, GetShaderLocation(toonShader, "bandCount"), &globalBandCount, SHADER_UNIFORM_FLOAT);
|
||||
|
||||
auto view = ecs.view<ECS_Transform, Render>();
|
||||
view.each([&](const auto &t, const auto &r)
|
||||
{
|
||||
Vector4 color = {r.color.r / 255.0f, r.color.g / 255.0f, r.color.b / 255.0f, r.color.a / 255.0f};
|
||||
SetShaderValue(toonShader, GetShaderLocation(toonShader, "albedo"), &color, SHADER_UNIFORM_VEC4);
|
||||
DrawModel(models[r.modelId], t.pos, 1.0f, WHITE); // Use WHITE since color is handled by the shader
|
||||
});
|
||||
|
||||
EndShaderMode();
|
||||
|
||||
EndMode3D();
|
||||
// Call script Draw function
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction());
|
||||
|
||||
// 2. Silhouette mask
|
||||
// BeginTextureMode(maskRT);
|
||||
// ClearBackground(WHITE);
|
||||
// BeginMode3D(camera);
|
||||
|
||||
// for (auto e : ecs.view<ECS_Transform, Render>())
|
||||
// {
|
||||
// auto &t = ecs.get<ECS_Transform>(e);
|
||||
// DrawModel(models[ecs.get<Render>(e).modelId], t.pos, 1.0f, BLACK);
|
||||
// }
|
||||
|
||||
// EndMode3D();
|
||||
// EndTextureMode();
|
||||
|
||||
// // 3. Outline postprocess
|
||||
// BeginShaderMode(outlineShader);
|
||||
// Rectangle src = {0, 0, (float)maskRT.texture.width, (float)-maskRT.texture.height};
|
||||
// DrawTextureRec(maskRT.texture, src, {0, 0}, WHITE);
|
||||
EndShaderMode();
|
||||
EndTextureMode();
|
||||
if (enableEditor)
|
||||
{
|
||||
int screenWidth = GetScreenWidth();
|
||||
int screenHeight = GetScreenHeight();
|
||||
|
||||
// Fallback to default values if screen dimensions are invalid
|
||||
if (screenWidth <= 0 || screenHeight <= 0)
|
||||
{
|
||||
log_warn("Invalid screen dimensions: %d x %d. Using default values.", screenWidth, screenHeight);
|
||||
screenWidth = 800;
|
||||
screenHeight = 600;
|
||||
}
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)screenWidth, (float)screenHeight); // Set DisplaySize
|
||||
|
||||
BeginTextureMode(renderTexture);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Call script Draw function
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction());
|
||||
|
||||
EndTextureMode();
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
guiManager.Render(renderTexture); // Render the GUI
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
// rlImGuiBegin();
|
||||
// ImGui::Begin("Comic Engine");
|
||||
// std::string fpsText = "FPS: " + std::to_string(GetFPS());
|
||||
// ImGui::Text(fpsText.c_str());
|
||||
// if (ImGui::Button("Spawn Cube"))
|
||||
// SpawnCube();
|
||||
// ImGui::Checkbox("Day Mode", &dayMode);
|
||||
// ImGui::SliderFloat("Band Count", &globalBandCount, 1.0f, 5.0f);
|
||||
// ImGui::ColorEdit3("Light Dir", &lightDir.x);
|
||||
// ImGui::Text("F1: Toggle editor");
|
||||
// ImGui::End();
|
||||
|
||||
// Show script error status in top left if there's an error, otherwise show normal message
|
||||
if (scriptCompilationError)
|
||||
{
|
||||
DrawText("SCRIPT ERROR - Check console for details", 10, 10, 16, RED);
|
||||
}
|
||||
|
||||
// Call script Draw function
|
||||
scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction());
|
||||
// // Scene hierarchy
|
||||
// std::string sceneTitle = "Scene (" + std::to_string(ecs.view<ECS_Transform>().size()) + " entities)";
|
||||
// ImGui::Begin(sceneTitle.c_str());
|
||||
// for (auto e : ecs.view<ECS_Transform>())
|
||||
// {
|
||||
// if (ImGui::Button(std::string("Cube " + std::to_string((int)e)).c_str()))
|
||||
// {
|
||||
// ecs.get<ECS_Transform>(e).pos.x += 1.0f;
|
||||
// }
|
||||
// }
|
||||
// ImGui::End();
|
||||
// rlImGuiEnd();
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
@@ -197,6 +321,13 @@ void Application::Shutdown()
|
||||
// Shutdown script engine
|
||||
scriptEngine.Shutdown();
|
||||
|
||||
// Unload assets
|
||||
UnloadModel(cube);
|
||||
UnloadShader(toonShader);
|
||||
UnloadShader(outlineShader);
|
||||
UnloadRenderTexture(sceneRT);
|
||||
UnloadRenderTexture(maskRT);
|
||||
|
||||
// Clear the trace log callback before closing window to prevent logging after cleanup
|
||||
SetTraceLogCallback(nullptr);
|
||||
CloseWindow();
|
||||
|
||||
@@ -33,6 +33,8 @@ void GuiManager::Render(RenderTexture2D &renderTexture)
|
||||
RenderErrorBanner();
|
||||
RenderNotifications();
|
||||
logWindow.Render(showLogWindow); // Render the LogWindow
|
||||
|
||||
|
||||
rlImGuiEnd();
|
||||
|
||||
ImGui::UpdatePlatformWindows();
|
||||
|
||||
Reference in New Issue
Block a user