-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial stab at integrated Direct2D support.
- Loading branch information
1 parent
c067a51
commit 085a430
Showing
19 changed files
with
689 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>WinExe</OutputType> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\thirtytwo\thirtytwo.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
using System.Numerics; | ||
using Windows; | ||
using Windows.Win32.Foundation; | ||
using Windows.Win32.Graphics.Direct2D; | ||
|
||
namespace Direct2dDemo; | ||
|
||
internal class Program | ||
{ | ||
[STAThread] | ||
private static void Main() => Application.Run(new Direct2dDemo()); | ||
|
||
private class Direct2dDemo : MainWindow | ||
{ | ||
private SolidColorBrush? _lightSlateGrayBrush; | ||
private SolidColorBrush? _cornflowerBlueBrush; | ||
|
||
public Direct2dDemo() : base(title: "Simple Direct2D Application", features: Features.EnableDirect2d) | ||
{ | ||
} | ||
|
||
protected override void RenderTargetCreated(HwndRenderTarget renderTarget) | ||
{ | ||
_lightSlateGrayBrush?.Dispose(); | ||
_cornflowerBlueBrush?.Dispose(); | ||
_lightSlateGrayBrush = renderTarget.CreateSolidColorBrush(Color.LightSlateGray); | ||
_cornflowerBlueBrush = renderTarget.CreateSolidColorBrush(Color.CornflowerBlue); | ||
base.RenderTargetCreated(renderTarget); | ||
} | ||
|
||
protected override LRESULT WindowProcedure(HWND window, MessageType message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (message) | ||
{ | ||
case MessageType.Paint: | ||
if (IsDirect2dEnabled(out var renderTarget)) | ||
{ | ||
renderTarget.SetTransform(Matrix3x2.Identity); | ||
renderTarget.Clear(Color.White); | ||
|
||
SizeF size = renderTarget.Size(); | ||
|
||
for (int x = 0; x < size.Width; x += 10) | ||
{ | ||
renderTarget.DrawLine( | ||
new(x, 0), new(x, size.Height), | ||
_lightSlateGrayBrush!, | ||
0.5f); | ||
} | ||
|
||
for (int y = 0; y < size.Height; y += 10) | ||
{ | ||
renderTarget.DrawLine( | ||
new(0, y), new(size.Width, y), | ||
_lightSlateGrayBrush!, | ||
0.5f); | ||
} | ||
|
||
RectangleF rectangle1 = RectangleF.FromLTRB( | ||
size.Width / 2 - 50, | ||
size.Height / 2 - 50, | ||
size.Width / 2 + 50, | ||
size.Height / 2 + 50); | ||
|
||
RectangleF rectangle2 = RectangleF.FromLTRB( | ||
size.Width / 2 - 100, | ||
size.Height / 2 - 100, | ||
size.Width / 2 + 100, | ||
size.Height / 2 + 100); | ||
|
||
renderTarget.FillRectangle(rectangle1, _lightSlateGrayBrush!); | ||
renderTarget.DrawRectangle(rectangle2, _cornflowerBlueBrush!); | ||
} | ||
return (LRESULT)0; | ||
} | ||
|
||
return base.WindowProcedure(window, message, wParam, lParam); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Runtime.CompilerServices; | ||
|
||
namespace System; | ||
|
||
internal static class EnumExtensions | ||
{ | ||
/// <summary> | ||
/// Returns true if the given flag or flags are set. | ||
/// </summary> | ||
/// <remarks> | ||
/// Simple wrapper for <see cref="Enum.HasFlag(Enum)"/> that gives you better intellisense. | ||
/// </remarks> | ||
[SkipLocalsInit] | ||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)] | ||
public static unsafe bool AreFlagsSet<T>(this T value, T flags) where T : unmanaged, Enum => value.HasFlag(flags); | ||
|
||
/// <summary> | ||
/// Sets the given flag or flags. | ||
/// </summary> | ||
[SkipLocalsInit] | ||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)] | ||
public static unsafe void SetFlags<T>(this ref T value, T flags) where T : unmanaged, Enum | ||
{ | ||
fixed (T* v = &value) | ||
{ | ||
// Note that the non-relevant if clauses will be omitted by the JIT so these become one statement. | ||
if (sizeof(T) == sizeof(byte)) | ||
{ | ||
*(byte*)v |= *(byte*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(short)) | ||
{ | ||
*(short*)v |= *(short*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(int)) | ||
{ | ||
*(int*)v |= *(int*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(long)) | ||
{ | ||
*(long*)v |= *(long*)&flags; | ||
} | ||
else | ||
{ | ||
throw new InvalidOperationException(); | ||
} | ||
} | ||
} | ||
|
||
[SkipLocalsInit] | ||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)] | ||
public static unsafe void ClearFlags<T>(this ref T value, T flags) where T : unmanaged, Enum | ||
{ | ||
fixed (T* v = &value) | ||
{ | ||
// Note that the non-relevant if clauses will be omitted by the JIT so these become one statement. | ||
if (sizeof(T) == sizeof(byte)) | ||
{ | ||
*(byte*)v &= (byte)~*(byte*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(short)) | ||
{ | ||
*(short*)v &= (short)~*(short*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(int)) | ||
{ | ||
*(int*)v &= ~*(int*)&flags; | ||
} | ||
else if (sizeof(T) == sizeof(long)) | ||
{ | ||
*(long*)v &= ~*(long*)&flags; | ||
} | ||
else | ||
{ | ||
throw new InvalidOperationException(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using Windows.Support; | ||
|
||
namespace Windows.Win32.Graphics.Direct2D; | ||
|
||
public unsafe class Brush : Resource, IPointer<ID2D1Brush> | ||
{ | ||
public unsafe new ID2D1Brush* Pointer { get; private set; } | ||
|
||
public Brush(ID2D1Brush* brush) : base((ID2D1Resource*)brush) => Pointer = brush; | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
Pointer = null; | ||
base.Dispose(disposing); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/thirtytwo/Win32/Graphics/Direct2D/Common/D2D1_COLOR_F.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
|
||
namespace Windows.Win32.Graphics.Direct2D.Common; | ||
|
||
public partial struct D2D1_COLOR_F | ||
{ | ||
public D2D1_COLOR_F(float r, float g, float b, float a) | ||
{ | ||
this.r = r; | ||
this.g = g; | ||
this.b = b; | ||
this.a = a; | ||
} | ||
|
||
public static explicit operator D2D1_COLOR_F(Color value) => | ||
new(value.R / 255.0f, value.G / 255.0f, value.B / 255.0f, value.A / 255.0f); | ||
} |
20 changes: 20 additions & 0 deletions
20
src/thirtytwo/Win32/Graphics/Direct2D/Common/D2D_RECT_F.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
|
||
namespace Windows.Win32.Graphics.Direct2D.Common; | ||
|
||
public partial struct D2D_RECT_F | ||
{ | ||
public D2D_RECT_F(float left, float top, float right, float bottom) | ||
{ | ||
this.left = left; | ||
this.top = top; | ||
this.right = right; | ||
this.bottom = bottom; | ||
} | ||
|
||
public static implicit operator D2D_RECT_F(RectangleF value) => | ||
new(value.Left, value.Top, value.Right, value.Bottom); | ||
} |
18 changes: 18 additions & 0 deletions
18
src/thirtytwo/Win32/Graphics/Direct2D/Common/D2D_SIZE_U.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
|
||
namespace Windows.Win32.Graphics.Direct2D.Common; | ||
|
||
public partial struct D2D_SIZE_U | ||
{ | ||
public D2D_SIZE_U(uint width, uint height) | ||
{ | ||
this.width = width; | ||
this.height = height; | ||
} | ||
|
||
public static explicit operator D2D_SIZE_U(Size value) => | ||
new(checked((uint)value.Width), checked((uint)value.Height)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using Windows.Support; | ||
using Windows.Win32.System.Com; | ||
|
||
namespace Windows.Win32.Graphics.Direct2D; | ||
|
||
public unsafe class Factory : DisposableBase.Finalizable, IPointer<ID2D1Factory> | ||
{ | ||
private readonly AgileComPointer<ID2D1Factory> _factory; | ||
|
||
public unsafe ID2D1Factory* Pointer { get; private set; } | ||
|
||
public Factory( | ||
D2D1_FACTORY_TYPE factoryType = D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED, | ||
D2D1_DEBUG_LEVEL factoryOptions = D2D1_DEBUG_LEVEL.D2D1_DEBUG_LEVEL_NONE) | ||
{ | ||
ID2D1Factory* factory; | ||
Interop.D2D1CreateFactory( | ||
factoryType, | ||
IID.Get<ID2D1Factory>(), | ||
(D2D1_FACTORY_OPTIONS*)&factoryOptions, | ||
(void**)&factory).ThrowOnFailure(); | ||
|
||
Pointer = factory; | ||
|
||
// Ensure that this can be disposed on the finalizer thread by giving the "last" ref count | ||
// to an agile pointer. | ||
_factory = new AgileComPointer<ID2D1Factory>(factory, takeOwnership: true); | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
Pointer = null; | ||
|
||
if (disposing) | ||
{ | ||
_factory.Dispose(); | ||
} | ||
} | ||
} |
Oops, something went wrong.