Commit Graph
55 Commits
Author SHA1 Message Date
emil28092005 233041ab00 fix: VK_INDEX_TYPE_UINT32 (was UINT16) + remove unused depth from pipeline
- vkCmdBindIndexBuffer indexType changed from 0 (UINT16) to 1 (UINT32)
  to match uint[] index data — this was causing black screen
- Removed depth stencil state, depth attachment format, and depth
  rendering attachment from pipeline/renderer (depth buffer still
  created in swapchain but unused)
2026-06-18 12:59:01 +03:00
emil28092005 aca8d1ab4d fix: correct matrix order (proj*view) + Z depth range for Vulkan
- VP matrix order: proj*view (GLSL column-vector convention)
- Z correction in vertex shader: gl_Position.z = (z+w)*0.5 (OpenGL [-1,1] → Vulkan [0,1])
- Depth test temporarily disabled for debugging
2026-06-18 12:47:20 +03:00
emil28092005 d620bd537f revert: back to triangle with 3D rotation + depth buffer
- Hardcoded triangle (RGB vertices) with index buffer
- 3D rotation: RotateZ * RotateX
- Depth buffer + UBO + push constant model matrix retained
- Camera at z=-3, perspective FOV 45°
2026-06-18 12:44:06 +03:00
emil28092005 e740cf1214 fix: compute face normals when OBJ has no vn lines
- ObjLoader.ParseFace: if no normals in OBJ, compute face normal from
  first triangle using MeshMath.ComputeFaceNormal and apply to all face vertices
- cube.obj has no vn lines, so all faces previously had normal (0,1,0)
- Now each face has correct outward-facing normal for proper lighting
2026-06-18 12:42:13 +03:00
emil28092005 d6ca80c678 fix: add normal-based diffuse lighting so cube is visible as 3D
- Fragment shader: directional light dot(normal, lightDir) with 0.2 ambient
- Vertex shader: pass normal through mat3(model) to fragment
- Same-color faces now have different shading based on orientation
2026-06-18 12:39:51 +03:00
emil28092005 d6bd1807cf feat: depth buffer + 3D model matrix — rotating cube now looks correct
- Depth image (D32_SFLOAT) + image view created in VulkanSwapchain
- VkPipelineDepthStencilStateCreateInfo: depth test + write enabled, CompareOp=Less
- Push constant changed from float angle (4B) to mat4 model (64B)
- 3D rotation: RotateY * RotateX in renderer, applied via push constant
- Vertex shader: gl_Position = vp * model * vec4(pos, 1.0)
- Depth attachment in VkRenderingInfo + depth clear (1.0)
- Depth image layout transition (Undefined → DepthStencilAttachmentOptimal)
- New Vulkan functions: vkCreateImage, vkDestroyImage, vkGetImageMemoryRequirements, vkBindImageMemory
- New structs: VkPipelineDepthStencilStateCreateInfo, VkStencilOpState, VkImageCreateInfo
- New enums: VkCompareOp, VkImageType, VkImageTiling
- 0 validation errors
2026-06-18 02:14:54 +03:00
emil28092005 fde8b0f63a feat: index buffer + OBJ cube rendering
- VulkanIndexBuffer.cs: staging → device-local index buffer (uint16 indices)
- vkCmdBindIndexBuffer + vkCmdDrawIndexed added to Vk.cs
- VulkanRenderer loads Content/cube.obj via ObjLoader (36 vertices, 12 faces)
- Replaced hardcoded triangle with rotating cube
- 0 validation errors, ~3800 FPS
2026-06-18 02:05:15 +03:00
emil28092005 4f3810010a feat: push constants + UBO descriptor sets — rotating triangle with VP matrix
- Push constants: rotation angle (float) sent to vertex shader via vkCmdPushConstants
- UBO + descriptor sets: VP matrix (mat4) in uniform buffer, bound via VkDescriptorSet
- New Vulkan functions: vkCreateDescriptorSetLayout, vkCreateDescriptorPool,
  vkAllocateDescriptorSets, vkUpdateDescriptorSets, vkCmdBindDescriptorSets,
  vkCmdPushConstants
- New structs: VkPushConstantRange, VkDescriptorSetLayoutBinding,
  VkDescriptorSetLayoutCreateInfo, VkDescriptorPoolCreateInfo,
  VkDescriptorPoolSize, VkDescriptorSetAllocateInfo, VkWriteDescriptorSet,
  VkDescriptorBufferInfo
- Per-frame UBO buffers (HOST_VISIBLE|HOST_COHERENT, 64 bytes each)
- Perspective projection + look-at camera (static, no ECS yet)
- Cleaned up debug logging in VulkanContext
- Zero validation errors
2026-06-18 01:59:41 +03:00
emil28092005 2e0970e769 feat: rebuild Vulkan renderer from scratch — pure P/Invoke triangle (Vulkan 1.3)
- Complete rewrite of Engine.Graphics.Vulkan with pure P/Invoke (no wrapper libs)
- Vulkan 1.3: dynamic rendering (vkCmdBeginRendering/vkCmdEndRendering),
  synchronization2 (vkQueueSubmit2, vkCmdPipelineBarrier2)
- Split types into VulkanHandles.cs, VulkanEnums.cs, VulkanStructs.cs
- Staging buffer → device-local vertex buffer pattern
- Correct swapchain semaphore indexing (per-image, not per-frame-in-flight)
- VK_EXT_debug_utils debug messenger with validation layer fallback
- Dynamic viewport/scissor (no pipeline recreation on resize)
- Simplified Program.cs to triangle-only rendering
- Removed old Silk.NET renderer, ImGui, PBR shaders, screenshot code
- Updated VULKAN_IMPLEMENTATION_PLAN.md with full architecture decisions
2026-06-18 01:49:25 +03:00
emil28092005 ee98e4ad08 fix(window): ensure SDL3/Wayland window is mapped by pumping events after ShowWindow
- Remove ALWAYS_ON_TOP and debug print hacks.
- Pump SDL events after SDL_ShowWindow so the Wayland compositor maps the window.
- Clean run.sh: do not force DISPLAY or SDL_VIDEODRIVER, let SDL3 auto-detect.
2026-06-18 00:38:16 +03:00
emil28092005 aa93b55a74 fix: window now visible — SDL_ShowWindow + Wayland support in run.sh
- Added SDL_ShowWindow + SDL_RaiseWindow after window creation
- run.sh: auto-detect Wayland vs X11, set SDL_VIDEODRIVER accordingly
- Wayland session uses SDL_VIDEODRIVER=wayland (bundled SDL3 lacks X11 support)
- Engine runs at 1600+ FPS, window visible on Wayland desktop
- Screenshots confirm 3D geometry rendering correctly
2026-06-18 00:22:27 +03:00
emil28092005 46a04850e3 fix: rendering now works — three critical bugs fixed
1. VkColorComponentFlags: wrong bit values (0x10-0x80 instead of 0x01-0x08)
   → colorWriteMask was 0xF0 instead of 0x0F → no color channels written

2. VkClearValue: was Sequential layout instead of Explicit (union)
   → depthStencil clear value written at wrong offset → depth buffer
   cleared to 0.0 instead of 1.0 → all fragments failed depth test

3. Vulkan clip space correction in vertex shader:
   gl_Position.y = -gl_Position.y (Vulkan Y-down vs OpenGL Y-up)
   gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5 (Z [0,1] vs [-1,1])

Also:
- PushConstantSize fixed from 128 to 144 (two mat4 + vec4)
- Dynamic viewport/scissor state added to pipeline
- Push constants use column_major (default) to match System.Numerics row-major layout
- Camera.GetProjectionMatrix reverted to pure OpenGL-style (correction in shader)
- Screenshots show actual 3D geometry (calibration cubes visible)
- 66/66 tests pass
2026-06-18 00:14:40 +03:00
emil28092005 749fbc8df4 feat: ImGui integration + real screenshot capture via Vulkan
ImGui:
- ImGui.NET 1.91.6.1 NuGet package
- VulkanImGui: font texture upload, ImGui pipeline (blending, no depth), vertex/index buffer streaming
- GLSL 450 ImGui shaders (vert: scale/translate push constants, frag: font texture sampler)
- Compiled to SPIR-V via @webgpu/glslang
- Debug overlay: FPS, camera position, entity count, light list
- 1600+ FPS with ImGui active

Screenshot:
- vkCmdCopyImageToBuffer embedded in main command buffer
- Layout transition PresentSrcKHR→TransferSrcOptimal→PresentSrcKHR
- Deferred read: staging buffer read on next frame after fence
- BMP format written directly to FileStream (row by row)
- All 16 camera tour screenshots captured (1280x720x32bpp)

All 66 tests pass.
2026-06-17 23:39:38 +03:00
emil28092005 544f6b59c0 feat: real screenshot capture — BMP from swapchain image via vkCmdCopyImageToBuffer
- Added vkCmdCopyImageToBuffer to P/Invoke layer
- Screenshot embedded in main command buffer (barrier PresentSrcKHR→TransferSrc, copy, barrier back)
- Deferred read: staging buffer read on next frame after fence signaled
- BMP format written directly to FileStream (row by row, avoids large heap allocations)
- BGRA→BGRA direct copy for B8G8R8A8 swapchain format
- All 16 camera tour screenshots captured successfully (1280x720x32bpp)
- 66/66 tests pass
2026-06-17 23:27:58 +03:00
emil28092005 80238b08f5 feat: pure Vulkan P/Invoke renderer — no wrappers, SDL3 window, SPIR-V shaders
- Engine.Graphics: restored interfaces (IRenderContext, IRenderer, RenderBackendFactory),
  loaders (ObjLoader, GltfLoader), ProceduralMesh, MeshMath, SceneSerializer
- Engine.Graphics.Vulkan: pure P/Invoke to libvulkan.so.1/vulkan-1.dll
  - VulkanNative: library loading, function pointer loading via vkGetInstanceProcAddr
  - Vk: static function cache for ~80 Vulkan functions, all delegate types
  - VulkanTypes: ~50 structs, ~20 enums matching Vulkan C headers
  - VulkanContext: instance, physical device, logical device, surface, memory types
  - VulkanSwapchain: swapchain, image views, depth image, render pass, framebuffers
  - VulkanPipeline: graphics pipeline, descriptor set layout, shader modules
  - VulkanBuffer: vertex/index/uniform buffers, staging, memory allocation
  - VulkanRenderer: command buffers, sync (semaphores/fences), render loop, 2 frames in flight
  - GLSL 450 shaders: PBR lighting (Fresnel, ACES, gamma), directional+point lights
  - Compiled to SPIR-V via @webgpu/glslang WASM
- CortexEngine.App: switched to vulkan backend, removed Raylib/OpenTK/ImGui refs
- Tests: all 66 pass (ObjLoader, MeshMath, ProceduralMesh, SceneSerializer, etc.)
- Camera tour: 16 poses, screenshots captured, clean shutdown
2026-06-17 23:03:24 +03:00
emil28092005 dd105ea4af chore: remove all graphics backends (Raylib, OpenTK, Vulkan/Silk.NET) — prepare for pure Vulkan P/Invoke rewrite 2026-06-17 22:12:51 +03:00
emil28092005 ff4a3faae9 revert: switch back to Raylib default, keep OpenTK for future
OpenTK renderer has matrix/swap issues causing garbled output.
Raylib restored as default. OpenTK project preserved for debugging.
Normal PBR shader restored in OpenTKRenderer.
2026-06-17 21:35:20 +03:00
emil28092005 f0af0a6b5e fix: rewrite OpenTK renderer from scratch — correct matrix transpose
- SetUniformMat4: copies Matrix4 to float[16] row-major, passes with
  transpose=true (OpenGL transposes row-major → column-major)
- Previous version used transpose=false with manual column-major copy
  which caused double-transpose → garbage rendering (strobe)
- VertexAttribPointer with stride=0 (tightly packed per-attribute buffers)
- MakeCurrent() explicitly in constructor to ensure GL context is ready
- 66/66 tests, 1400+ FPS
2026-06-17 21:28:53 +03:00
emil28092005 270806a189 feat: OpenTK 4.x OpenGL backend — replaces Silk.NET, default renderer
- Deleted Engine.Graphics.OpenGL (Silk.NET) project
- Created Engine.Graphics.OpenTK with OpenTK 4.9.4
- OpenTKWindow: GameWindow + ProcessEvents() (non-blocking), SwapBuffers()
- OpenTKInputState: KeyboardState/MouseState → Engine.Core.Key
- OpenTKRenderer: raw OpenGL 3.3 Core, managed arrays (no unsafe),
  OpenTK.Mathematics.Matrix4 (column-major, no transpose needed),
  shadow FBO with depth texture, PCF 3x3, full PBR shader
- OpenTKRenderContext + OpenTKBackendRegistrar ('opentk')
- Program.cs: default backend is 'opentk'
- 66/66 tests, 0 errors, 1600 FPS (VSync off)
2026-06-17 21:24:33 +03:00
emil28092005 5687e97a09 revert: switch back to Raylib as default backend
OpenGL backend has rendering issues (stripes) that need visual debugging.
Raylib restored as default. OpenGL backend code preserved for future work.
2026-06-17 21:05:59 +03:00
emil28092005 a306439f22 wip: OpenGL backend — pinned buffers, void* offsets, manual swap
- GCHandle.Alloc(Pinned) for BufferData to prevent GC relocation
- void* null for VertexAttribPointer offsets
- ShouldSwapAutomatically=false, manual SwapBuffers
- Solid color debug shader active
- Still has rendering issues — needs visual debugging
2026-06-17 21:05:17 +03:00
emil28092005 3c67790947 fix: column-major matrix copy for OpenGL
CopyMatrixToBuffer now transposes during copy (column-major output),
UniformMatrix4 uses transpose=false. Fixes garbage rendering.
2026-06-17 20:59:15 +03:00
emil28092005 07754a31bf fix: transpose matrices for OpenGL (row-major → column-major)
System.Numerics.Matrix4x4 is row-major, OpenGL UniformMatrix4 with
transpose=false expects column-major. Changed all UniformMatrix4 calls
to transpose=true. Also explicitly enable depth test + disable cull face
for main pass. Fixes strobe/flickering issue.
2026-06-17 20:55:59 +03:00
emil28092005 417915e861 feat: switch default backend to Silk.NET OpenGL
- OpenGLRenderContext: Initialize() + CreateOpenGL() for non-blocking
- OpenGLWindow: Initialize() instead of Run(), CreateGL() method
- Program.cs: default backend is now 'opengl', SwapBuffers per frame
- ImGui guarded: only initialized for RaylibRenderer, ObjectManipulator
  checks _imGuiAvailable before calling ImGui.GetIO()
- 66/66 tests, 145 FPS with OpenGL backend
2026-06-17 20:14:15 +03:00
emil28092005 cc9a1a4602 feat: Silk.NET OpenGL backend compiles — full shadow mapping support
- Fixed all Silk.NET 2.21 API issues:
  - BufferData with void* + fixed blocks
  - UniformMatrix4 with float[] buffer (CopyMatrixToBuffer helper)
  - DrawBuffer/ReadBuffer with DrawBufferMode/ReadBufferMode
  - Clear with (uint) cast
  - Input delegates: KeyDown(IKeyboard,Key,int), MouseDown(IMouse,MouseButton), Scroll(IMouse,ScrollWheel)
  - GetProgram with ProgramPropertyARB
  - IWindow alias SilkWindow to avoid ambiguity
- OpenGLRenderer: shadow FBO with depth texture, PCF 3x3, full PBR shader
- OpenGLRenderContext: Silk.NET window + GL context
- OpenGLBackendRegistrar registered as 'opengl'
- 66/66 tests, 0 errors
2026-06-17 18:59:36 +03:00
emil28092005 6e65eedf1d wip: Silk.NET OpenGL backend — project structure, partial implementation
- Engine.Graphics.OpenGL project with Silk.NET.OpenGL, Windowing, Input
- OpenGLWindow (Silk.NET.Windowing), OpenGLInputState (Silk.NET.Input)
- OpenGLRenderer: full shader pipeline with shadow mapping, VAO/VBO upload
- OpenGLRenderContext, OpenGLBackendRegistrar
- Build errors due to Silk.NET 2.21 API differences — needs API investigation
- Raylib and Vulkan backends unchanged
2026-06-17 18:48:36 +03:00
emil28092005 e452a294cc revert: remove shadow mapping attempts, restore clean renderer
Shadow mapping via Raylib doesn't work reliably:
- Rlgl.GetMatrixModelview returns zeros with custom FBO
- MaterialMapIndex binding doesn't map to expected texture units
- DrawModelEx resets texture state internally
Restored to last working state without shadows.
Consider direct OpenGL backend for shadow mapping.
2026-06-17 18:40:30 +03:00
emil28092005 573872298f fix: shadow map binding before draw + correct matrix transpose
- Use BeginShaderMode/EndShaderMode around DrawModelEx to keep shader active
- Bind shadow map on texture unit 1 BEFORE DrawModelEx (not after)
- Remove manual Matrix4x4.Transpose — SetShaderValueMatrix already handles
  row-major to column-major conversion via glUniformMatrix4fv(transpose=false)
- 66/66 tests, 145 FPS
2026-06-17 18:11:08 +03:00
emil28092005 6d16287bcb fix: shadow map re-bind after DrawModelEx + transpose lightViewProj
- Bind shadow map on MaterialMapIndex.Emission (unit 1) per entity
- Re-bind via Rlgl.ActiveTextureSlot(1)+EnableTexture after DrawModelEx
  (DrawModelEx resets texture state internally)
- Transpose lightViewProj matrix (Raylib row-major → OpenGL column-major)
- 66/66 tests, 145 FPS
2026-06-17 18:07:13 +03:00
emil28092005 2e73a0b52c feat: shadow mapping via rlgl depth FBO (official raylib approach)
- Depth-only FBO via Rlgl.LoadFramebuffer + Rlgl.LoadTextureDepth (2048x2048)
- Shadow pass: BeginMode3D with orthographic light camera, grab
  ModelView/Projection matrices via Rlgl.GetMatrixModelview/Projection
- Main pass: Rlgl.ActiveTextureSlot(1) + Rlgl.EnableTexture(depth) +
  SetShaderValue(shadowMapLoc, 1) to bind shadow map on texture unit 1
- Main shader: uniform mat4 lightViewProj + uniform sampler2D shadowMap
  with PCF 3x3 soft shadows, bias 0.005
- Shadow factor applied to first directional light only
- Shadow shader: empty fragment (depth written automatically)
- 66/66 tests, all shaders compile, 145 FPS
2026-06-17 18:03:45 +03:00
emil28092005 de262732bd feat: Unity-like object manipulation + physics fixes
- ObjectManipulator: left-click to pick, drag on camera-orthogonal plane
- Screen-space movement (like Unity), not ground-plane
- Skip dragged entity in SyncTransforms so physics doesn't fight drag
- Zero velocity on grab to prevent momentum accumulation
- ImGui selection sync with manipulator
- Floor lowered to y=-0.5, visual thickness corrected
- Physics shape sizes fixed (BoxShape uses half-extents)
- Collision pairs explicitly enabled in ObjectLayerPairFilterTable
2026-06-17 17:59:32 +03:00
emil28092005 a9d8af48e5 fix: enable collision pairs, correct physics shape sizes, lower floor
- ObjectLayerPairFilterTable blocks all collisions by default in C# binding;
  explicitly EnableCollision for all layer pairs (NonMoving/Moving)
- BoxShape takes half-extents, not full size: DynamicBox(scale * 0.5f)
- Floor visual thickness reduced (scale Y 1→0.5), top at y=0 matching collider
- Floor lowered to y=-0.5
- Physics works: cubes and spheres fall and land on floor, no clipping
2026-06-17 17:31:17 +03:00
emil28092005 4a5893dc61 fix: physics segfault — keep layer filter objects alive as fields
BroadPhaseLayerInterfaceTable, ObjectLayerPairFilterTable, and
ObjectVsBroadPhaseLayerFilterTable were local variables in the
constructor. After GC collected them, Jolt crashed with dangling
native pointers during PhysicsSystem.Update(). Now stored as readonly
fields with proper Dispose in cleanup. Also fixed Flecs table lock
assertion by collecting RigidBody init list before calling entity.Set().
2026-06-17 17:25:29 +03:00
emil28092005 cca89040c3 feat: JoltPhysicsSharp integration — physics simulation
- Engine.Physics project with JoltPhysicsSharp 2.21.0
- PhysicsWorld: PhysicsSystem init/update/dispose, body creation/removal,
  transform sync (Jolt body → ECS Transform)
- RigidBody ECS component: MotionType (Static/Kinematic/Dynamic),
  ShapeType (Box/Sphere), mass, friction, restitution, damping
- Factory methods: DynamicBox, DynamicSphere, StaticBox, StaticPlane
- Main loop integration: create bodies on first frame, step physics,
  sync transforms back to ECS
- Demo scene: 6 dynamic cubes + 3 dynamic spheres fall from height,
  static floor plane. Torus knot and textured cube remain static.
- Collision layers: NonMoving (floor), Moving (dynamic objects)
- JobSystemThreadPool for multi-threaded physics
- 66/66 tests passing, 0 warnings, 0 errors
2026-06-17 16:45:43 +03:00
emil28092005 9bee806a6c docs: update roadmap — shadow mapping deferred 2026-06-17 16:39:07 +03:00
emil28092005 23cac8052c fix: remove shadow mapping, keep all other improvements
Shadow mapping removed — Raylib's DrawModelEx doesn't support
multi-texture-unit binding needed for shadow map sampling.
Kept: linear gamma, per-channel Fresnel, point/directional lights,
correct CW normals, backface culling, floor entity.
66/66 tests passing.
2026-06-17 16:33:12 +03:00
emil28092005 c82ff48119 fix: rlgl depth FBO shadows, correct normals, linear gamma, per-channel Fresnel
- Shadow mapping via rlgl: custom depth FBO (2048x2048, 24-bit depth texture)
  instead of color-attachment approach. Proper depth-only render pass.
- Shadow map bound via MaterialMapIndex.Emission (texture unit 1), sampled
  in shadow receiver shader with PCF 3x3 soft shadows.
- Fixed inverted normals: Cross(ac, ab) for CW winding in OBJ files.
- Linear workflow: pow(albedo, 2.2) before lighting, pow(result, 1/2.2) after.
- Per-channel Fresnel: vec3 F0 + (1-F0)*pow(1-HdotV,5) instead of F0.x.
- Single CollectLights call after BeginMode3D.
- Shadow pass after BeginDrawing (inside frame).
- Backface culling disabled globally for mixed-winding meshes.
- Point light support: Light.Point/Directional factory methods, attenuation,
  ImGui inspector with type combo, position/range for point lights.
- Floor rendered for both light types (shadow receiver or main shader).
- 66/66 tests passing.
2026-06-17 16:13:46 +03:00
emil28092005 f905fe3040 fix: restore rendering after shadow mapping attempt
Shadow mapping via DrawModelEx doesn't work — Raylib's material system
only supports texture unit 0, shadow map sampling needs unit 1.
Additional uniforms in fragment shader also broke NVIDIA GLSL uniform
layout, causing render artifacts. Reverted shader to pre-shadow state.
Shadow pass infrastructure (RenderShadowPass, shadow shader, RT) kept
but disabled. 66/66 tests passing.
2026-06-17 14:44:49 +03:00
emil28092005 2d30dec01c feat: Dear ImGui editor, GLTF materials, scene serialization
- ImGuiLayer: entity inspector (Transform/Material/Light/Camera editing),
  hierarchy panel, debug overlay with FPS graph (rlImgui-cs + ImGui.NET)
- GltfLoader.LoadWithMaterials: extracts PBR albedo, roughness, metallic,
  base color texture from glTF files
- SceneSerializer: save/load ECS world to/from JSON with custom
  Vector3/Quaternion converters, 6 tests
- ImGui disabled in tour/test mode to keep screenshots clean
- 66/66 tests passing
2026-06-17 14:12:02 +03:00
emil28092005 fb6e26a268 feat: modular HAL, Raylib backend, PBR shading, textures, 60 unit tests
- Replace hardcoded SDL3 windowing with IWindow/IInputState/Key abstractions
- Each render backend owns its window (Raylib GLFW, SDL3 for Vulkan)
- Raylib backend: DrawModelEx, custom GLSL shader with Fresnel, ACES
  tonemapping, gamma correction, hemisphere ambient
- Fix backface culling, mesh memory (NativeMemory.Alloc), texture loading
- Camera controllers use backend-agnostic Key enum (inverted yaw/strafe)
- Demo scene: 8 cubes, 7 spheres, torus knot OBJ with checker texture
- Extract ProceduralMesh + MeshMath from Program.cs to Engine.Graphics
- Vulkan backend deferred (compiles, untested, IWindow-compatible)
- 60 unit tests: ObjLoader, camera controllers, AiCommandProcessor,
  RenderBackendFactory, Timing, ProceduralMesh, MeshMath, Transform
- AGENTS.md for opencode integration
2026-06-17 13:49:12 +03:00
emil28092005 61f8c7065e feat: WASD free-fly camera with F toggle
- Add ICameraController interface and FreeFlyCameraController.
- WASD moves, Q/E up/down, Shift sprint, right-mouse + mouse look.
- Toggle between Orbit and FreeFly with F key.
- OrbitCameraController now implements ICameraController.
- Update Program.cs to switch active controller on F.
- Update CORTEX_ENGINE_ARCHITECTURE.md with camera controls.
- Debug/Release/ReleaseAOT all build.
2026-06-16 21:14:32 +03:00
emil28092005 6d3b5cca37 feat: world state, multiple lights, textures, stdio MCP, Claude config
- Add get_world_state AI command that dumps ECS entities with Transform,
  Camera, Material, Light, and Mesh summaries.
- Add set_material AI command to update albedo/roughness/metallic/texture.
- Expose both commands as MCP HTTP tools and stdio tools.
- Add Light component and support up to 4 directional lights via a Vulkan
  uniform buffer (descriptor set 0) with std140 layout.
- Move per-frame lighting/camera data into the uniform buffer; push constants
  now carry only MVP + material properties (96 bytes).
- Add Texture class for PNG loading and Vulkan image/view/sampler creation.
- Add per-entity combined image sampler descriptor set (set 1) and use it
  for albedo texture sampling in the fragment shader.
- Generate a checkerboard floor texture in Program.cs.
- Add McpStdioServer for headless stdio MCP (Claude Desktop compatible).
- Add claude_desktop_config.json and scripts/start_mcp_engine.sh.
- Update CORTEX_ENGINE_ARCHITECTURE.md with runtime notes, CLI arguments,
  Vulkan pipeline details, and MCP client configuration.
- All configs (Debug/Release/ReleaseAOT) build successfully.
2026-06-16 21:07:09 +03:00
emil28092005 751e403c0c feat: materials, floor grid, specular lighting, orbit camera
- Add Material component with Albedo, Roughness, Metallic.
- MeshRenderer reads Material and tints vertex color; falls back to default.
- Add Blinn-Phong specular using camera position pushed via push constants.
- Add floor plane and grid mesh in Program.cs.
- Add OrbitCameraController with right-mouse orbit and mouse-wheel zoom.
- Forward SDL events to InputMapping from Sdl3Window.PumpEvents.
- Update main loop to update camera and aspect ratio on resize.
- Recompile SPIR-V shaders.
- Update CORTEX_ENGINE_ARCHITECTURE.md with Material, lighting, and orbit camera.
2026-06-16 20:28:32 +03:00
emil28092005 98a429710a feat: directional lighting with per-face normals
- Add Normal to Vertex struct and vertex input pipeline.
- Update vertex/fragment shaders with push-constant light data (direction, color, ambient).
- Compute per-face normals in ObjLoader and GltfLoader for flat shading.
- Add Transform.TransformNormal() using inverse-transpose of the model matrix.
- MeshRenderer builds world-space normals and pushes light constants each frame.
- Recompile SPIR-V shaders.
2026-06-16 20:18:20 +03:00
emil28092005 9312810f0c feat: AI screenshot capture for visual analysis
- Add ScreenshotCapture class to Engine.Graphics using Vulkan image readback.
- Integrate screenshot capture into MeshRenderer; request triggers readback on next frame.
- Add SixLabors.ImageSharp 3.1.11 for PNG encoding (patched for CVE-2025-54575).
- Add capture_screenshot AI command and MCP tool.
- Wire screenshot request into Program.cs with demo command.
- Expose swapchain surface format and image accessor for readback.
- Add Screenshots/ to .gitignore.
- Update CORTEX_ENGINE_ARCHITECTURE.md with MCP, Silk.NET.Vulkan, ImageSharp, and screenshot capture.
2026-06-16 20:09:57 +03:00
emil28092005 a9c783d204 feat: Step 6 MCP server bridge for AI agents
- Add ModelContextProtocol + ModelContextProtocol.AspNetCore 1.4.0 to Engine.AI.
- Expose AI commands as MCP tools: spawn_model, set_transform, delete_entity, list_entities.
- Add AiCommandQueue to marshal commands from the MCP server thread to the main thread.
- Start in-process HTTP MCP server in Program.cs (Debug/Release only; excluded in ReleaseAOT).
- Add --mcp-port CLI argument to configure the MCP server port.
- Fix Flecs.NET package conditions to include ReleaseAOT config.
2026-06-16 19:59:19 +03:00
emil28092005 2f21ffada4 feat: Step 5 AI agent command bridge
- Add new Engine.AI project referenced by the App.
- Define JSON command model: spawn_model, set_transform, delete_entity, list_entities.
- Implement AiCommandProcessor with System.Text.Json and custom Vector3/Quaternion converters.
- Wire processor into Program.cs; demo commands spawn and move a second cube.
- AI commands are executed against the live Flecs world and visible in the next frame.
2026-06-16 19:30:33 +03:00
emil28092005 e1ab3a14be feat: add depth buffer, camera and MVP push constants
- Add Camera ECS component with view/projection matrices.
- Add Vulkan depth buffer to Swapchain: image, memory, view, render pass, framebuffers.
- Update VulkanPipeline with depth stencil testing and push-constant layout.
- Update vertex shader to use push-constant MVP matrix.
- MeshRenderer finds Camera, computes MVP per entity and pushes it.
- Program.cs creates a camera entity and keeps the cube rotating.

Build and run verified: window opens and FPS is reported.
2026-06-16 19:20:29 +03:00
emil28092005 05703f820f feat: Step 4 load .obj and glTF models into ECS
- Add Vertex struct and Mesh ECS component (vertices + indices).
- Add Vulkan IndexBuffer for indexed draws.
- Add MeshRenderer that draws Mesh + Transform entities with vkCmdDrawIndexed.
- Add minimal .obj loader (positions, faces) and glTF/glTF-binary loader via SharpGLTF.Core.
- Rewrite shaders to 3D position + color; recompile to SPIR-V.
- Update VulkanPipeline for new vertex format.
- Ship a sample Content/cube.obj and wire Program.cs to load it.
- Remove TriangleRenderer (replaced by MeshRenderer).
2026-06-16 19:15:20 +03:00
emil28092005 608c3c24a8 feat: Step 3 Flecs.NET ECS integration with animated triangle
- Add Transform component and ECS world in Engine.Core.
- TriangleRenderer.RenderWorld queries entities and applies transforms.
- Animate a single triangle entity in Program.cs.
- Pin ppy.SDL3-CS to 2026.520.0 and add linux-x64 RID for bundled native SDL3.
- Add Flecs.NET.Debug/Release 4.0.4-build.546 per configuration.
- Update SDL3 API usage for the 2026.520.0 binding.
- Update architecture file to Silk.NET.Vulkan and Flecs 4.0.4.
2026-06-16 19:06:04 +03:00