Diligent Core 是一种现代跨平台低级图形 API,它构成了 Diligent Engine 的基础。该模块实现 Direct3D11、Direct3D12、OpenGL、OpenGLES 和 Vulkan 渲染后端(商业客户可使用 Metal 实现)以及基本的特定于平台的实用程序。它是独立的,可以自己构建。请参阅主存储库,了解有关支持的平台和功能、构建说明等的信息。
平台 | 构建状态 |
---|---|
Win32 | |
通用Windows | |
Linux | |
安卓 | |
苹果系统 | |
iOS系统 | |
电视操作系统 | |
恩脚本 |
克隆存储库
API基础知识
管道资源布局
Win32
通用Windows平台
Linux
苹果系统
安卓
iOS系统
恩脚本
摧毁发动机
初始化引擎
创建资源
创建着色器
初始化管道状态
绑定着色器资源
设置管道状态并调用Draw命令
低级 API 互操作性
NuGet 包构建说明
执照
贡献
发布历史
要获取存储库和所有子模块,请使用以下命令:
git clone --recursive https://github.com/DiligentGraphics/DiligentCore.git
要构建模块,请参阅主存储库中的构建说明。
在使用引擎提供的任何功能之前,您需要创建渲染设备、直接上下文和交换链。
在Win32平台上,您可以创建OpenGL、Direct3D11、Direct3D12或Vulkan设备,如下所示:
无效InitializeDiligentEngine(HWND NativeWindowHandle) { SwapChainDesc SCDesc;// RefCntAutoPtr<IRenderDevice> m_pDevice;// RefCntAutoPtr<IDeviceContext> m_pImmediateContext;// RefCntAutoPtr<ISwapChain> m_pSwapChain;switch (m_DeviceType) {案例RENDER_DEVICE_TYPE_D3D11: { EngineD3D11CreateInfo EngineCI; # if ENGINE_DLL// 加载dll并导入GetEngineFactoryD3D11()函数auto* GetEngineFactoryD3D11 = LoadGraphicsEngineD3D11(); # endifauto* pFactoryD3D11 = GetEngineFactoryD3D11(); pFactoryD3D11->CreateDeviceAndContextsD3D11(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow 窗口{hWnd}; pFactoryD3D11->CreateSwapChainD3D11(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}, 窗口, &m_pSwapChain); }break;case RENDER_DEVICE_TYPE_D3D12: { # if ENGINE_DLL//加载dll并导入GetEngineFactoryD3D12()函数auto GetEngineFactoryD3D12 = LoadGraphicsEngineD3D12(); # endifEngineD3D12CreateInfo EngineCI;auto* pFactoryD3D12 = GetEngineFactoryD3D12(); pFactoryD3D12->CreateDeviceAndContextsD3D12(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow 窗口{hWnd}; pFactoryD3D12->CreateSwapChainD3D12(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}, 窗口, &m_pSwapChain); }break;case RENDER_DEVICE_TYPE_GL: { # if EXPLICITLY_LOAD_ENGINE_GL_DLL//加载dll并导入GetEngineFactoryOpenGL()函数auto GetEngineFactoryOpenGL = LoadGraphicsEngineOpenGL(); # endifauto* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI; EngineCI.Window.hWnd = hWnd; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pImmediateContext, SCDesc, &m_pSwapChain); }break;case RENDER_DEVICE_TYPE_VULKAN: { # if EXPLICITLY_LOAD_ENGINE_VK_DLL//加载dll并导入GetEngineFactoryVk()函数auto GetEngineFactoryVk = LoadGraphicsEngineVk(); # endifEngineVkCreateInfo EngineCI;auto* pFactoryVk = GetEngineFactoryVk(); pFactoryVk->CreateDeviceAndContextsVk(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow 窗口{hWnd}; pFactoryVk->CreateSwapChainVk(m_pDevice, m_pImmediateContext, SCDesc, Window, &m_pSwapChain); }中断;默认: std::cerr << "未知设备类型"; } }
在 Windows 上,引擎可以静态链接到应用程序或构建为单独的 DLL。在第一种情况下,可以直接调用工厂函数GetEngineFactoryOpenGL()
、 GetEngineFactoryD3D11()
、 GetEngineFactoryD3D12()
和GetEngineFactoryVk()
。在第二种情况下,您需要使用LoadGraphicsEngineOpenGL()
、 LoadGraphicsEngineD3D11()
、 LoadGraphicsEngineD3D12()
或LoadGraphicsEngineVk()
函数将 DLL 加载到进程的地址空间中。每个函数加载适当的动态库并导入初始化引擎所需的函数。您需要包含以下标头:
#include“EngineFactoryD3D11.h”#include“EngineFactoryD3D12.h”#include“EngineFactoryOpenGL.h”#include“EngineFactoryVk.h”
您还需要将以下目录添加到包含搜索路径中:
DiligentCore/Graphics/GraphicsEngineD3D11/interface
DiligentCore/Graphics/GraphicsEngineD3D12/interface
DiligentCore/Graphics/GraphicsEngineOpenGL/interface
DiligentCore/Graphics/GraphicsEngineVulkan/interface
作为替代方案,您可以仅添加根文件夹的路径,然后使用相对于它的包含路径。
启用Diligent
命名空间:
使用命名空间 Diligent;
IEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
、 IEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
和IEngineFactoryVk::CreateDeviceAndContextsVk()
函数还可以创建指定数量的立即上下文和延迟上下文,这些上下文可用于异步渲染和多线程命令记录。上下文只能在引擎初始化期间创建。该函数填充指向上下文的指针数组,其中首先是立即上下文,然后是所有延迟上下文。
有关更多详细信息,请查看Tutorial00_HelloWin32.cpp 文件。
在通用Windows平台上,您可以创建Direct3D11或Direct3D12设备。初始化的执行方式与 Win32 平台上相同。区别在于,您首先通过调用IEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
或IEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
创建渲染设备和设备上下文。稍后通过调用IEngineFactoryD3D11::CreateSwapChainD3D11()
或IEngineFactoryD3D12::CreateSwapChainD3D12()
创建交换链。请查看 SampleAppUWP.cpp 文件以了解更多详细信息。
在Linux平台上,该引擎支持OpenGL和Vulkan后端。 Linux 上 GL 上下文的初始化与窗口创建紧密结合。因此,Diligent Engine 不会初始化上下文,而是附加到应用程序初始化的上下文。 Linux 上的引擎初始化示例可以在Tutorial00_HelloLinux.cpp 中找到。
在 MacOS 上,Diligent Engine 支持 OpenGL、Vulkan 和 Metal 后端。 MacOS 上 GL 上下文的初始化由应用程序执行,引擎附加到应用程序创建的上下文;详细信息请参见 GLView.mm。 Vulkan 后端的初始化与其他平台类似。请参阅 MetalView.mm。
在 Android 上,您可以创建 OpenGLES 或 Vulkan 设备。以下代码片段显示了一个示例:
自动* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI; EngineCI.Window.pAWindow = NativeWindowHandle; pFactoryOpenGL->CreateDeviceAndSwapChainGL( EngineCI、&m_pDevice、&m_pContext、SCDesc、&m_pSwapChain);
如果引擎构建为动态库,则需要由本机活动加载该库。以下代码显示了一种可能的方法:
静态{尝试{System.loadLibrary(“GraphicsEngineOpenGL”); } catch (UnsatisfiedLinkError e) {Log.e("native-activity", "无法加载 GraphicsEngineOpenGL 库.n" + e); } }
iOS 实现支持 OpenGLES、Vulkan 和 Metal 后端。 iOS上GL上下文的初始化由应用程序执行,引擎附加到应用程序初始化的上下文;详细信息请参见 EAGLView.mm。
在 Emscripten 上,您可以创建 OpenGLES 设备。以下代码片段显示了一个示例:
//需要将画布的id传递给NativeWindowauto* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI = {}; EngineCI.Window = NativeWindow{"#canvas"}; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pContext, SCDesc, &m_pSwapChain);
如果您在现有上下文中使用 SDL 或 GLFW,则可以提供 null 作为本机窗口句柄: EngineCI.Window = NativeWindow{nullptr}
引擎执行自动引用计数,并在释放对引擎对象的最后一个引用时关闭。
设备资源由渲染设备创建。两种主要资源类型是缓冲区(代表线性内存)和纹理(使用针对快速过滤而优化的内存布局)。要创建缓冲区,您需要填充BufferDesc
结构并调用IRenderDevice::CreateBuffer()
。以下代码创建一个统一(恒定)缓冲区:
缓冲区描述 缓冲区描述; BufferDesc.Name = "统一缓冲区"; BuffDesc.BindFlags = BIND_UNIFORM_BUFFER; BuffDesc.Usage = USAGE_DYNAMIC; BuffDesc.uiSizeInBytes = sizeof(ShaderConstants); BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE; m_pDevice->CreateBuffer(BuffDesc, nullptr, &m_pConstantBuffer);
类似地,要创建纹理,请填充TextureDesc
结构并调用IRenderDevice::CreateTexture()
,如下例所示:
纹理描述 纹理描述; TexDesc.Name = "我的纹理 2D"; TexDesc.Type = TEXTURE_TYPE_2D; TexDesc.Width = 1024; TexDesc.Height = 1024; TexDesc.Format = TEX_FORMAT_RGBA8_UNORM; TexDesc.Usage = USAGE_DEFAULT; TexDesc.BindFlags = BIND_SHADER_RESOURCE | TexDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET | BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS; TexDesc.Name = "示例 2D 纹理"; m_pRenderDevice->CreateTexture(TexDesc, nullptr, &m_pTestTex);
只有一个函数CreateTexture()
能够创建所有类型的纹理。类型、格式、数组大小和所有其他参数均由TextureDesc
结构的成员指定。
对于纹理创建期间指定的每个绑定标志,纹理对象都会创建一个默认视图。默认着色器资源视图引用整个纹理,默认渲染目标和深度模板视图引用最详细的 mip 级别中的所有数组切片,无序访问视图引用整个纹理。要从纹理获取默认视图,请使用ITexture::GetDefaultView()
函数。请注意,此函数不会增加返回接口的引用计数器。您可以使用ITexture::CreateView()
创建其他纹理视图。使用IBuffer::CreateView()
创建缓冲区的附加视图。
要创建着色器,请填充ShaderCreateInfo
结构:
ShaderCreateInfo ShaderCI;
创建着色器的方法有3种。第一种方法是通过ShaderCreateInfo::Source
成员提供指向着色器源代码的指针。第二种方法是提供文件名。第三种方法是通过ShaderCreateInfo::ByteCode
成员提供指向已编译字节码的指针。图形引擎与平台完全解耦。由于主机文件系统依赖于平台,因此该结构公开ShaderCreateInfo::pShaderSourceStreamFactory
成员,旨在为引擎提供对文件系统的访问权限。如果提供了源文件名,则还必须提供指向着色器源流工厂的非空指针。如果着色器源包含任何#include
指令,源流工厂也将用于加载这些文件。该引擎为每个受支持的平台提供默认实现,这在大多数情况下应该足够了。不过,您可以定义自己的实现。
一个重要的成员是ShaderCreateInfo::SourceLanguage
。以下是该成员的有效值:
SHADER_SOURCE_LANGUAGE_DEFAULT
- 着色器源格式与底层图形 API 匹配:用于 D3D11 或 D3D12 模式的 HLSL,以及用于 OpenGL、OpenGLES 和 Vulkan 模式的 GLSL。
SHADER_SOURCE_LANGUAGE_HLSL
- 着色器源采用 HLSL。对于 OpenGL 和 OpenGLES 模式,源代码将转换为 GLSL。在Vulkan后端,代码将直接编译为SPIRV。
SHADER_SOURCE_LANGUAGE_GLSL
- 着色器源采用 GLSL。
SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM
- 着色器源语言是 GLSL,应逐字编译。
SHADER_SOURCE_LANGUAGE_MSL
- 源语言是金属着色语言。
ShaderCreateInfo
结构的其他成员定义着色器,包括搜索目录、着色器宏定义、着色器入口点和其他参数。
ShaderMacroHelper 宏; Macros.AddShaderMacro("USE_SHADOWS", 1); Macros.AddShaderMacro("NUM_SHADOW_SAMPLES", 4); 宏.Finalize(); ShaderCI.Macros = 宏;
当一切准备就绪后,调用IRenderDevice::CreateShader()
创建着色器对象:
ShaderCreateInfo ShaderCI; ShaderCI.Desc.Name = "MyPixelShader"; ShaderCI.FilePath = "MyShaderFile.fx"; ShaderCI.EntryPoint = "MyPixelShader"; ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;const auto* SearchDirectories =“着色器;着色器inc;”; RefCntAutoPtr<IShaderSourceInputStreamFactory> pShaderSourceFactory; m_pEngineFactory->CreateDefaultShaderSourceStreamFactory(SearchDirectories, &pShaderSourceFactory); ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory; RefCntAutoPtr<IShader> pShader; m_pDevice->CreateShader(ShaderCI, &pShader);
Diligent Engine遵循Direct3D12/Vulkan风格来配置图形/计算管道。一个整体管道状态对象 (PSO) 包含所有必需的状态(所有着色器阶段、输入布局描述、深度模板、光栅器和混合状态描述等)。要创建图形管道状态对象,请定义GraphicsPipelineStateCreateInfo
结构的实例:
GraphicsPipelineStateCreateInfo PSOCreateInfo; PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; PSODesc.Name = "我的管道状态";
描述管道细节,例如渲染目标的数量和格式以及深度模板格式:
// 这是一个图形管道PSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS; PSOCreateInfo.GraphicsPipeline.NumRenderTargets = 1; PSOCreateInfo.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; PSOCreateInfo.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
初始化深度模板状态描述DepthStencilStateDesc
。请注意,构造函数使用默认值初始化成员,您只能设置与默认值不同的成员。
// 初始化深度模板状态DepthStencilStateDesc& DepthStencilDesc = PSOCreateInfo.GraphicsPipeline.DepthStencilDesc; DepthStencilDesc.DepthEnable = true; DepthStencilDesc.DepthWriteEnable = true;
初始化混合状态描述BlendStateDesc
:
// 初始化混合状态BlendStateDesc& BSDesc = PSOCreateInfo.GraphicsPipeline.BlendDesc; BSDesc.IndependentBlendEnable = False;auto &RT0 = BSDesc.RenderTargets[0]; RT0.BlendEnable = True; RT0.RenderTargetWriteMask = COLOR_MASK_ALL; RT0.SrcBlend = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlend = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOp = BLEND_OPERATION_ADD; RT0.SrcBlendAlpha = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlendAlpha = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOpAlpha = BLEND_OPERATION_ADD;
初始化光栅器状态描述RasterizerStateDesc
:
// 初始化光栅化器 stateRasterizerStateDesc& RasterizerDesc = PSOCreateInfo.GraphicsPipeline.RasterizerDesc; RasterizerDesc.FillMode = FILL_MODE_SOLID; RasterizerDesc.CullMode = CULL_MODE_NONE; RasterizerDesc.FrontCounterClockwise = True; RasterizerDesc.ScissorEnable = True; RasterizerDesc.AntialiasedLineEnable = False;
初始化输入布局描述InputLayoutDesc
:
// 定义输入布局InputLayoutDesc& Layout = PSOCreateInfo.GraphicsPipeline.InputLayout; 布局元素 布局元素[] = {LayoutElement( 0, 0, 3, VT_FLOAT32, 假 ),LayoutElement( 1, 0, 4, VT_UINT8, True ),LayoutElement( 2, 0, 2, VT_FLOAT32, 假 ), }; Layout.LayoutElements = LayoutElems; Layout.NumElements = _countof(LayoutElems);
定义基元拓扑并设置着色器指针:
// 定义着色器和图元拓扑PSOCreateInfo.GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; PSOCreateInfo.pVS = m_pVS; PSOCreateInfo.pPS = m_pPS;
管道资源布局通知引擎应用程序将如何使用不同的着色器资源变量。为了允许根据资源绑定更改的预期频率对资源进行分组,Diligent Engine 引入了着色器变量的分类:
静态变量( SHADER_RESOURCE_VARIABLE_TYPE_STATIC
) 是预计仅设置一次的变量。一旦资源绑定到变量,它们就不能更改。此类变量旨在保存全局常量,例如相机属性或全局灯光属性常量缓冲区。请注意,资源绑定可能不会更改,而资源的内容允许根据其使用情况进行更改。
可变变量( SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE
) 定义预期按材质频率更改的资源。示例可能包括漫反射纹理、法线贴图等。同样,对资源内容的更新与绑定更改正交。
动态变量( SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC
) 预计会频繁且随机地更改。
要定义变量类型,请准备ShaderResourceVariableDesc
结构数组并初始化PSODesc.ResourceLayout.Variables
和PSODesc.ResourceLayout.NumVariables
成员。 PSODesc.ResourceLayout.DefaultVariableType
还可用于设置未提供变量名称时将使用的类型。
ShaderResourceVariableDesc ShaderVars[] = { {SHADER_TYPE_PIXEL,“g_StaticTexture”,SHADER_RESOURCE_VARIABLE_TYPE_STATIC}, {SHADER_TYPE_PIXEL,“g_MutableTexture”,SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}, {SHADER_TYPE_PIXEL、“g_DynamicTexture”、SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; PSODesc.ResourceLayout.Variables = ShaderVars; PSODesc.ResourceLayout.NumVariables = _countof(ShaderVars); PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC;
创建管道状态时,可以为纹理永久分配不可变的采样器。如果将不可变采样器分配给纹理,则将始终使用该采样器,而不是在纹理着色器资源视图中初始化的采样器。要定义不可变采样器,请准备ImmutableSamplerDesc
结构数组并初始化PSODesc.ResourceLayout.ImmutableSamplers
和PSODesc.ResourceLayout.NumImmutableSamplers
成员。请注意,不可变采样器可以分配给任何类型的纹理变量,不一定是静态的,以便可以在运行时更改纹理绑定,而采样器将保持不可变。强烈建议尽可能使用不可变采样器。
不可变采样器描述 ImtblSampler; ImtblSampler.ShaderStages = SHADER_TYPE_PIXEL; ImtblSampler.Desc.MinFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MagFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MipFilter = FILTER_TYPE_LINEAR; ImtblSampler.TextureName = "g_MutableTexture"; PSODesc.ResourceLayout.NumImmutableSamplers = 1; PSODesc.ResourceLayout.ImmutableSamplers = &ImtblSampler;
本文档提供了有关使用纹理采样器的详细信息。
当 PSO 描述结构的所有必填字段设置完毕后,调用IRenderDevice::CreateGraphicsPipelineState()
创建 PSO 对象:
m_pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &m_pPSO);
如上所述,Diligent Engine 中的着色器资源绑定基于将变量分组为 3 个不同组(静态、可变和动态)。静态变量是预期仅设置一次的变量。一旦资源绑定到变量,它们就不能更改。此类变量旨在保存全局常量,例如相机属性或全局光属性常量缓冲区。它们直接绑定到管道状态对象:
m_pPSO->GetStaticShaderVariable(SHADER_TYPE_PIXEL, "g_tex2DShadowMap")->Set(pShadowMapSRV);
可变变量和动态变量通过名为 Shader Resource Binding (SRB) 的新对象进行绑定,该对象是由管道状态 ( IPipelineState::CreateShaderResourceBinding()
)或高级用例中的管道资源签名创建的:
m_pPSO->CreateShaderResourceBinding(&m_pSRB, true);
第二个参数告诉系统初始化 SRB 对象中引用 PSO 中静态变量的内部结构。
然后通过 SRB 对象绑定动态和可变资源:
m_pSRB->GetVariable(SHADER_TYPE_PIXEL, "tex2DDiffuse")->Set(pDiffuseTexSRV); m_pSRB->GetVariable(SHADER_TYPE_VERTEX, "cbRandomAttribs")->Set(pRandomAttrsCB);
可变资源和动态资源之间的区别在于,可变资源只能为着色器资源绑定的每个实例设置一次。动态资源可以设置多次。正确设置变量类型很重要,因为这会影响性能。静态变量和可变变量效率更高。动态变量更昂贵并且会引入一些运行时开销。
绑定着色器资源的另一种方法是创建一个IResourceMapping
接口,将资源文字名称映射到实际资源:
资源映射条目条目[] = { {“g_Texture”,pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)} }; ResourceMappingCreateInfo ResMappingCI; ResMappingCI.pEntries = 条目; ResMappingCI.NumEntries = _countof(Entries); RefCntAutoPtr<IResourceMapping> pResMapping; pRenderDevice->CreateResourceMapping(ResMappingCI, &pResMapping);
然后,资源映射可用于绑定管道状态中的所有静态资源( IPipelineState::BindStaticResources()
):
m_pPSO->BindStaticResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
或着色器资源绑定中的所有可变和动态资源 ( IShaderResourceBinding::BindResources()
):
m_pSRB->BindResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
所有BindResources()
函数的最后一个参数定义了如何解析资源:
BIND_SHADER_RESOURCES_UPDATE_STATIC
- 指示要更新静态变量绑定。
BIND_SHADER_RESOURCES_UPDATE_MUTABLE
- 指示要更新可变变量绑定。
BIND_SHADER_RESOURCES_UPDATE_DYNAMIC
- 指示要更新动态变量绑定。
BIND_SHADER_RESOURCES_UPDATE_ALL
- 指示要更新所有变量类型(静态、可变和动态)。请注意,如果未设置BIND_SHADER_RESOURCES_UPDATE_STATIC
、 BIND_SHADER_RESOURCES_UPDATE_MUTABLE
和BIND_SHADER_RESOURCES_UPDATE_DYNAMIC
标志,则所有变量类型都会更新,就像指定了BIND_SHADER_RESOURCES_UPDATE_ALL
一样。
BIND_SHADER_RESOURCES_KEEP_EXISTING
- 如果指定此标志,则仅更新未解析的绑定。所有现有的绑定将保留其原始值。如果未指定此标志,则如果映射包含相应的资源,则每个着色器变量都将被更新。
BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED
- 如果指定此标志,则预计在调用后解析所有着色器绑定。如果不是这种情况,则会报告错误。
可以使用不同的资源映射多次调用BindResources()
来绑定资源。但是,建议使用一个大型资源映射,因为映射的大小不会影响元素搜索时间。
引擎执行运行时检查以验证是否绑定了正确的资源。例如,如果您尝试将常量缓冲区绑定到着色器资源视图变量,则会将错误输出到调试控制台。
在调用任何绘制命令之前,所有必需的顶点和索引缓冲区以及管道状态都应绑定到设备上下文:
// 在发出任何绘制命令之前设置渲染目标。 auto* pRTV = m_pSwapChain->GetCurrentBackBufferRTV();auto* pDSV = m_pSwapChain->GetDepthBufferDSV(); m_pContext->SetRenderTargets(1, &pRTV, pDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// 清除渲染目标和深度模板常量 float Zero[4] = {0, 0, 0, 0}; m_pContext->ClearRenderTarget(pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->ClearDepthStencil(pDSV, CLEAR_DEPTH_FLAG, 1.f, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// 设置顶点和索引缓冲区IBuffer* buffer[] = {m_pVertexBuffer}; Uint32 偏移量[] = {0}; m_pContext->SetVertexBuffers(0, 1, 缓冲区, 偏移量, SET_VERTEX_BUFFERS_FLAG_RESET, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetIndexBuffer(m_pIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetPipelineState(m_pPSO);
所有可能需要执行资源状态转换的方法都采用RESOURCE_STATE_TRANSITION_MODE
枚举作为参数。枚举定义了以下模式:
RESOURCE_STATE_TRANSITION_MODE_NONE
- 不执行资源状态转换。
RESOURCE_STATE_TRANSITION_MODE_TRANSITION
- 将资源转换到命令所需的状态。
RESOURCE_STATE_TRANSITION_MODE_VERIFY
- 不转换,但验证状态是否正确。
最后一步是将着色器资源提交到设备上下文。这是通过IDeviceContext::CommitShaderResources()
方法完成的:
m_pContext->CommitShaderResources(m_pSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
如果未调用该方法,引擎将检测到资源未提交并输出调试消息。请注意,最后一个参数告诉系统将资源转换到正确的状态。如果未指定此标志,则必须通过调用IDeviceContext::TransitionShaderResources()
将资源显式转换为所需状态:
m_pContext->TransitionShaderResources(m_pPSO, m_pSRB);
请注意,该方法需要指向创建着色器资源绑定的管道状态的指针。
当所有必需的状态和资源都绑定后, IDeviceContext::DrawIndexed()
可用于执行绘制命令,或者IDeviceContext::DispatchCompute()
可用于执行计算命令。请注意,对于绘制命令,必须绑定图形管道,对于调度命令,必须绑定计算管道。 DrawIndexed()
将DrawIndexedAttribs
结构作为参数,例如:
DrawIndexedAttribs attrs; attrs.IndexType = VT_UINT16; attrs.NumIndices = 36; attrs.Flags = DRAW_FLAG_VERIFY_STATES; pContext->DrawIndexed(attrs);
DRAW_FLAG_VERIFY_STATES
标志指示引擎验证绘制命令使用的顶点和索引缓冲区是否已转换到正确的状态。
DispatchCompute()
采用定义计算网格维度的DispatchComputeAttribs
结构:
m_pContext->SetPipelineState(m_pComputePSO); m_pContext->CommitShaderResources(m_pComputeSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); DispatchComputeAttribs DispatchAttrs{64, 64, 8}; m_pContext->DispatchCompute(DispatchAttrs);
您可以通过学习示例和教程来了解有关引擎 API 的更多信息。
Diligent Engine 广泛支持与底层低级 API 的互操作性。该引擎可以通过附加到现有的 D3D11/D3D12 设备或 OpenGL/GLES 上下文来初始化,并提供对底层本机 API 对象的访问。请参阅以下页面了解更多信息:
Direct3D11 互操作性
Direct3D12 互操作性
OpenGL/GLES 互操作性
Vulkan 互操作性
请按照以下步骤构建 NuGet 包:
安装所需的Python包
python -m pip install -r ./BuildTools/.NET/requirements.txt
运行 NuGet 包构建脚本,例如:
python ./BuildTools/.NET/dotnet-build-package.py -c Debug -d ./
争论 | 描述 | 必需的 |
---|---|---|
-c ( configuration ) | 本机动态库构建配置(例如调试、发布等) | 是的 |
-d ( root-dir ) | DiligentCore根目录路径 | 是的 |
-s ( settings ) | 设置文件的路径 | 不 |
dotnet-tests | 指示是否运行 .NET 测试的标志 | 不 |
dotnet-publish | 指示是否将包发布到 NuGet Gallery 的标志 | 不 |
free-memory | 如果在构建过程中遇到内存不足的情况,请使用此参数 | 不 |
您可以使用设置文件覆盖默认设置(检查dotnet-build-package.py
中的default_settings
字典)
请参阅 Apache 2.0 许可证。
该项目有一些第三方依赖项,每个依赖项都可能具有独立的许可:
Vulkan-Headers:Vulkan 头文件和 API 注册表(Apache 许可证 2.0)。
SPIRV-Cross:SPIRV 解析和交叉编译工具(Apache 许可证 2.0)。
SPIRV-Heads:SPIRV 头文件(类似 Khronos MIT 的许可证)。
SPIRV-Tools:SPIRV 优化和验证工具(Apache 许可证 2.0)。
glslang:适用于 GLSL、ESSL 和 HLSL 的 Khronos 参考编译器和验证器(3 条款 BSD 许可证、2 条款 BSD 许可证、MIT、Apache 许可证 2.0)。
glew:OpenGL 扩展牧马人库(Mesa 3-D 图形库,类似 Khronos MIT 的许可证)。
volk:Vulkan API 的元加载器(类似 Arseny Kapoulkine MIT 的许可证)。
stb:用于 C/C++ 的 stb 单文件公共域库(MIT 许可证或公共域)。
googletest:Google 测试和模拟框架(BSD 3 条款“新”或“修订”许可证)。
DirectXShaderCompiler:基于 LLVM/Clang 的 DirectX Shader 编译器(LLVM 发行许可证)。
DXBCChecksum:AMD 开发工具团队 (MIT lincesne) 的 DXBC 校验和计算算法。
xxHash:极快的非加密哈希算法(2-Clause BSD 许可证)。
要贡献您的代码,请向此存储库提交拉取请求。 Diligent Engine根据 Apache 2.0 许可证分发,保证DiligentCore存储库中的内容不存在知识产权负担。在向此存储库提交任何内容时,您将根据相同的条款对该内容进行许可,并且您同意该内容不存在任何知识产权声明,并且您有权根据这些条款对其进行许可。
Diligent Engine 使用 clang-format 来确保整个代码库中源代码风格的一致性。 CI 对每个提交和拉取请求都会验证格式,如果发现任何代码格式问题,构建将失败。请参阅此页面,了解如何设置 clang-format 和自动代码格式化的说明。
查看发布历史记录
diligentgraphics.com