A Windows Direct3D 11 playground: a small renderer and editor-style UI built around an off-screen render target, Dear ImGui (docking + viewport), and an EnTT-backed scene.
Русская версия / Russian version → README.ru.md
Entry point is WinMain in Source/main.cpp, which constructs the engine via EntryPoint::initEngine() and runs Application::run(). EntryPoint checks that the host OS is Windows before creating the app.
Application owns the window (Window), initializes Renderer3D, GuiManager, and Scene, then runs the main loop in Application::run():
- Timestep — frame time is taken from a small
Timestephelper for camera updates. - 3D pass —
GraphicsManagerbinds the texture render target, clears it, andScene::renderScene()submits all draw work throughRenderer3D. - UI pass — the back buffer is bound and cleared; ImGui is framed, rendered (dock space, viewport, entity editor, metrics, demo window), then presented with
GraphicsManager::swapBuffers(). - Camera — updated when the viewport panel is hovered or focused, so UI interaction does not fight camera controls.
This split mimics a game/editor pipeline: world renders to an intermediate target, UI composites on top; the 3D result is shown with ImGui::Image using the scene texture’s shader resource view.
DX11Context creates the device and immediate context with D3D11CreateDevice (optional debug device in _DEBUG), asserts feature level 11_0, builds a swap chain (buffer format RGBA8_UNORM, double-buffered, refresh rate from EnumDisplaySettings, borderless fullscreen heuristic when client size matches desktop), and sets up a depth/stencil buffer bound with the main render targets.
GraphicsManager is a thin static façade over two RenderTarget instances:
- Back buffer — created from the swap chain for the final composite (clear + ImGui).
- Scene texture — a dedicated
RGBA82D texture with RTV + SRV (RenderTargetconstructor taking width/height) so the same GPU resource is both a render target and a sampleable texture for the ImGui viewport.
It centralizes bind/unbind of render targets, viewport sizing (with hooks to resize the back buffer when the window changes), clear, indexed draw, depth clear, and present.
Renderer3D is mostly static state: geometric primitives (Cube, Pyramid, Sphere), light helpers (PointLight, SpotLight), samplers, constant buffers, and loaded shaders. init() wires DX11Context and GraphicsManager, loads vertex/pixel shader bytecode (.cso), builds a fixed input layout (position, color, normal, material, texture coordinates, texture index), binds primitive topology (TRIANGLELIST), and sets up projection-related constant buffers.
begin() / end() bracket a frame batch with the active camera view–projection. Draw paths include both legacy-style helpers (drawCube(position, …)) and ECS-driven overloads that take TransformComponent, MaterialComponent, or MeshComponent so Scene::renderScene() can iterate EnTT views and dispatch without duplicating layout logic.
Textures default through a shared white texture; WIC loading uses DirectX Tool Kit (WICTextureLoader). Assimp loads .obj (and related) data in Model, which expands meshes into CPU-side vertex buffers compatible with the engine layout.
Scene holds a static entt::registry and a single camera pointer. Factories such as createCube(), createSphere(), createPointLight(), etc. create entities with the right default components. renderScene() uses EnTT views:
TransformComponent+MeshComponent— mesh type switches between cube, pyramid, sphere, or external model; optionalMaterialComponentsupplies color and texture.PointLightComponent/SpotLightComponent— separate passes for light visualization and buffer updates.
Entity is a thin handle around entt::entity with template helpers (addComponent, getComponent, hasComponent, removeComponent) that forward to Scene::s_Registry. Components are plain structs (UUIDComponent, TagComponent, transforms, mesh type + Model*, materials with Phong-style intensities, lights with attenuation and direction for spots). Transforms expose DirectXMath matrices for the GPU path.
GuiManager enables ImGui docking and multi-viewports, and bridges Win32 and D3D11 backends.
EntityEditor (Entedit) builds an outliner-style tree over entities with UUID/tag, context menus to spawn primitives and lights, delete, and property panels (transform drags, mesh type combo, material color and texture fields, light parameters). Loading a mesh model uses a Win32 file dialog (WindowsDialogs::openFile) and ResourceManager::createModel.
- Math — custom
Vector2f/Vector3f/Vector4fhelpers and matrix utilities layered on DirectXMath (XMMATRIXfor view/projection and transforms). - Exceptions — hierarchy around
BasicException/GraphicsException, plus an InfoManager path for richer D3D error reporting during development. - Resources —
ResourceManagercaches textures and models in maps keyed by path to avoid duplicate GPU uploads.
Resource/ holds textures, sample OBJ/MTL data, and HLSL sources. Compiled shader bytecode (.cso) is listed in .gitignore; the runtime expects bytecode at paths configured in Renderer3D.cpp (the exact names should stay in sync with whatever pixel shader variant implements your lighting pass).
| Area | Libraries / APIs |
|---|---|
| Platform | Windows, Win32 |
| Graphics | Direct3D 11, HLSL, DXGI swap chain |
| UI | Dear ImGui (imgui_impl_dx11, imgui_impl_win32) |
| ECS | EnTT |
| Models | Assimp |
| Images | DirectX Tool Kit (WIC texture loader) |
| Language | C++20-oriented (<format>, <numbers>, …) |
DX11Engine/
├── Source/
│ ├── Core/ Application, window, input, ImGui setup
│ ├── Renderer/ DX11 context, targets, pipeline, geometry, lighting, textures
│ ├── Scene/ Registry, entities, components
│ ├── Editor/ ImGui entity editor
│ ├── Events/ Keyboard / mouse
│ ├── Math/ Vectors and matrix helpers
│ ├── Exceptions/ Error types and debug helpers
│ └── Utils/ Win32 helpers (e.g. file dialogs)
├── Resource/ Textures, models, shader sources
├── Vendor/ ImGui, EnTT, Assimp, DirectXTK (vendored copies)
└── README.md / README.ru.md
Screenshots or a short clip of the docked viewport and entity editor read well on a portfolio page. If you publish the repo, add an explicit license for your own code (third-party code under Vendor/ keeps its original licenses).
Editor UI (viewport, entity list, properties, FPS) running inside the application window:
