-
Notifications
You must be signed in to change notification settings - Fork 512
IEffect
DirectXTK | Effects |
---|
This is the abstract interfaced implemented by all effects in DirectX Tool Kit, and is typically used as the 'base' reference. For example, ModelMeshPart defines a reference to an effect as
std::shared_ptr<IEffect> effect;
classDiagram
class IEffect{
<<Interface>>
+Apply()
+GetVertexShaderBytecode()
}
class IEffectMatrices{
<<Interface>>
+SetWorld()
+SetView()
+SetProjection()
+SetMatrices()
}
class IEffectLights{
<<Interface>>
+SetLightingEnabled()
+SetPerPixelLighting()
+SetAmbientLightColor()
+SetLightEnabled()
+SetLightDirection()
+SetLightDiffuseColor()
+SetLightSpecularColor()
+EnableDefaultLighting()
}
class IEffectFog{
<<Interface>>
+SetFogEnabled()
+SetFogStart()
+SetFogEnd()
+SetFogColor()
}
class IEffectSkinning{
<<Interface>>
+SetWeightsPerVertex()
+SetBoneTransforms()
+ResetBoneTransforms()
}
IEffect --> IEffectMatrices
IEffect --> IEffectLights
IEffect --> IEffectFog
IEffect --> IEffectSkinning
The Apply method is used to set up a device context for drawing with the effect. This includes setting up the appropriate vertex and pixel shaders (and potentially other shader stages as well), and updating and setting the required constant buffer(s) consumed by these shaders.
The caller is assumed to handle setting the appropriate input layout, vertex and index buffer, primitive topology, blend state, depth-stencil state, and rasterizer state. Texturing effects will also set the shader resources needed for the texturing modes it supports, but assumes the caller has set up the appropriate samplers.
GeometricPrimitive and Model set the various state settings to reasonable defaults as part of their prepare and/or drawing methods. PrimitiveBatch only sets vertex buffer, index buffer, primitive topology leaving the rest of the device state vector up to the caller.
m_states = std::make_unique<CommonStates>(device);
...
deviceContext->OMSetBlendState(m_states->Opaque(), nullptr, 0xFFFFFFFF);
deviceContext->OMSetDepthStencilState(m_states->DepthDefault(), 0);
deviceContext->RSSetState( m_states->CullCounterClockwise() );
auto samplerState = m_states->LinearClamp();
deviceContext->PSSetSamplers(0, 1, &samplerState);
...
effect->Apply( devicecontext );
deviceContext->IASetInputLayout(inputLayout);
auto vertexBuffer = mVertexBuffer.Get();
UINT vertexStride = sizeof(VertexType);
UINT vertexOffset = 0;
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer,
&vertexStride, &vertexOffset);
deviceContext->IASetIndexBuffer(mIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
deviceContext->DrawIndexed(mIndexCount, 0, 0);
Direct3D 11 requires that an input layout is used that matches the signature of the vertex shader used for rendering. Since effect instances are dynamic and use many different shaders depending on various settings, this requires that the caller have access to the correct vertex shader code to create the input layout. The GetVertexShaderBytecode method handles this request.
// Setup effect and parameters
...
void const* shaderByteCode;
size_t byteCodeLength;
effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);
device->CreateInputLayout(VertexPositionNormalTexture::InputElements,
VertexPositionNormalTexture::InputElementCount,
shaderByteCode, byteCodeLength,
pInputLayout);
Some dynamic state changes in an effect only impact contstant buffer content, which is easily updated. Other state changes can result in a different shader permutation, in which case the the associated input layouts may no longer bind (you'll get a Direct3D 11 error at runtime if this occurs).
For the built-in effects, the trigger for needing to create a new layout would be:
- Enabling or disabling lighting (which requires a vertex normal)
- Enabling or disabling per vertex color (which requires a vertex color value)
- Enabling or disabling textures (which requires vertex texture coordinates)
- Changing effect class (BasicEffect <-> SkinnedEffect or DGSLEffect)
All built-in effects require the SV_Position
semantic.
This effect requires TEXCOORD0
, and COLOR
if per-vertex colors are enabled.
This effect requires NORMAL
if lighting is enabled, COLOR
if per-vertex colors are enabled, and TEXCOORD0
if texturing is enabled.
This effect requires NORMAL
, TANGENT
, and TEXCOORD0
. If enableSkinning is true, it also requires BLENDINDICES
and BLENDWEIGHT
.
This effect requires TEXCOORD0
and TEXCOORD1
.
This effect requires NORMAL
and TEXCOORD0
.
This effect requires NORMAL
, TEXCOORD0
and TANGENT
. If per-vertex colors are enabled, it also requires COLOR
.
This effect requires NORMAL
, TEXCOORD0
, BLENDINDICES
and BLENDWEIGHT
.
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Windows 8.1
- Windows 7 Service Pack 1
- Xbox One
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20