Skip to content

Commit

Permalink
Add support for "normal" 0->1 depth range in OpenGL
Browse files Browse the repository at this point in the history
Also, add a way to query a GraphicsDevice's depth range.
  • Loading branch information
mellinoe committed May 21, 2018
1 parent ec8a923 commit 2d48f94
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/NeoDemo/NeoDemo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public NeoDemo()
WindowInitialState = WindowState.Normal,
WindowTitle = "Veldrid NeoDemo"
};
GraphicsDeviceOptions gdOptions = new GraphicsDeviceOptions(false, null, false, ResourceBindingModel.Improved);
GraphicsDeviceOptions gdOptions = new GraphicsDeviceOptions(false, null, false, ResourceBindingModel.Improved, true);
#if DEBUG
gdOptions.Debug = true;
#endif
Expand Down
12 changes: 12 additions & 0 deletions src/Veldrid.OpenGLBindings/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2020,4 +2020,16 @@ public enum RenderbufferPname
RenderbufferWidth = 0x8D42,
RenderbufferHeight = 0x8D43,
}

public enum ClipControlOrigin
{
LowerLeft = 0x8CA1,
UpperLeft = 0x8CA2,
}

public enum ClipControlDepthRange
{
NegativeOneToOne = 0x935E,
ZeroToOne = 0x935F,
}
}
7 changes: 7 additions & 0 deletions src/Veldrid.OpenGLBindings/OpenGLNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,12 @@ public static void glBindRenderbuffer(RenderbufferTarget bindPoint, uint name)
private static glGenerateTextureMipmap_t p_glGenerateTextureMipmap;
public static void glGenerateTextureMipmap(uint texture) => p_glGenerateTextureMipmap(texture);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void glClipControl_t(ClipControlOrigin origin, ClipControlDepthRange depth);
private static glClipControl_t p_glClipControl;
public static void glClipControl(ClipControlOrigin origin, ClipControlDepthRange depth)
=> p_glClipControl(origin, depth);

public static void LoadGetString(IntPtr glContext, Func<string, IntPtr> getProcAddress)
{
s_getProcAddress = getProcAddress;
Expand Down Expand Up @@ -1685,6 +1691,7 @@ public static void LoadAllFunctions(IntPtr glContext, Func<string, IntPtr> getPr
LoadFunction("glViewportIndexedf", out p_glViewportIndexedf);
LoadFunction("glCopyImageSubData", out p_glCopyImageSubData);
LoadFunction("glGenerateTextureMipmap", out p_glGenerateTextureMipmap);
LoadFunction("glClipControl", out p_glClipControl);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions src/Veldrid/D3D11/D3D11GraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ internal class D3D11GraphicsDevice : GraphicsDevice

public override bool IsUvOriginTopLeft => true;

public override bool IsDepthRangeZeroToOne => true;

public override ResourceFactory ResourceFactory => _d3d11ResourceFactory;

public SharpDX.Direct3D11.Device Device => _device;
Expand Down
6 changes: 6 additions & 0 deletions src/Veldrid/GraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public abstract class GraphicsDevice : IDisposable
/// </summary>
public abstract bool IsUvOriginTopLeft { get; }

/// <summary>
/// Gets a value indicating whether this device's depth values range from 0 to 1.
/// If false, depth values instead range from -1 to 1.
/// </summary>
public abstract bool IsDepthRangeZeroToOne { get; }

/// <summary>
/// Gets the <see cref="ResourceFactory"/> controlled by this instance.
/// </summary>
Expand Down
35 changes: 35 additions & 0 deletions src/Veldrid/GraphicsDeviceOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public struct GraphicsDeviceOptions
/// by specifying a value in <see cref="GraphicsPipelineDescription.ResourceBindingModel"/>.
/// </summary>
public ResourceBindingModel ResourceBindingModel;
/// <summary>
/// Indicates whether a 0-to-1 depth range mapping is preferred. For OpenGL, this is not the default, and is not available
/// on all systems.
/// </summary>
public bool PreferDepthRangeZeroToOne;

/// <summary>
/// Constructs a new GraphicsDeviceOptions for a device with no main Swapchain.
Expand All @@ -41,6 +46,7 @@ public GraphicsDeviceOptions(bool debug)
SwapchainDepthFormat = null;
SyncToVerticalBlank = false;
ResourceBindingModel = ResourceBindingModel.Default;
PreferDepthRangeZeroToOne = false;
}

/// <summary>
Expand All @@ -59,6 +65,7 @@ public GraphicsDeviceOptions(bool debug, PixelFormat? swapchainDepthFormat, bool
SwapchainDepthFormat = swapchainDepthFormat;
SyncToVerticalBlank = syncToVerticalBlank;
ResourceBindingModel = ResourceBindingModel.Default;
PreferDepthRangeZeroToOne = false;
}

/// <summary>
Expand All @@ -82,6 +89,34 @@ public GraphicsDeviceOptions(bool debug, PixelFormat? swapchainDepthFormat, bool
SwapchainDepthFormat = swapchainDepthFormat;
SyncToVerticalBlank = syncToVerticalBlank;
ResourceBindingModel = resourceBindingModel;
PreferDepthRangeZeroToOne = false;
}

/// <summary>
/// Constructs a new GraphicsDeviceOptions for a device with a main Swapchain.
/// </summary>
/// <param name="debug">Indicates whether the GraphicsDevice will enable debug features, provided they are supported by
/// the host system.</param>
/// <param name="swapchainDepthFormat">An optional <see cref="PixelFormat"/> to be used for the depth buffer of the
/// swapchain. If this value is null, then no depth buffer will be present on the swapchain.</param>
/// <param name="syncToVerticalBlank">Indicates whether the main Swapchain will be synchronized to the window system's
/// vertical refresh rate.</param>
/// <param name="resourceBindingModel">Specifies which model the rendering backend should use for binding resources.</param>
/// <param name="preferZeroToOneDepthRange">Indicates whether a 0-to-1 depth range mapping is preferred. For OpenGL,
/// this is not the default, and is not available on all systems.</param>
public GraphicsDeviceOptions(
bool debug,
PixelFormat? swapchainDepthFormat,
bool syncToVerticalBlank,
ResourceBindingModel resourceBindingModel,
bool preferZeroToOneDepthRange)
{
Debug = debug;
HasMainSwapchain = true;
SwapchainDepthFormat = swapchainDepthFormat;
SyncToVerticalBlank = syncToVerticalBlank;
ResourceBindingModel = resourceBindingModel;
PreferDepthRangeZeroToOne = preferZeroToOneDepthRange;
}
}
}
2 changes: 2 additions & 0 deletions src/Veldrid/MTL/MTLGraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ internal unsafe class MTLGraphicsDevice : GraphicsDevice

public override bool IsUvOriginTopLeft => true;

public override bool IsDepthRangeZeroToOne => true;

public override ResourceFactory ResourceFactory { get; }

public override Swapchain MainSwapchain => _mainSwapchain;
Expand Down
3 changes: 3 additions & 0 deletions src/Veldrid/OpenGL/OpenGLExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public OpenGLExtensions(HashSet<string> extensions, GraphicsBackend backend, int
|| GLESVersion(3, 1);
MultiDrawIndirect = GLVersion(4, 3) || IsExtensionSupported("GL_ARB_multi_draw_indirect")
|| IsExtensionSupported("GL_EXT_multi_draw_indirect");

ARB_ClipControl = GLVersion(4, 5) || IsExtensionSupported("GL_ARB_clip_control");
}

public readonly bool ARB_DirectStateAccess;
Expand All @@ -55,6 +57,7 @@ public OpenGLExtensions(HashSet<string> extensions, GraphicsBackend backend, int
public readonly bool ARB_DebugOutput;
public readonly bool KHR_Debug;
public readonly bool ARB_ViewportArray;
public readonly bool ARB_ClipControl;

// Differs between GL / GLES
public readonly bool TextureStorage;
Expand Down
10 changes: 10 additions & 0 deletions src/Veldrid/OpenGL/OpenGLGraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal unsafe class OpenGLGraphicsDevice : GraphicsDevice
private OpenGLCommandExecutor _commandExecutor;
private DebugProc _debugMessageCallback;
private OpenGLExtensions _extensions;
private bool _isDepthRangeZeroToOne;

private TextureSampleCount _maxColorTextureSamples;
private uint _maxTextureSize;
Expand Down Expand Up @@ -65,6 +66,8 @@ internal unsafe class OpenGLGraphicsDevice : GraphicsDevice

public override bool IsUvOriginTopLeft => false;

public override bool IsDepthRangeZeroToOne => _isDepthRangeZeroToOne;

public override ResourceFactory ResourceFactory => _resourceFactory;

public OpenGLExtensions Extensions => _extensions;
Expand Down Expand Up @@ -245,6 +248,13 @@ public override bool SyncToVerticalBlank
glGetIntegerv(GetPName.MaxArrayTextureLayers, &maxTexArrayLayers);
CheckLastError();

if (options.PreferDepthRangeZeroToOne && _extensions.ARB_ClipControl)
{
glClipControl(ClipControlOrigin.LowerLeft, ClipControlDepthRange.ZeroToOne);
CheckLastError();
_isDepthRangeZeroToOne = true;
}

_maxTextureSize = (uint)maxTexSize;
_maxTexDepth = (uint)maxTexDepth;
_maxTexArrayLayers = (uint)maxTexArrayLayers;
Expand Down
2 changes: 2 additions & 0 deletions src/Veldrid/Vk/VkGraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ internal unsafe class VkGraphicsDevice : GraphicsDevice

public override bool IsUvOriginTopLeft => true;

public override bool IsDepthRangeZeroToOne => true;

public override Swapchain MainSwapchain => _mainSwapchain;

public override GraphicsDeviceFeatures Features { get; }
Expand Down

0 comments on commit 2d48f94

Please sign in to comment.