Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added D3D 1.2 - Texture tutorial #1966

Merged
merged 4 commits into from
Mar 3, 2024

Conversation

otac0n
Copy link
Contributor

@otac0n otac0n commented Mar 2, 2024

Summary of the PR

Hopefully saves a lot of trundling through D3D documentation.

Related issues, Discord discussions, or proposals

I plan to add more tutorials soon. I do have working examples of Abstractions here, which would be the next step.
I do need to add a license to my repo first. (I'm targeting MIT)

https://github.com/otac0n/RenderLoop/tree/master/RenderLoop.SilkRenderer/DX

Further Comments

Please suggest if I need to use an alternative to System.Drawing.Bitmap, as it is Windows only. (I think this is OK for a Direct3D tutorial?)

@otac0n otac0n requested a review from a team as a code owner March 2, 2024 21:37
@Beyley
Copy link
Contributor

Beyley commented Mar 2, 2024

Ideally you would use SixLabors.ImageSharp or stbimagesharp for image loading. We support D3D11 natively under linux through DXVK-native (eg. not through wine)
Shouldnt be much of a change to move over

@Perksey
Copy link
Member

Perksey commented Mar 2, 2024

(preferably ImageSharp as we use that more than any of the other ones, and provides a nice user experience)

@otac0n
Copy link
Contributor Author

otac0n commented Mar 2, 2024

Differences to Tutorial 1.2:

    //  X      Y      Z                                         <>     //  X      Y      Z, U  V
     0.5f,  0.5f,  0.0f,                                                0.5f,  0.5f,  0.0f, 1, 1,
     0.5f, -0.5f,  0.0f,                                                0.5f, -0.5f,  0.0f, 1, 0,
    -0.5f, -0.5f,  0.0f,                                               -0.5f, -0.5f,  0.0f, 0, 0,
    -0.5f,  0.5f,  0.5f,                                               -0.5f,  0.5f,  0.5f, 0, 1,
-------------------------------------------------------------------------------------------------------------------------------------------
var vertexStride = 3U * sizeof(float);                          <> var vertexStride = 3U * sizeof(float) + 2U * sizeof(float);
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+ Texture2D silk_logo: register(t0);

                                                                   SamplerState LogoSampler: register(s0);

-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+     float2 tex_coord : TEXCOORD0;
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+     float2 tex_coord : TEXCOORD0;
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+     output.tex_coord = input.tex_coord;
-------------------------------------------------------------------------------------------------------------------------------------------
    return float4( 1.0, 0.5, 0.2, 1.0 );                        <>     return silk_logo.Sample(LogoSampler, input.tex_coord);
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+ ComPtr<ID3D11Texture2D> texture = default;
                                                                   ComPtr<ID3D11SamplerState> textureSampler = default;
                                                                   ComPtr<ID3D11ShaderResourceView> textureResourceView = default;
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+ textureResourceView.Dispose();
                                                                   textureSampler.Dispose();
                                                                   texture.Dispose();
-------------------------------------------------------------------------------------------------------------------------------------------
    fixed (float* vertexData = vertices)                        <>     fixed (void* vertexData = vertices)
-------------------------------------------------------------------------------------------------------------------------------------------
    fixed (byte* name = SilkMarshal.StringToMemory("POS"))      <>     fixed (byte* pos = SilkMarshal.StringToMemory("POS"))
                                                                       fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD"))
-------------------------------------------------------------------------------------------------------------------------------------------
        var inputElement = new InputElementDesc                 <>         var inputElements = new InputElementDesc[]
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                <>             new()
                                                                               {
            SemanticName = name,                                                   SemanticName = pos,
            SemanticIndex = 0,                                                     SemanticIndex = 0,
            Format = Format.FormatR32G32B32Float,                                  Format = Format.FormatR32G32B32Float,
            InputSlot = 0,                                                         InputSlot = 0,
            AlignedByteOffset = 0,                                                 AlignedByteOffset = 0,
            InputSlotClass = InputClassification.PerVertexData,                    InputSlotClass = InputClassification.PerVertexData,
            InstanceDataStepRate = 0                                               InstanceDataStepRate = 0
                                                                               },
                                                                               new()
                                                                               {
                                                                                   SemanticName = texcoord,
                                                                                   SemanticIndex = 0, // TEXCOORD0
                                                                                   Format = Format.FormatR32G32Float,
                                                                                   InputSlot = 0,
                                                                                   AlignedByteOffset = uint.MaxValue, // AUTO
                                                                                   InputSlotClass = InputClassification.PerVertexData,
                                                                                   InstanceDataStepRate = 0
                                                                               }
-------------------------------------------------------------------------------------------------------------------------------------------
                in inputElement,                                <>                 in inputElements[0],
                1,                                                                 (uint) inputElements.Length,
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+
                                                                       // Load the image using any applicable library.
                                                                       using var imgBmp = new System.Drawing.Bitmap("silk.png");

                                                                       var textureDesc = new Texture2DDesc
                                                                       {
                                                                           Width = (uint) imgBmp.Width,
                                                                           Height = (uint) imgBmp.Height,
                                                                           Format = Format.FormatB8G8R8A8Unorm,
                                                                           MipLevels = 1,
                                                                           BindFlags = (uint) BindFlag.ShaderResource,
                                                                           Usage = Usage.Default,
                                                                           CPUAccessFlags = 0,
                                                                           MiscFlags = (uint) ResourceMiscFlag.None,
                                                                           SampleDesc = new SampleDesc(1, 0),
                                                                           ArraySize = 1
                                                                       };

                                                                       var bmp = imgBmp.LockBits
                                                                       (
                                                                           new System.Drawing.Rectangle(0, 0, imgBmp.Width, imgBmp.Height),
                                                                           System.Drawing.Imaging.ImageLockMode.ReadOnly,
                                                                           System.Drawing.Imaging.PixelFormat.Format32bppArgb
                                                                       );

                                                                       try
                                                                       {
                                                                           var subresourceData = new SubresourceData
                                                                           {
                                                                               PSysMem = (void*) bmp.Scan0,
                                                                               SysMemPitch = (uint) bmp.Stride,
                                                                               SysMemSlicePitch = (uint) (bmp.Stride * bmp.Height)
                                                                           };

                                                                           SilkMarshal.ThrowHResult
                                                                           (
                                                                               device.CreateTexture2D
                                                                               (
                                                                                   in textureDesc,
                                                                                   in subresourceData,
                                                                                   ref texture
                                                                               )
                                                                           );
                                                                       }
                                                                       finally
                                                                       {
                                                                           imgBmp.UnlockBits(bmp);
                                                                       }

                                                                   	// Create a view of the texture for the shader.
                                                                       var srvDesc = new ShaderResourceViewDesc
                                                                       {
                                                                           Format = textureDesc.Format,
                                                                           ViewDimension = D3DSrvDimension.D3DSrvDimensionTexture2D,
                                                                           Anonymous = new ShaderResourceViewDescUnion
                                                                           {
                                                                               Texture2D =
                                                                               {
                                                                                   MostDetailedMip = 0,
                                                                                   MipLevels = 1
                                                                               }
                                                                           }
                                                                       };

                                                                       SilkMarshal.ThrowHResult
                                                                       (
                                                                           device.CreateShaderResourceView
                                                                           (
                                                                               texture,
                                                                               in srvDesc,
                                                                               ref textureResourceView
                                                                           )
                                                                       );

                                                                   	// Create a sampler.
                                                                       var samplerDesc = new SamplerDesc
                                                                       {
                                                                           Filter = Filter.MinMagMipLinear,
                                                                           AddressU = TextureAddressMode.Clamp,
                                                                           AddressV = TextureAddressMode.Clamp,
                                                                           AddressW = TextureAddressMode.Clamp,
                                                                           MipLODBias = 0,
                                                                           MaxAnisotropy = 1,
                                                                           MinLOD = float.MinValue,
                                                                           MaxLOD = float.MaxValue,
                                                                       };
                                                                       // Black border color.
                                                                       samplerDesc.BorderColor[0] = 0.0f;
                                                                       samplerDesc.BorderColor[1] = 0.0f;
                                                                       samplerDesc.BorderColor[2] = 0.0f;
                                                                       samplerDesc.BorderColor[3] = 1.0f;

                                                                       SilkMarshal.ThrowHResult
                                                                       (
                                                                           device.CreateSamplerState
                                                                           (
                                                                               in samplerDesc,
                                                                               ref textureSampler
                                                                           )
                                                                       );
-------------------------------------------------------------------------------------------------------------------------------------------
                                                                -+     deviceContext.PSSetSamplers(0, 1, textureSampler);
                                                                       deviceContext.PSSetShaderResources(0, 1, textureResourceView);

@otac0n
Copy link
Contributor Author

otac0n commented Mar 2, 2024

Works using ImageSharp:

image

Copy link
Member

@Perksey Perksey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can’t see anything objectionable in the diff you provided. Thank you again for your contribution, your work is really appreciated! 😄

@Perksey Perksey merged commit b01d65f into dotnet:main Mar 3, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants