Added CopyTexture support in ICommandBuffer
This commit is contained in:
@@ -1,75 +0,0 @@
|
|||||||
# GhostEngine 架构详解
|
|
||||||
|
|
||||||
本文档深入探讨 GhostEngine 核心模块的设计实现,为协同开发提供详细的技术参考。
|
|
||||||
|
|
||||||
## 1. 实体组件系统 (Ghost.Entities)
|
|
||||||
|
|
||||||
Ghost.Entities 采用 Archetype (原型) 模式,旨在优化大规模实体的遍历效率和内存布局。
|
|
||||||
|
|
||||||
### 1.1 核心组件
|
|
||||||
- **World**: 包含实体生命周期管理的顶层容器,包含 `EntityManager`。
|
|
||||||
- **Archetype**: 定义了一组特定组件的组合。具有相同组件集的所有实体都存储在同一 Archetype 中。
|
|
||||||
- **Chunk**: Archetype 内部的数据块,按列存储 (Columnar Storage) 组件数据,以确保对单个组件的线性访问具备极佳的 CPU 缓存亲和性。
|
|
||||||
- **EntityQuery**: 通过位掩码 (Bitmask) 快速匹配 Archetype,支持 `WithAll`, `WithAny`, `WithNone` 过滤规则。
|
|
||||||
|
|
||||||
### 1.2 并行处理
|
|
||||||
- 实体查询支持多线程作业系统 (Job System) 迭代。
|
|
||||||
- **EntityCommandBuffer (ECB)**: 允许在并行作业中排队待处理的实体修改请求 (如创建、删除、添加组件),并在单线程同步点进行统一应用,以避免竞态条件。
|
|
||||||
|
|
||||||
## 2. 渲染架构 (Ghost.Graphics)
|
|
||||||
|
|
||||||
渲染系统设计目标是支持高效、现代的图形渲染流水线,同时降低 D3D12 的开发复杂度。
|
|
||||||
|
|
||||||
### 2.1 RHI (渲染硬件接口)
|
|
||||||
RHI 位于 `Ghost.Graphics.RHI` 命名空间下,抽象了底层的渲染资源:
|
|
||||||
- **IRenderDevice**: 逻辑渲染设备。
|
|
||||||
- **ICommandBuffer**: 用于录制 GPU 指令。
|
|
||||||
- **IPipelineLibrary**: 缓存并管理渲染管线状态对象 (PSO)。
|
|
||||||
- **IResourceDatabase**: 管理显存资源 (Buffer, Texture) 及其生命周期。
|
|
||||||
|
|
||||||
### 2.2 Render Graph (渲染图)
|
|
||||||
Render Graph 是图形模块的核心组件,负责帧内资源的依赖分析和自动调度:
|
|
||||||
- **Pass Builder**: 在帧开始阶段,每个 Pass 声明其读取 (`Read`) 和写入 (`Write`) 的资源。
|
|
||||||
- **Resource Aliasing**: 自动识别不重叠的资源生命周期,实现显存的物理地址复用。
|
|
||||||
- **Automatic Barrier**: 自动根据资源的读写关系插入 `ResourceBarrier` (例如从 `RenderTarget` 状态转换到 `PixelShaderResource` 状态)。
|
|
||||||
|
|
||||||
### 2.3 自定义着色器语言 (Ghost.DSL)
|
|
||||||
引擎支持 `.gshdr` 文件,其语法借鉴了 HLSL 但增强了元数据支持:
|
|
||||||
- **自动属性映射**: DSL 编译器会解析着色器定义的属性,并自动生成与之匹配的 C# 结构体 (`ShaderStructGenerator`),简化 CPU 到 GPU 的数据传递。
|
|
||||||
|
|
||||||
## 3. 编辑器架构 (Ghost.Editor)
|
|
||||||
|
|
||||||
编辑器框架采用模块化设计,重点在于扩展性和资源工作流。
|
|
||||||
|
|
||||||
### 3.1 资源数据库 (Asset Database)
|
|
||||||
- **AssetRegistry**: 通过资源文件的 GUID 进行追踪,支持跨文件引用的完整性校验。
|
|
||||||
- **AssetProcessor**: 插件化系统,针对不同文件扩展名 (如 `.png`, `.fbx`) 提供特定的导入和转换逻辑 (如调用 Nvtt 压缩纹理)。
|
|
||||||
|
|
||||||
### 3.2 检查器 (Inspector)
|
|
||||||
- **Service-driven**: `InspectorService` 动态检测当前选中实体的组件列表,并根据组件类型匹配对应的 `ComponentEditor` 进行 UI 渲染。
|
|
||||||
- **Data Binding**: 利用 `ReflectionBinding` 实现编辑器 UI 与运行时组件数据的双向同步。
|
|
||||||
|
|
||||||
## 4. 核心设计原则 (Core Design Principles)
|
|
||||||
|
|
||||||
项目在底层代码中遵循以下核心设计原则,以确保高性能和系统稳定性:
|
|
||||||
|
|
||||||
### 4.1 Result over Exception (结果对象胜于异常)
|
|
||||||
在引擎的核心运行时(尤其是 `Ghost.Graphics` 和 `Ghost.Entities`)中,我们避免使用异常来处理预期的错误。
|
|
||||||
- **Result 结构体**: 使用 `Ghost.Core.Result` 或 `Result<T>` 结构体返回操作结果。
|
|
||||||
- **性能**: 避免了异常产生的堆栈跟踪开销。
|
|
||||||
- **显性处理**: 强制调用者检查 `IsSuccess` 或使用 `Deconstruct` 模式处理错误,使错误流更加清晰。
|
|
||||||
|
|
||||||
### 4.2 Handle over Ptr/Reference (句柄胜于指针/引用)
|
|
||||||
为了内存安全和支持序列化,引擎广泛使用句柄而非直接的内存指针。
|
|
||||||
- **Handle<T>**: 资源(如 `Texture`, `Buffer`, `Entity`)通过强类型句柄进行引用。
|
|
||||||
- **安全性**: 防止野指针问题,支持资源的延迟加载和卸载,而不破坏引用。
|
|
||||||
- **解耦**: 句柄作为后端资源的索引,使得底层的资源管理器(如 `D3D12ResourceDatabase`)可以自由地重新分配或移动物理资源。
|
|
||||||
|
|
||||||
## 5. 协同开发建议
|
|
||||||
|
|
||||||
|
|
||||||
- **跨项目引用**: 尽量避免 `Runtime` 项目引用 `Editor` 项目。`Editor` 应依赖 `Runtime` 以提供实时预览。
|
|
||||||
- **性能关键点**: 在 `Ghost.Entities` 和 `Ghost.Graphics` 模块中,应尽量避免堆内存分配 (GC Allocation),优先使用 `Span<T>`, `Memory<T>` 及非托管内存。
|
|
||||||
|
|
||||||
---
|
|
||||||
*注:本架构基于当前代码实现,如有变更将及时更新文档。*
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# GhostEngine 开发指南
|
|
||||||
|
|
||||||
欢迎参与 GhostEngine 项目。本文档旨在帮助你快速了解项目的当前状态、架构设计、开发规范及环境配置。
|
|
||||||
|
|
||||||
## 1. 开发环境要求 (Prerequisites)
|
|
||||||
|
|
||||||
在开始开发之前,请确保你的开发环境满足以下要求:
|
|
||||||
|
|
||||||
- **操作系统**: Windows 10 版本 1809 (17763) 或更高版本。
|
|
||||||
- **IDE**: Visual Studio 2022 (建议使用最新预览版以支持 .NET 10)。
|
|
||||||
- **.NET SDK**: .NET 10.0 SDK。
|
|
||||||
- **Windows App SDK**: 项目目前使用 Windows App SDK (WinUI 3) 版本 1.8.260101001。
|
|
||||||
- **显卡**: 支持 DirectX 12 (Feature Level 11.0+) 的显卡。
|
|
||||||
- **Visual Studio 工作负载**:
|
|
||||||
- .NET 桌面开发
|
|
||||||
- 使用 C++ 的桌面开发 (部分第三方库包装需要)
|
|
||||||
- 通用 Windows 平台开发 (用于 Windows App SDK 支持)
|
|
||||||
|
|
||||||
## 2. 项目结构 (Project Structure)
|
|
||||||
|
|
||||||
项目代码主要位于 `src` 目录下,按功能分为三个主要部分:
|
|
||||||
|
|
||||||
### 2.1 Runtime (引擎运行时)
|
|
||||||
- **Ghost.Graphics**: 图形渲染核心。包含 RHI (渲染硬件接口) 定义及其 D3D12 实现。集成了 Render Graph (渲染图) 模块用于管理复杂的渲染流水线。
|
|
||||||
- **Ghost.Entities**: 基于 Archetype (原型) 的高性能 ECS (实体组件系统) 实现。包含 `World`, `EntityManager`, `EntityQuery` 等核心组件。
|
|
||||||
- **Ghost.Engine**: 引擎基础逻辑。包含场景管理 (`Scene`)、基础组件 (如 `Hierarchy`, `LocalToWorld`) 及数学工具类。
|
|
||||||
|
|
||||||
### 2.2 Editor (编辑器)
|
|
||||||
- **Ghost.Editor**: 基于 WinUI 3 编写的桌面编辑器前端。采用 MVVM 架构。
|
|
||||||
- **Ghost.Editor.Core**: 编辑器框架层。包含资源管理 (`AssetRegistry`)、检查器服务 (`InspectorService`)、场景树管理 (`SceneGraph`) 等非 UI 逻辑。
|
|
||||||
- **Ghost.DSL**: 引擎自定义着色器语言 (GSL) 的编译器和解析器,用于处理着色器代码生成。
|
|
||||||
|
|
||||||
### 2.3 ThirdParty (第三方库)
|
|
||||||
- 包含对 FMOD (音频)、Nvtt (纹理压缩)、MeshOptimizer (模型优化) 等 C++ 库的 C# 包装。
|
|
||||||
|
|
||||||
## 3. 命名规范 (Naming Conventions)
|
|
||||||
|
|
||||||
项目严格遵守以下 C# 编程规范:
|
|
||||||
|
|
||||||
- **命名空间**: 以 `Ghost.` 开头,后跟模块名 (例如 `Ghost.Graphics.D3D12`)。
|
|
||||||
- **类与方法**: 使用 `PascalCase` (大驼峰命名法)。
|
|
||||||
- **私有字段**: 使用 `_camelCase` (下划线前缀的小驼峰命名法)。
|
|
||||||
- **接口**: 必须以 `I` 作为前缀 (例如 `IRenderDevice`)。
|
|
||||||
- **异步方法**: 必须以 `Async` 作为后缀 (例如 `LoadAssetAsync`)。
|
|
||||||
- **实现类**: 针对接口的具体实现应体现技术细节 (例如 `D3D12GraphicsEngine` 实现了 `IGraphicsEngine`)。
|
|
||||||
|
|
||||||
## 4. 架构设计与模式 (Architecture & Patterns)
|
|
||||||
|
|
||||||
### 4.1 ECS (Entity Component System)
|
|
||||||
运行时逻辑优先使用 ECS 模式以获得最佳的缓存命中率和并行性能:
|
|
||||||
- **Entity**: 纯 ID。
|
|
||||||
- **Component**: 纯数据结构 (Struct)。
|
|
||||||
- **System**: 处理特定组件组合的逻辑类。
|
|
||||||
|
|
||||||
### 4.2 RHI & Render Graph
|
|
||||||
- **RHI (Render Hardware Interface)**: 抽象了底层的图形 API。目前主要实现为 D3D12,通过 Vortice.Windows 进行绑定。
|
|
||||||
- **Render Graph**: 采用有向无环图 (DAG) 管理每一帧的渲染顺序、资源屏障 (Resource Barriers) 和资源复用,简化了 D3D12 的资源管理负担。
|
|
||||||
|
|
||||||
### 4.3 MVVM & Service Pattern (Editor)
|
|
||||||
编辑器部分遵循:
|
|
||||||
- **MVVM**: 分离 UI (`View`) 与业务逻辑 (`ViewModel`)。
|
|
||||||
- **Service/Contract**: 通过接口定义服务 (如 `IAssetRegistry`),并利用依赖注入 (Dependency Injection) 进行解耦。
|
|
||||||
|
|
||||||
### 4.4 核心设计原则 (Core Design Principles)
|
|
||||||
- **Result over Exception (结果对象胜于异常)**: 在核心运行时中,避免使用 `throw` 处理预期错误,优先返回 `Ghost.Core.Result` 结构体,以提高性能和错误流的可控性。
|
|
||||||
- **Handle over Ptr/Reference (句柄胜于指针/引用)**: 资源引用(如实体、纹理、缓冲区)应优先使用 `Handle<T>`,避免持有直接的内存地址,以确保资源管理的安全性并支持高效序列化。
|
|
||||||
|
|
||||||
## 5. 核心逻辑当前状态
|
|
||||||
|
|
||||||
- **渲染系统**: 已具备基础的 D3D12 渲染器、Render Graph 编译器及简单的 Mesh 渲染 pass。支持自定义着色器加载。
|
|
||||||
- **实体系统**: 已实现 Archetype-based ECS,支持高性能的实体查询 (`EntityQuery`) 和作业系统迭代。
|
|
||||||
- **资源管理**: 编辑器端已实现初步的资产数据库 (`AssetRegistry`),支持纹理和模型的导入流程。
|
|
||||||
- **场景管理**: 支持基础的层级结构 (`Hierarchy`) 和变换同步 (`LocalToWorld`)。
|
|
||||||
|
|
||||||
---
|
|
||||||
*注:关于后续的开发计划 (TODO) 及改进方向,我将直接通过会议或即时通讯工具进行沟通。*
|
|
||||||
@@ -5,6 +5,7 @@ using Misaki.HighPerformance.LowLevel;
|
|||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
|
using TerraFX.Interop.Gdiplus;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
using static TerraFX.Aliases.D3D_Alias;
|
using static TerraFX.Aliases.D3D_Alias;
|
||||||
@@ -984,10 +985,32 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTexture(Handle<Texture> dst, Handle<Texture> src)
|
private D3D12_TEXTURE_COPY_LOCATION GetTextureCopyLocation(SharedPtr<ID3D12Resource> texture, TextureSubresource subres)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var flatIndex = subres.MipLevel + subres.ArrayLayer * texture.Get()->GetDesc().MipLevels;
|
||||||
|
|
||||||
|
return new D3D12_TEXTURE_COPY_LOCATION
|
||||||
|
{
|
||||||
|
pResource = texture,
|
||||||
|
Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
SubresourceIndex = flatIndex
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AreTexturesIdentical(SharedPtr<ID3D12Resource> tex1, SharedPtr<ID3D12Resource> tex2)
|
||||||
|
{
|
||||||
|
var desc1 = tex1.Get()->GetDesc();
|
||||||
|
var desc2 = tex2.Get()->GetDesc();
|
||||||
|
return desc1.Width == desc2.Width
|
||||||
|
&& desc1.Height == desc2.Height
|
||||||
|
&& desc1.DepthOrArraySize == desc2.DepthOrArraySize
|
||||||
|
&& desc1.MipLevels == desc2.MipLevels
|
||||||
|
&& desc1.Format == desc2.Format
|
||||||
|
&& desc1.SampleDesc.Count == desc2.SampleDesc.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTexture(Handle<Texture> dst, TextureRegion? dstRegion, Handle<Texture> src, TextureRegion? srcRegion)
|
||||||
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
@@ -1011,8 +1034,34 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
if (dstRegion == null || srcRegion == null)
|
||||||
_commandList.Get()->CopyTextureRegion(null, 0, 0, 0, null, null);
|
{
|
||||||
|
if (!AreTexturesIdentical(pDstResource, pSrcResource))
|
||||||
|
{
|
||||||
|
RecordError(nameof(CopyTexture), Error.InvalidArgument);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_commandList.Get()->CopyResource(pDstResource, pSrcResource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dstRegionV = dstRegion.Value;
|
||||||
|
var srcRegionV = srcRegion.Value;
|
||||||
|
|
||||||
|
var dstLocation = GetTextureCopyLocation(pDstResource, dstRegionV.Subresource);
|
||||||
|
var srcLocation = GetTextureCopyLocation(pSrcResource, srcRegionV.Subresource);
|
||||||
|
var srcBoc = new D3D12_BOX
|
||||||
|
{
|
||||||
|
left = srcRegionV.X,
|
||||||
|
top = srcRegionV.Y,
|
||||||
|
front = srcRegionV.Z,
|
||||||
|
right = srcRegionV.X + srcRegionV.Width,
|
||||||
|
bottom = srcRegionV.Y + srcRegionV.Height,
|
||||||
|
back = srcRegionV.Z + srcRegionV.Depth
|
||||||
|
};
|
||||||
|
|
||||||
|
_commandList.Get()->CopyTextureRegion(&dstLocation, dstRegionV.X, dstRegionV.Y, dstRegionV.Z, &srcLocation, &srcBoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -457,6 +457,58 @@ public struct PassDepthStencilDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public struct TextureSubresource
|
||||||
|
{
|
||||||
|
public uint MipLevel
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ArrayLayer
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TextureRegion
|
||||||
|
{
|
||||||
|
public TextureSubresource Subresource
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint X
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Y
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Z
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Width
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Height
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Depth
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public struct BarrierSubresourceRange
|
public struct BarrierSubresourceRange
|
||||||
{
|
{
|
||||||
public uint IndexOrFirstMipLevel
|
public uint IndexOrFirstMipLevel
|
||||||
|
|||||||
@@ -65,8 +65,21 @@ public interface ICommandBuffer : IDisposable
|
|||||||
/// <param name="depthTarget">A handle to the texture to be used as the depth Target. Specify a invalid handle if no depth Target is required.</param>
|
/// <param name="depthTarget">A handle to the texture to be used as the depth Target. Specify a invalid handle if no depth Target is required.</param>
|
||||||
void SetRenderTargets(ReadOnlySpan<Handle<Texture>> renderTargets, Handle<Texture> depthTarget);
|
void SetRenderTargets(ReadOnlySpan<Handle<Texture>> renderTargets, Handle<Texture> depthTarget);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the specified render target to a given color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="renderTarget">A handle to the render target texture to be cleared. Must reference a valid render target.</param>
|
||||||
|
/// <param name="clearColor">The color value used to clear the render target. Specifies the RGBA components to fill the target.</param>
|
||||||
void ClearRenderTargetView(Handle<Texture> renderTarget, Color128 clearColor);
|
void ClearRenderTargetView(Handle<Texture> renderTarget, Color128 clearColor);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the specified depth-stencil view by resetting its depth and/or stencil values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="depthStencil">A handle to the depth-stencil texture to be cleared. Must reference a valid depth-stencil resource.</param>
|
||||||
|
/// <param name="inlcludeDepth">A value indicating whether the depth component should be cleared.</param>
|
||||||
|
/// <param name="includeStencil">A value indicating whether the stencil component should be cleared.</param>
|
||||||
|
/// <param name="clearDepth">The value to which the depth buffer will be set. Typically ranges from 0.0f (nearest) to 1.0f (farthest).</param>
|
||||||
|
/// <param name="clearStencil">The value to which the stencil buffer will be set. Must be a valid stencil value supported by the format.</param>
|
||||||
void ClearDepthStencilView(Handle<Texture> depthStencil, bool inlcludeDepth, bool includeStencil, float clearDepth = 1.0f, byte clearStencil = 0);
|
void ClearDepthStencilView(Handle<Texture> depthStencil, bool inlcludeDepth, bool includeStencil, float clearDepth = 1.0f, byte clearStencil = 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -201,4 +214,13 @@ public interface ICommandBuffer : IDisposable
|
|||||||
/// <param name="srcOffset">The byte Offset in the source buffer at which to begin reading. Must be zero or greater.</param>
|
/// <param name="srcOffset">The byte Offset in the source buffer at which to begin reading. Must be zero or greater.</param>
|
||||||
/// <param name="numBytes">The number of bytes to copy. If zero, copies the remaining bytes from the source buffer starting at <paramref name="srcOffset"/>.</param>
|
/// <param name="numBytes">The number of bytes to copy. If zero, copies the remaining bytes from the source buffer starting at <paramref name="srcOffset"/>.</param>
|
||||||
void CopyBuffer(Handle<GraphicsBuffer> dest, Handle<GraphicsBuffer> src, ulong destOffset = 0, ulong srcOffset = 0, ulong numBytes = 0);
|
void CopyBuffer(Handle<GraphicsBuffer> dest, Handle<GraphicsBuffer> src, ulong destOffset = 0, ulong srcOffset = 0, ulong numBytes = 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies a region of a source texture to a destination texture. The source and destination regions can be specified to copy a subset of the textures, or the entire textures if the regions are null.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dst">The handle to the destination texture where data will be written.</param>
|
||||||
|
/// <param name="dstRegion">The region of the destination texture to copy to. If null, the entire texture will be used.</param>
|
||||||
|
/// <param name="src">The handle to the source texture from which data will be read.</param>
|
||||||
|
/// <param name="srcRegion">The region of the source texture to copy from. If null, the entire texture will be used.</param>
|
||||||
|
void CopyTexture(Handle<Texture> dst, TextureRegion? dstRegion, Handle<Texture> src, TextureRegion? srcRegion);
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/Runtime/Ghost.Graphics/Contracts/IRenderPipeline.cs
Normal file
9
src/Runtime/Ghost.Graphics/Contracts/IRenderPipeline.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Ghost.Graphics.Core;
|
||||||
|
using Ghost.Graphics.RHI;
|
||||||
|
|
||||||
|
namespace Ghost.Graphics.Contracts;
|
||||||
|
|
||||||
|
public interface IRenderPipeline
|
||||||
|
{
|
||||||
|
void Render(RenderContext ctx, ReadOnlySpan<Camera> cameras);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user