// Copyright (c) 2015-2019 Michael Popoloski // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Security; namespace SharpBgfx { /// /// Provides an interface for programs to respond to callbacks from the bgfx library. /// public interface ICallbackHandler { /// /// Called when an error occurs in the library. /// /// The name of the source file in which the message originated. /// The line number in which the message originated. /// The type of error that occurred. /// Message string detailing what went wrong. /// /// If the error type is not , bgfx is in an /// unrecoverable state and the application should terminate. /// /// This method can be called from any thread. /// void ReportError (string fileName, int line, ErrorType errorType, string message); /// /// Called to print debug messages. /// /// The name of the source file in which the message originated. /// The line number in which the message originated. /// The message format string. /// A pointer to format arguments. /// This method can be called from any thread. void ReportDebug (string fileName, int line, string format, IntPtr args); /// /// Called when a profiling region is entered. /// /// The name of the region. /// The color of the region. /// The path of the source file containing the region. /// The line number on which the region was started. void ProfilerBegin (string name, int color, string filePath, int line); /// /// Called when a profiling region is ended. /// void ProfilerEnd (); /// /// Queries the size of a cache item. /// /// The cache entry ID. /// The size of the cache item, or 0 if the item is not found. int GetCachedSize (long id); /// /// Retrieves an entry from the cache. /// /// The cache entry ID. /// A pointer that should be filled with data from the cache. /// The size of the memory block pointed to be . /// true if the item is found in the cache; otherwise, false. bool GetCacheEntry (long id, IntPtr data, int size); /// /// Saves an entry in the cache. /// /// The cache entry ID. /// A pointer to the data to save in the cache. /// The size of the memory block pointed to be . void SetCacheEntry (long id, IntPtr data, int size); /// /// Save a captured screenshot. /// /// The path at which to save the image. /// The width of the image. /// The height of the image. /// The number of bytes between lines in the image. /// A pointer to the image data to save. /// The size of the image memory. /// true if the image origin is bottom left instead of top left; otherwise, false. void SaveScreenShot (string path, int width, int height, int pitch, IntPtr data, int size, bool flipVertical); /// /// Notifies that a frame capture has begun. /// /// The width of the capture surface. /// The height of the capture surface. /// The number of bytes between lines in the captured frames. /// The format of captured frames. /// true if the image origin is bottom left instead of top left; otherwise, false. void CaptureStarted (int width, int height, int pitch, TextureFormat format, bool flipVertical); /// /// Notifies that a frame capture has finished. /// void CaptureFinished (); /// /// Notifies that a frame has been captured. /// /// A pointer to the frame data. /// The size of the frame data. void CaptureFrame (IntPtr data, int size); } /// /// Managed interface to the bgfx graphics library. /// public unsafe static class Bgfx { /// /// Attempts to allocate both a transient vertex buffer and index buffer. /// /// The number of vertices to allocate. /// The layout of each vertex. /// The number of indices to allocate. /// Returns the allocated transient vertex buffer. /// Returns the allocated transient index buffer. /// true if both space requirements are satisfied and the buffers were allocated. public static bool AllocateTransientBuffers (int vertexCount, VertexLayout layout, int indexCount, out TransientVertexBuffer vertexBuffer, out TransientIndexBuffer indexBuffer) { return NativeMethods.bgfx_alloc_transient_buffers(out vertexBuffer, ref layout.data, (ushort)vertexCount, out indexBuffer, (ushort)indexCount); } /// /// Packs a vector into vertex stream format. /// /// The four element vector to pack. /// true if the input vector is normalized. /// The attribute usage of the vector data. /// The layout of the vertex stream. /// The pointer to the vertex data stream. /// The index of the vertex within the stream. public static void VertexPack (float* input, bool inputNormalized, VertexAttributeUsage attribute, VertexLayout layout, IntPtr data, int index = 0) { NativeMethods.bgfx_vertex_pack(input, inputNormalized, attribute, ref layout.data, data, index); } /// /// Unpack a vector from a vertex stream. /// /// A pointer to four floats that will receive the unpacked vector. /// The usage of the vertex attribute. /// The layout of the vertex stream. /// A pointer to the vertex data stream. /// The index of the vertex within the stream. public static void VertexUnpack (float* output, VertexAttributeUsage attribute, VertexLayout layout, IntPtr data, int index = 0) { NativeMethods.bgfx_vertex_unpack(output, attribute, ref layout.data, data, index); } /// /// Converts a stream of vertex data from one format to another. /// /// The destination format. /// A pointer to the output location. /// The source format. /// A pointer to the source vertex data to convert. /// The number of vertices to convert. public static void VertexConvert (VertexLayout destinationLayout, IntPtr destinationData, VertexLayout sourceLayout, IntPtr sourceData, int count = 1) { NativeMethods.bgfx_vertex_convert(ref destinationLayout.data, destinationData, ref sourceLayout.data, sourceData, count); } /// /// Welds vertices that are close together. /// /// The layout of the vertex stream. /// A pointer to the vertex data stream. /// The number of vertices in the stream. /// An output remapping table from the original vertices to the welded ones. /// The tolerance for welding vertex positions. /// /// The number of unique vertices after welding. /// public static int WeldVertices (VertexLayout layout, IntPtr data, int count, out int[] remappingTable, float epsilon = 0.001f) { var output = stackalloc ushort[count]; var result = NativeMethods.bgfx_weld_vertices(output, ref layout.data, data, (ushort)count, epsilon); remappingTable = new int[count]; for (int i = 0; i < count; i++) remappingTable[i] = output[i]; return result; } /// /// Swizzles an RGBA8 image to BGRA8. /// /// The destination image data. /// The width of the image. /// The height of the image. /// The pitch of the image (in bytes). /// The source image data. /// /// This method can operate in-place on the image (i.e. src == dst). /// public static void ImageSwizzleBgra8(IntPtr destination, int width, int height, int pitch, IntPtr source) { NativeMethods.bgfx_image_swizzle_bgra8(destination, width, height, pitch, source); } /// /// Downsamples an RGBA8 image with a 2x2 pixel average filter. /// /// The destination image data. /// The width of the image. /// The height of the image. /// The pitch of the image (in bytes). /// The source image data. /// /// This method can operate in-place on the image (i.e. src == dst). /// public static void ImageRgba8Downsample2x2 (IntPtr destination, int width, int height, int pitch, IntPtr source) { NativeMethods.bgfx_image_rgba8_downsample_2x2(destination, width, height, pitch, source); } /// /// Sets platform-specific data pointers to hook into low-level library functionality. /// /// A collection of platform-specific data pointers. public static void SetPlatformData (PlatformData platformData) { NativeMethods.bgfx_set_platform_data(ref platformData); } /// /// Sets the handle of the main rendering window. /// /// The handle of the native OS window. public static void SetWindowHandle (IntPtr windowHandle) { var data = new PlatformData { WindowHandle = windowHandle }; NativeMethods.bgfx_set_platform_data(ref data); } /// /// Gets access to underlying API internals for interop scenarios. /// /// A structure containing API context information. public static InternalData GetInternalData () { unsafe { return *NativeMethods.bgfx_get_internal_data(); } } /// /// Manually renders a frame. Use this to control the Bgfx render loop. /// /// /// The amount of time to wait, in milliseconds, for the next frame to be rendered. /// If the timeout is exceeded, the call /// returns. /// /// The result of the render call. /// /// Use this function if you don't want Bgfx to create and maintain a /// separate render thread. Call this once before /// to avoid having the thread created internally. /// public static RenderFrameResult ManuallyRenderFrame (int timeoutMs = -1) { return NativeMethods.bgfx_render_frame(timeoutMs); } /// /// Gets the currently active rendering backend API. /// /// The currently active rendering backend. public static RendererBackend GetCurrentBackend () { return NativeMethods.bgfx_get_renderer_type(); } /// /// Closes the library and releases all resources. /// public static void Shutdown () { NativeMethods.bgfx_shutdown(); CallbackShim.FreeShim(); } /// /// Gets the capabilities of the rendering device. /// /// Information about the capabilities of the device. public static Capabilities GetCaps () { return new Capabilities(NativeMethods.bgfx_get_caps()); } /// /// Gets frame performance statistics. /// /// Information about frame performance. public static PerfStats GetStats () { return new PerfStats(NativeMethods.bgfx_get_stats()); } /// /// Resets graphics settings and surfaces. /// /// The width of the main window. /// The height of the main window. /// Flags used to configure rendering output. public static void Reset (int width, int height, ResetFlags flags = ResetFlags.None) { Reset(width, height, flags, (TextureFormat)TextureFormatCount); } /// /// Resets graphics settings and surfaces. /// /// The width of the main window. /// The height of the main window. /// Flags used to configure rendering output. /// The format of the backbuffer. public static void Reset (int width, int height, ResetFlags flags, TextureFormat format) { NativeMethods.bgfx_reset(width, height, flags, format); } /// /// Advances to the next frame. /// /// If true the frame is captured for debugging. /// The current frame number. /// /// When using a multithreaded renderer, this call /// just swaps internal buffers, kicks render thread, and returns. In a /// singlethreaded renderer this call does frame rendering. /// public static int Frame (bool capture = false) { return NativeMethods.bgfx_frame(capture); } /// /// Initializes the graphics library on the specified adapter. /// /// Settings that control initialization, or null to use sane defaults. /// true if initialization succeeds; otherwise, false. public static bool Init (InitSettings settings = null) { InitSettings.Native native; NativeMethods.bgfx_init_ctor(&native); settings = settings ?? new InitSettings(); native.Backend = settings.Backend; native.VendorId = (ushort)settings.Adapter.Vendor; native.DeviceId = (ushort)settings.Adapter.DeviceId; native.Debug = (byte)(settings.Debug ? 1 : 0); native.Profiling = (byte)(settings.Profiling ? 1 : 0); native.Resolution.Format = settings.Format; native.Resolution.Width = (uint)settings.Width; native.Resolution.Height = (uint)settings.Height; native.Resolution.Flags = (uint)settings.ResetFlags; native.Resolution.NumBackBuffers = (byte)settings.BackBufferCount; native.Resolution.MaxFrameLatency = (byte)settings.MaxFrameLatency; native.Callbacks = CallbackShim.CreateShim(settings.CallbackHandler ?? new DefaultCallbackHandler()); native.PlatformData = settings.PlatformData; return NativeMethods.bgfx_init(&native); } /// /// Gets the set of supported rendering backends. /// /// public static RendererBackend[] GetSupportedBackends () { var types = new RendererBackend[(int)RendererBackend.Default]; var count = NativeMethods.bgfx_get_supported_renderers((byte)types.Length, types); return types.Take(count).ToArray(); } /// /// Gets the friendly name of a specific rendering backend. /// /// The backend for which to retrieve a name. /// The friendly name of the specified backend. public static string GetBackendName (RendererBackend backend) { return Marshal.PtrToStringAnsi(new IntPtr(NativeMethods.bgfx_get_renderer_name(backend))); } /// /// Enables debugging features. /// /// The set of debug features to enable. public static void SetDebugFeatures (DebugFeatures features) { NativeMethods.bgfx_set_debug(features); } /// /// Sets a marker that can be used for debugging purposes. /// /// The user-defined name of the marker. public static void SetDebugMarker (string marker) { NativeMethods.bgfx_set_marker(marker); } /// /// Clears the debug text buffer. /// /// The color with which to clear the background. /// true to use a small font for debug output; false to use normal sized text. public static void DebugTextClear (DebugColor color = DebugColor.Black, bool smallText = false) { var attr = (byte)((byte)color << 4); NativeMethods.bgfx_dbg_text_clear(attr, smallText); } /// /// Writes debug text to the screen. /// /// The X position, in cells. /// The Y position, in cells. /// The foreground color of the text. /// The background color of the text. /// The format of the message. /// The arguments with which to format the message. public static void DebugTextWrite (int x, int y, DebugColor foreColor, DebugColor backColor, string format, params object[] args) { DebugTextWrite(x, y, foreColor, backColor, string.Format(CultureInfo.CurrentCulture, format, args)); } /// /// Writes debug text to the screen. /// /// The X position, in cells. /// The Y position, in cells. /// The foreground color of the text. /// The background color of the text. /// The message to write. public static void DebugTextWrite (int x, int y, DebugColor foreColor, DebugColor backColor, string message) { var attr = (byte)(((byte)backColor << 4) | (byte)foreColor); NativeMethods.bgfx_dbg_text_printf((ushort)x, (ushort)y, attr, "%s", message); } /// /// Writes debug text to the screen. /// /// The X position, in cells. /// The Y position, in cells. /// The foreground color of the text. /// The background color of the text. /// The message to write. public static void DebugTextWrite (int x, int y, DebugColor foreColor, DebugColor backColor, IntPtr message) { var attr = (byte)(((byte)backColor << 4) | (byte)foreColor); var format = stackalloc byte[3]; format[0] = (byte)'%'; format[1] = (byte)'s'; format[2] = 0; NativeMethods.bgfx_dbg_text_printf((ushort)x, (ushort)y, attr, format, message); } /// /// Draws data directly into the debug text buffer. /// /// The X position, in cells. /// The Y position, in cells. /// The width of the image to draw. /// The height of the image to draw. /// The image data bytes. /// The pitch of each line in the image data. public static void DebugTextImage (int x, int y, int width, int height, IntPtr data, int pitch) { NativeMethods.bgfx_dbg_text_image((ushort)x, (ushort)y, (ushort)width, (ushort)height, data, (ushort)pitch); } /// /// Draws data directly into the debug text buffer. /// /// The X position, in cells. /// The Y position, in cells. /// The width of the image to draw. /// The height of the image to draw. /// The image data bytes. /// The pitch of each line in the image data. public static void DebugTextImage (int x, int y, int width, int height, byte[] data, int pitch) { fixed (byte* ptr = data) NativeMethods.bgfx_dbg_text_image((ushort)x, (ushort)y, (ushort)width, (ushort)height, new IntPtr(ptr), (ushort)pitch); } /// /// Sets the name of a rendering view, for debugging purposes. /// /// The index of the view. /// The name of the view. public static void SetViewName (ushort id, string name) { NativeMethods.bgfx_set_view_name(id, name); } /// /// Sets the viewport for the given rendering view. /// /// The index of the view. /// The X coordinate of the viewport. /// The Y coordinate of the viewport. /// The width of the viewport, in pixels. /// The height of the viewport, in pixels. public static void SetViewRect (ushort id, int x, int y, int width, int height) { NativeMethods.bgfx_set_view_rect(id, (ushort)x, (ushort)y, (ushort)width, (ushort)height); } /// /// Sets the viewport for the given rendering view. /// /// The index of the view. /// The X coordinate of the viewport. /// The Y coordinate of the viewport. /// The ratio with which to automatically size the viewport. public static void SetViewRect (ushort id, int x, int y, BackbufferRatio ratio) { NativeMethods.bgfx_set_view_rect_auto(id, (ushort)x, (ushort)y, ratio); } /// /// Sets the scissor rectangle for a specific view. /// /// The index of the view. /// The X coordinate of the scissor rectangle. /// The Y coordinate of the scissor rectangle. /// The width of the scissor rectangle. /// The height of the scissor rectangle. /// /// Set all values to zero to disable the scissor test. /// public static void SetViewScissor (ushort id, int x, int y, int width, int height) { NativeMethods.bgfx_set_view_scissor(id, (ushort)x, (ushort)y, (ushort)width, (ushort)height); } /// /// Sets view clear flags. /// /// The index of the view. /// The target surfaces that should be cleared. /// The clear color. /// The value to fill the depth buffer. /// The value to fill the stencil buffer. public static void SetViewClear (ushort id, ClearTargets targets, int colorRgba, float depth = 1.0f, byte stencil = 0) { NativeMethods.bgfx_set_view_clear(id, targets, colorRgba, depth, stencil); } /// /// Sets view clear flags for multiple render targets. /// /// The index of the view. /// The target surfaces that should be cleared. /// The value to fill the depth buffer. /// The value to fill the stencil buffer. /// The color palette index for render target 0. /// The color palette index for render target 1. /// The color palette index for render target 2. /// The color palette index for render target 3. /// The color palette index for render target 4. /// The color palette index for render target 5. /// The color palette index for render target 6. /// The color palette index for render target 7. public static void SetViewClear ( ushort id, ClearTargets targets, float depth, byte stencil, byte rt0 = byte.MaxValue, byte rt1 = byte.MaxValue, byte rt2 = byte.MaxValue, byte rt3 = byte.MaxValue, byte rt4 = byte.MaxValue, byte rt5 = byte.MaxValue, byte rt6 = byte.MaxValue, byte rt7 = byte.MaxValue ) { NativeMethods.bgfx_set_view_clear_mrt( id, targets, depth, stencil, rt0, rt1, rt2, rt3, rt4, rt5, rt6, rt7 ); } /// /// Sets an entry in the color palette. /// /// The index of the palette entry to set. /// The color to set. /// /// The clear color palette is used with SetViewClear for clearing multiple render targets /// to different color values. /// public static void SetPaletteColor (byte index, float* color) { NativeMethods.bgfx_set_palette_color(index, color); } /// /// Sets the sorting mode to use for the given view. /// /// The index of the view. /// The sorting mode to use. public static void SetViewMode (ushort id, ViewMode mode) { NativeMethods.bgfx_set_view_mode(id, mode); } /// /// Sets the view and projection transforms for the given rendering view. /// /// The index of the view. /// The 4x4 view transform matrix. /// The 4x4 projection transform matrix. public static void SetViewTransform (ushort id, float* view, float* projection) { NativeMethods.bgfx_set_view_transform(id, view, projection); } /// /// Sets the frame buffer used by a particular view. /// /// The index of the view. /// The frame buffer to set. public static void SetViewFrameBuffer (ushort id, FrameBuffer frameBuffer) { NativeMethods.bgfx_set_view_frame_buffer(id, frameBuffer.handle); } /// /// Sets the model transform to use for drawing primitives. /// /// A pointer to one or more matrices to set. /// The number of matrices in the array. /// An index into the matrix cache to allow reusing the matrix in other calls. public static int SetTransform (float* matrix, int count = 1) { return NativeMethods.bgfx_set_transform(matrix, (ushort)count); } /// /// Sets a model transform from the cache. /// /// The index of the cached matrix. /// The number of matrices to set from the cache. public static void SetTransform (int cacheIndex, int count = 1) { NativeMethods.bgfx_set_transform_cached(cacheIndex, (ushort)count); } /// /// Sets the scissor rectangle to use for clipping primitives. /// /// The X coordinate of the scissor rectangle. /// The Y coordinate of the scissor rectangle. /// The width of the rectangle. /// The height of the rectangle. /// /// An index into the scissor cache to allow reusing the rectangle in other calls. /// public static int SetScissor (int x, int y, int width, int height) { return NativeMethods.bgfx_set_scissor((ushort)x, (ushort)y, (ushort)width, (ushort)height); } /// /// Sets a scissor rectangle from the cache. /// /// The index of the cached scissor rectangle, or -1 to unset. public static void SetScissor (int cacheIndex = -1) { NativeMethods.bgfx_set_scissor_cached((ushort)cacheIndex); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public static void SetIndexBuffer (IndexBuffer indexBuffer) { NativeMethods.bgfx_set_index_buffer(indexBuffer.handle, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public static void SetIndexBuffer (IndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_set_index_buffer(indexBuffer.handle, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public static void SetVertexBuffer (int stream, VertexBuffer vertexBuffer) { NativeMethods.bgfx_set_vertex_buffer((byte)stream, vertexBuffer.handle, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public static void SetVertexBuffer (int stream, VertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_set_vertex_buffer((byte)stream, vertexBuffer.handle, firstVertex, count); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public static void SetIndexBuffer (DynamicIndexBuffer indexBuffer) { NativeMethods.bgfx_set_dynamic_index_buffer(indexBuffer.handle, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public static void SetIndexBuffer (DynamicIndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_set_dynamic_index_buffer(indexBuffer.handle, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public static void SetVertexBuffer (int stream, DynamicVertexBuffer vertexBuffer) { NativeMethods.bgfx_set_dynamic_vertex_buffer((byte)stream, vertexBuffer.handle, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public static void SetVertexBuffer (int stream, DynamicVertexBuffer vertexBuffer, int startVertex, int count) { NativeMethods.bgfx_set_dynamic_vertex_buffer((byte)stream, vertexBuffer.handle, startVertex, count); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public static void SetIndexBuffer (TransientIndexBuffer indexBuffer) { NativeMethods.bgfx_set_transient_index_buffer(ref indexBuffer, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public static void SetIndexBuffer (TransientIndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_set_transient_index_buffer(ref indexBuffer, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public static void SetVertexBuffer (int stream, TransientVertexBuffer vertexBuffer) { NativeMethods.bgfx_set_transient_vertex_buffer((byte)stream, ref vertexBuffer, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public static void SetVertexBuffer (int stream, TransientVertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_set_transient_vertex_buffer((byte)stream, ref vertexBuffer, firstVertex, count); } /// /// Sets the number of auto-generated vertices for use with gl_VertexID. /// /// The number of auto-generated vertices. public static void SetVertexCount(int count) { NativeMethods.bgfx_set_vertex_count(count); } /// /// Sets the number of auto-generated indices for use with gl_InstanceID. /// /// The number of auto-generated instances. public static void SetInstanceCount (int count) { NativeMethods.bgfx_set_instance_count(count); } /// /// Sets instance data to use for drawing primitives. /// /// The instance data. /// The starting offset in the buffer. /// The number of entries to pull from the buffer. public static void SetInstanceDataBuffer (ref InstanceDataBuffer instanceData, int start = 0, int count = -1) { NativeMethods.bgfx_set_instance_data_buffer(ref instanceData.data, (uint)start, (uint)count); } /// /// Sets instance data to use for drawing primitives. /// /// The vertex buffer containing instance data. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public static void SetInstanceDataBuffer (VertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_set_instance_data_from_vertex_buffer(vertexBuffer.handle, firstVertex, count); } /// /// Sets instance data to use for drawing primitives. /// /// The vertex buffer containing instance data. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public static void SetInstanceDataBuffer (DynamicVertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_set_instance_data_from_dynamic_vertex_buffer(vertexBuffer.handle, firstVertex, count); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public static void SetUniform (Uniform uniform, float value, int arraySize = 1) { NativeMethods.bgfx_set_uniform(uniform.handle, &value, (ushort)arraySize); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public static void SetUniform (Uniform uniform, void* value, int arraySize = 1) { NativeMethods.bgfx_set_uniform(uniform.handle, value, (ushort)arraySize); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public static void SetUniform (Uniform uniform, IntPtr value, int arraySize = 1) { NativeMethods.bgfx_set_uniform(uniform.handle, value.ToPointer(), (ushort)arraySize); } /// /// Sets a texture to use for drawing primitives. /// /// The texture unit to set. /// The sampler uniform. /// The texture to set. public static void SetTexture (byte textureUnit, Uniform sampler, Texture texture) { NativeMethods.bgfx_set_texture(textureUnit, sampler.handle, texture.handle, uint.MaxValue); } /// /// Sets a texture to use for drawing primitives. /// /// The texture unit to set. /// The sampler uniform. /// The texture to set. /// Sampling flags that override the default flags in the texture itself. public static void SetTexture (byte textureUnit, Uniform sampler, Texture texture, TextureFlags flags) { NativeMethods.bgfx_set_texture(textureUnit, sampler.handle, texture.handle, (uint)flags); } /// /// Sets a texture mip as a compute image. /// /// The buffer stage to set. /// The texture to set. /// The index of the mip level within the texture to set. /// The format of the buffer data. /// Access control flags. public static void SetComputeImage (byte stage, Texture texture, byte mip, ComputeBufferAccess access, TextureFormat format = TextureFormat.Unknown) { NativeMethods.bgfx_set_image(stage, texture.handle, mip, format, access); } /// /// Sets an index buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public static void SetComputeBuffer (byte stage, IndexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_set_compute_index_buffer(stage, buffer.handle, access); } /// /// Sets a verterx buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public static void SetComputeBuffer (byte stage, VertexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_set_compute_vertex_buffer(stage, buffer.handle, access); } /// /// Sets a dynamic index buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public static void SetComputeBuffer (byte stage, DynamicIndexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_set_compute_dynamic_index_buffer(stage, buffer.handle, access); } /// /// Sets a dynamic vertex buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public static void SetComputeBuffer (byte stage, DynamicVertexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_set_compute_dynamic_vertex_buffer(stage, buffer.handle, access); } /// /// Sets an indirect buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public static void SetComputeBuffer (byte stage, IndirectBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_set_compute_indirect_buffer(stage, buffer.handle, access); } /// /// Marks a view as "touched", ensuring that its background is cleared even if nothing is rendered. /// /// The index of the view to touch. /// The number of draw calls. public static int Touch (ushort id) { return NativeMethods.bgfx_touch(id); } /// /// Resets all view settings to default. /// /// The index of the view to reset. public static void ResetView (ushort id) { NativeMethods.bgfx_reset_view(id); } /// /// Submits the current batch of primitives for rendering. /// /// The index of the view to submit. /// The program with which to render. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public static int Submit (ushort id, Program program, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_submit(id, program.handle, depth, preserveState); } /// /// Submits the current batch of primitives for rendering. /// /// The index of the view to submit. /// The program with which to render. /// An occlusion query to use as a predicate during rendering. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public static int Submit (ushort id, Program program, OcclusionQuery query, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_submit_occlusion_query(id, program.handle, query.handle, depth, preserveState); } /// /// Submits an indirect batch of drawing commands to be used for rendering. /// /// The index of the view to submit. /// The program with which to render. /// The buffer containing drawing commands. /// The index of the first command to process. /// The number of commands to process from the buffer. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public static int Submit (ushort id, Program program, IndirectBuffer indirectBuffer, int startIndex = 0, int count = 1, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_submit_indirect(id, program.handle, indirectBuffer.handle, (ushort)startIndex, (ushort)count, depth, preserveState); } /// /// Discards all previously set state for the draw call. /// public static void Discard () { NativeMethods.bgfx_discard(); } /// /// Dispatches a compute job. /// /// The index of the view to dispatch. /// The shader program to use. /// The size of the job in the first dimension. /// The size of the job in the second dimension. /// The size of the job in the third dimension. public static void Dispatch (ushort id, Program program, int xCount = 1, int yCount = 1, int zCount = 1) { NativeMethods.bgfx_dispatch(id, program.handle, (uint)xCount, (uint)yCount, (uint)zCount); } /// /// Dispatches an indirect compute job. /// /// The index of the view to dispatch. /// The shader program to use. /// The buffer containing drawing commands. /// The index of the first command to process. /// The number of commands to process from the buffer. public static void Dispatch (ushort id, Program program, IndirectBuffer indirectBuffer, int startIndex = 0, int count = 1) { NativeMethods.bgfx_dispatch_indirect(id, program.handle, indirectBuffer.handle, (ushort)startIndex, (ushort)count); } /// /// Requests that a screenshot be saved. The ScreenshotTaken event will be fired to save the result. /// /// The file path that will be passed to the callback event. public static void RequestScreenShot(string filePath) { NativeMethods.bgfx_request_screen_shot(ushort.MaxValue, filePath); } /// /// Requests that a screenshot be saved. The ScreenshotTaken event will be fired to save the result. /// /// The frame buffer to save. /// The file path that will be passed to the callback event. public static void RequestScreenShot (FrameBuffer frameBuffer, string filePath) { NativeMethods.bgfx_request_screen_shot(frameBuffer.handle, filePath); } /// /// Set rendering states used to draw primitives. /// /// The set of states to set. public static void SetRenderState (RenderState state) { NativeMethods.bgfx_set_state((ulong)state, 0); } /// /// Set rendering states used to draw primitives. /// /// The set of states to set. /// The color used for "factor" blending modes. public static void SetRenderState (RenderState state, int colorRgba) { NativeMethods.bgfx_set_state((ulong)state, colorRgba); } /// /// Sets stencil test state. /// /// The stencil state to use for front faces. public static void SetStencil (StencilFlags frontFace) { SetStencil(frontFace, StencilFlags.None); } /// /// Sets stencil test state. /// /// The stencil state to use for front faces. /// The stencil state to use for back faces. public static void SetStencil (StencilFlags frontFace, StencilFlags backFace) { NativeMethods.bgfx_set_stencil((uint)frontFace, (uint)backFace); } /// /// Begins submission of commands via an encoder on this thread. /// /// An encoder instance that can be used to submit commands. public static Encoder Begin () { return new Encoder(NativeMethods.bgfx_begin()); } static readonly int TextureFormatCount = Enum.GetValues(typeof(TextureFormat)).Length; class DefaultCallbackHandler : ICallbackHandler { public void ProfilerBegin (string name, int color, string filePath, int line) {} public void ProfilerEnd () {} public void CaptureStarted(int width, int height, int pitch, TextureFormat format, bool flipVertical) {} public void CaptureFrame(IntPtr data, int size) {} public void CaptureFinished() {} public int GetCachedSize(long id) { return 0; } public bool GetCacheEntry(long id, IntPtr data, int size) { return false; } public void SetCacheEntry(long id, IntPtr data, int size) {} public void SaveScreenShot(string path, int width, int height, int pitch, IntPtr data, int size, bool flipVertical) {} public void ReportDebug(string fileName, int line, string format, IntPtr args) { sbyte* buffer = stackalloc sbyte[1024]; NativeMethods.bgfx_vsnprintf(buffer, new IntPtr(1024), format, args); Debug.Write(Marshal.PtrToStringAnsi(new IntPtr(buffer))); } public void ReportError(string fileName, int line, ErrorType errorType, string message) { if (errorType == ErrorType.DebugCheck) Debug.Write(message); else { Debug.Write(string.Format("{0}: {1}", errorType, message)); Debugger.Break(); Environment.Exit(1); } } } } /// /// Contains various settings used to initialize the library. /// public class InitSettings { /// /// The backend API to use for rendering. /// public RendererBackend Backend { get; set; } /// /// The adapter on which to create the device. /// public Adapter Adapter { get; set; } /// /// Enable debugging with the device. /// public bool Debug { get; set; } /// /// Enable profling with the device. /// public bool Profiling { get; set; } /// /// The initial texture format of the screen. /// public TextureFormat Format { get; set; } /// /// The initial width of the screen. /// public int Width { get; set; } /// /// The initial height of the screen. /// public int Height { get; set; } /// /// Various flags that control creation of the device. /// public ResetFlags ResetFlags { get; set; } /// /// The number of backbuffers to create. /// public int BackBufferCount { get; set; } /// /// The maximum allowed frame latency, or zero if you don't care. /// public int MaxFrameLatency { get; set; } /// /// A set of handlers for various library callbacks. /// public ICallbackHandler CallbackHandler { get; set; } /// /// Optional platform-specific initialization data. /// public PlatformData PlatformData { get; set; } /// /// Initializes a new intance of the class. /// unsafe public InitSettings () { Native native; NativeMethods.bgfx_init_ctor(&native); Backend = native.Backend; Adapter = new Adapter((Vendor)native.VendorId, native.DeviceId); Debug = native.Debug != 0; Profiling = native.Profiling != 0; Format = native.Resolution.Format; Width = (int)native.Resolution.Width; Height = (int)native.Resolution.Height; ResetFlags = (ResetFlags)native.Resolution.Flags; BackBufferCount = native.Resolution.NumBackBuffers; MaxFrameLatency = native.Resolution.MaxFrameLatency; PlatformData = native.PlatformData; } /// /// Initializes a new intance of the class. /// /// The initial width of the screen. /// The initial height of the screen. /// Various flags that control creation of the device. public InitSettings (int width, int height, ResetFlags resetFlags = ResetFlags.None) : this() { Width = width; Height = height; ResetFlags = resetFlags; } internal struct ResolutionNative { public TextureFormat Format; public uint Width; public uint Height; public uint Flags; public byte NumBackBuffers; public byte MaxFrameLatency; } internal struct InitLimits { public ushort MaxEncoders; public uint TransientVbSize; public uint TransientIbSize; } internal struct Native { public RendererBackend Backend; public ushort VendorId; public ushort DeviceId; public byte Debug; public byte Profiling; public PlatformData PlatformData; public ResolutionNative Resolution; public InitLimits Limits; public IntPtr Callbacks; public IntPtr Allocator; } } /// /// Represents a loaded texture. /// public unsafe sealed class Texture : IDisposable, IEquatable { internal readonly ushort handle; /// /// The width of the texture. /// public int Width { get; private set; } /// /// The height of the texture. /// public int Height { get; private set; } /// /// The depth of the texture, if 3D. /// public int Depth { get; private set; } /// /// Indicates whether the texture is a cubemap. /// public bool IsCubeMap { get; private set; } /// /// The number of texture array layers (for 2D or cube textures). /// public int ArrayLayers { get; private set; } /// /// The number of mip levels in the texture. /// public int MipLevels { get; private set; } /// /// The number of bits per pixel. /// public int BitsPerPixel { get; private set; } /// /// The size of the entire texture, in bytes. /// public int SizeInBytes { get; private set; } /// /// The format of the image data. /// public TextureFormat Format { get; private set; } internal Texture (ushort handle, ref TextureInfo info) { this.handle = handle; Width = info.Width; Height = info.Height; Depth = info.Depth; ArrayLayers = info.Layers; MipLevels = info.MipCount; BitsPerPixel = info.BitsPerPixel; SizeInBytes = info.StorageSize; Format = info.Format; IsCubeMap = info.IsCubeMap; } /// /// Creates a new texture from a file loaded in memory. /// /// The content of the file. /// Flags that control texture behavior. /// A number of top level mips to skip when parsing texture data. /// The newly created texture. /// /// This function supports textures in the following container formats: /// - DDS /// - KTX /// - PVR /// public static Texture FromFile (MemoryBlock memory, TextureFlags flags = TextureFlags.None, int skipMips = 0) { TextureInfo info; var handle = NativeMethods.bgfx_create_texture(memory.ptr, flags, (byte)skipMips, out info); return new Texture(handle, ref info); } /// /// Creates a new 2D texture. /// /// The width of the texture. /// The height of the texture. /// Indicates that texture contains full mip-map chain. /// Number of layers in texture array. Must be 1 if Texture2DArray caps flag not set. /// The format of the texture data. /// Flags that control texture behavior. /// If not null, contains the texture's image data. /// /// The newly created texture handle. /// public static Texture Create2D (int width, int height, bool hasMips, int arrayLayers, TextureFormat format, TextureFlags flags = TextureFlags.None, MemoryBlock? memory = null) { var info = new TextureInfo(); NativeMethods.bgfx_calc_texture_size(ref info, (ushort)width, (ushort)height, 1, false, hasMips, (ushort)arrayLayers, format); var handle = NativeMethods.bgfx_create_texture_2d(info.Width, info.Height, hasMips, (ushort)arrayLayers, format, flags, memory == null ? null : memory.Value.ptr); return new Texture(handle, ref info); } /// /// Creates a new 2D texture that scales with backbuffer size. /// /// The amount to scale when the backbuffer resizes. /// Indicates that texture contains full mip-map chain. /// Number of layers in texture array. Must be 1 if Texture2DArray caps flag not set. /// The format of the texture data. /// Flags that control texture behavior. /// /// The newly created texture handle. /// public static Texture Create2D (BackbufferRatio ratio, bool hasMips, int arrayLayers, TextureFormat format, TextureFlags flags = TextureFlags.None) { var info = new TextureInfo { Format = format, Layers = (ushort)arrayLayers }; var handle = NativeMethods.bgfx_create_texture_2d_scaled(ratio, hasMips, (ushort)arrayLayers, format, flags); return new Texture(handle, ref info); } /// /// Creates a new 3D texture. /// /// The width of the texture. /// The height of the texture. /// The depth of the texture. /// Indicates that texture contains full mip-map chain. /// The format of the texture data. /// Flags that control texture behavior. /// If not null, contains the texture's image data. /// The newly created texture handle. public static Texture Create3D (int width, int height, int depth, bool hasMips, TextureFormat format, TextureFlags flags = TextureFlags.None, MemoryBlock? memory = null) { var info = new TextureInfo(); NativeMethods.bgfx_calc_texture_size(ref info, (ushort)width, (ushort)height, (ushort)depth, false, hasMips, 1, format); var handle = NativeMethods.bgfx_create_texture_3d(info.Width, info.Height, info.Depth, hasMips, format, flags, memory == null ? null : memory.Value.ptr); return new Texture(handle, ref info); } /// /// Creates a new cube texture. /// /// The size of each cube face. /// Indicates that texture contains full mip-map chain. /// Number of layers in texture array. Must be 1 if Texture2DArray caps flag not set. /// The format of the texture data. /// Flags that control texture behavior. /// If not null, contains the texture's image data. /// /// The newly created texture handle. /// public static Texture CreateCube (int size, bool hasMips, int arrayLayers, TextureFormat format, TextureFlags flags = TextureFlags.None, MemoryBlock? memory = null) { var info = new TextureInfo(); NativeMethods.bgfx_calc_texture_size(ref info, (ushort)size, (ushort)size, 1, true, hasMips, (ushort)arrayLayers, format); var handle = NativeMethods.bgfx_create_texture_cube(info.Width, hasMips, (ushort)arrayLayers, format, flags, memory == null ? null : memory.Value.ptr); return new Texture(handle, ref info); } /// /// Checks whether a texture with the given parameters would be considered valid. /// /// The depth of the texture. /// true if the texture contains a cubemap. /// Number of layers in texture array. /// The format of the texture data. /// Flags that control texture behavior. /// public static bool IsValid (int depth, bool isCube, int arrayLayers, TextureFormat format, TextureFlags flags = TextureFlags.None) { return NativeMethods.bgfx_is_texture_valid((ushort)depth, isCube, (ushort)arrayLayers, format, flags); } /// /// Releases the texture. /// public void Dispose () { NativeMethods.bgfx_destroy_texture(handle); } /// /// Sets the name of the texture, for debug display purposes. /// /// The name of the texture. public void SetName(string name) { NativeMethods.bgfx_set_texture_name(handle, name, int.MaxValue); } /// /// Updates the data in a 2D texture. /// /// The layer in a texture array to update. /// The mip level. /// The X coordinate of the rectangle to update. /// The Y coordinate of the rectangle to update. /// The width of the rectangle to update. /// The height of the rectangle to update. /// The new image data. /// The pitch of the image data. public void Update2D (int arrayLayer, int mipLevel, int x, int y, int width, int height, MemoryBlock memory, int pitch) { NativeMethods.bgfx_update_texture_2d(handle, (ushort)arrayLayer, (byte)mipLevel, (ushort)x, (ushort)y, (ushort)width, (ushort)height, memory.ptr, (ushort)pitch); } /// /// Updates the data in a 3D texture. /// /// The mip level. /// The X coordinate of the volume to update. /// The Y coordinate of the volume to update. /// The Z coordinate of the volume to update. /// The width of the volume to update. /// The height of the volume to update. /// The depth of the volume to update. /// The new image data. public void Update3D (int mipLevel, int x, int y, int z, int width, int height, int depth, MemoryBlock memory) { NativeMethods.bgfx_update_texture_3d(handle, (byte)mipLevel, (ushort)x, (ushort)y, (ushort)z, (ushort)width, (ushort)height, (ushort)depth, memory.ptr); } /// /// Updates the data in a cube texture. /// /// The cube map face to update. /// The layer in a texture array to update. /// The mip level. /// The X coordinate of the rectangle to update. /// The Y coordinate of the rectangle to update. /// The width of the rectangle to update. /// The height of the rectangle to update. /// The new image data. /// The pitch of the image data. public void UpdateCube (CubeMapFace face, int arrayLayer, int mipLevel, int x, int y, int width, int height, MemoryBlock memory, int pitch) { NativeMethods.bgfx_update_texture_cube(handle, (ushort)arrayLayer, face, (byte)mipLevel, (ushort)x, (ushort)y, (ushort)width, (ushort)height, memory.ptr, (ushort)pitch); } /// /// Blits the contents of the texture to another texture. /// /// The view in which the blit will be ordered. /// The destination texture. /// The destination X position. /// The destination Y position. /// The source X position. /// The source Y position. /// The width of the region to blit. /// The height of the region to blit. /// The destination texture must be created with the flag. public void BlitTo (ushort viewId, Texture dest, int destX, int destY, int sourceX = 0, int sourceY = 0, int width = ushort.MaxValue, int height = ushort.MaxValue) { BlitTo(viewId, dest, 0, destX, destY, 0, 0, sourceX, sourceY, 0, width, height, 0); } /// /// Blits the contents of the texture to another texture. /// /// The view in which the blit will be ordered. /// The destination texture. /// The destination mip level. /// The destination X position. /// The destination Y position. /// The destination Z position. /// The source mip level. /// The source X position. /// The source Y position. /// The source Z position. /// The width of the region to blit. /// The height of the region to blit. /// The depth of the region to blit. /// The destination texture must be created with the flag. public void BlitTo (ushort viewId, Texture dest, int destMip, int destX, int destY, int destZ, int sourceMip = 0, int sourceX = 0, int sourceY = 0, int sourceZ = 0, int width = ushort.MaxValue, int height = ushort.MaxValue, int depth = ushort.MaxValue) { NativeMethods.bgfx_blit(viewId, dest.handle, (byte)destMip, (ushort)destX, (ushort)destY, (ushort)destZ, handle, (byte)sourceMip, (ushort)sourceX, (ushort)sourceY, (ushort)sourceZ, (ushort)width, (ushort)height, (ushort)depth); } /// /// Blits the contents of the texture to another texture. /// /// The encoder used for threaded command submission. /// The view in which the blit will be ordered. /// The destination texture. /// The destination X position. /// The destination Y position. /// The source X position. /// The source Y position. /// The width of the region to blit. /// The height of the region to blit. /// The destination texture must be created with the flag. public void BlitTo (Encoder encoder, ushort viewId, Texture dest, int destX, int destY, int sourceX = 0, int sourceY = 0, int width = ushort.MaxValue, int height = ushort.MaxValue) { BlitTo(encoder, viewId, dest, 0, destX, destY, 0, 0, sourceX, sourceY, 0, width, height, 0); } /// /// Blits the contents of the texture to another texture. /// /// The encoder used for threaded command submission. /// The view in which the blit will be ordered. /// The destination texture. /// The destination mip level. /// The destination X position. /// The destination Y position. /// The destination Z position. /// The source mip level. /// The source X position. /// The source Y position. /// The source Z position. /// The width of the region to blit. /// The height of the region to blit. /// The depth of the region to blit. /// The destination texture must be created with the flag. public void BlitTo (Encoder encoder, ushort viewId, Texture dest, int destMip, int destX, int destY, int destZ, int sourceMip = 0, int sourceX = 0, int sourceY = 0, int sourceZ = 0, int width = ushort.MaxValue, int height = ushort.MaxValue, int depth = ushort.MaxValue) { NativeMethods.bgfx_encoder_blit(encoder.ptr, viewId, dest.handle, (byte)destMip, (ushort)destX, (ushort)destY, (ushort)destZ, handle, (byte)sourceMip, (ushort)sourceX, (ushort)sourceY, (ushort)sourceZ, (ushort)width, (ushort)height, (ushort)depth); } /// /// Reads the contents of the texture and stores them in memory pointed to by . /// /// The destination for the read image data. /// The mip level to read. /// The frame number on which the result will be available. /// The texture must have been created with the flag. public int Read (IntPtr data, int mip) { return (int)NativeMethods.bgfx_read_texture(handle, data, (byte)mip); } /// /// Override internal texture with externally created texture. /// /// The native API texture pointer. /// /// Native API pointer to the texture. If result is , the texture is not yet /// created from the main thread. /// public IntPtr OverrideInternal (IntPtr ptr) { return NativeMethods.bgfx_override_internal_texture_ptr(handle, ptr); } /// /// Override internal texture by creating a new 2D texture. /// /// The width of the texture. /// The height of the texture. /// The number of mip levels. /// The format of the texture data. /// Flags that control texture behavior. /// /// Native API pointer to the texture. If result is , the texture is not yet /// created from the main thread. /// public IntPtr OverrideInternal (int width, int height, int mipCount, TextureFormat format, TextureFlags flags = TextureFlags.None) { Width = width; Height = height; MipLevels = mipCount; Format = format; return NativeMethods.bgfx_override_internal_texture(handle, (ushort)width, (ushort)height, (byte)mipCount, format, flags); } /// /// Returns a direct pointer to the texture memory. /// /// /// A pointer to the texture's memory. If result is direct access is /// not supported. If the result is -1, the texture is pending creation. /// public IntPtr GetDirectAccess () { return NativeMethods.bgfx_get_direct_access_ptr(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (Texture other) { if (ReferenceEquals(other, null)) return false; if (ReferenceEquals(other, this)) return true; return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { return Equals(obj as Texture); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator == (Texture left, Texture right) { if (ReferenceEquals(left, null)) return ReferenceEquals(right, null); return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator != (Texture left, Texture right) { return !(left == right); } internal struct TextureInfo { public TextureFormat Format; public int StorageSize; public ushort Width; public ushort Height; public ushort Depth; public ushort Layers; public byte MipCount; public byte BitsPerPixel; public bool IsCubeMap; } } /// /// Describes the layout of data in a vertex stream. /// public sealed class VertexLayout { internal Data data; /// /// The stride of a single vertex using this layout. /// public int Stride { get { return data.Stride; } } /// /// Starts a stream of vertex attribute additions to the layout. /// /// The rendering backend with which to associate the attributes. /// This instance, for use in a fluent API. public VertexLayout Begin (RendererBackend backend = RendererBackend.Noop) { NativeMethods.bgfx_vertex_decl_begin(ref data, backend); return this; } /// /// Starts a stream of vertex attribute additions to the layout. /// /// The kind of attribute to add. /// The number of elements in the attribute (1, 2, 3, or 4). /// The type of data described by the attribute. /// if set to true, values will be normalized from a 0-255 range to 0.0 - 0.1 in the shader. /// if set to true, the attribute is packaged as an integer in the shader. /// /// This instance, for use in a fluent API. /// public VertexLayout Add (VertexAttributeUsage attribute, int count, VertexAttributeType type, bool normalized = false, bool asInt = false) { NativeMethods.bgfx_vertex_decl_add(ref data, attribute, (byte)count, type, normalized, asInt); return this; } /// /// Skips the specified number of bytes in the vertex stream. /// /// The number of bytes to skip. /// This instance, for use in a fluent API. public VertexLayout Skip (int count) { NativeMethods.bgfx_vertex_decl_skip(ref data, (byte)count); return this; } /// /// Marks the end of the vertex stream. /// /// This instance, for use in a fluent API. public VertexLayout End () { NativeMethods.bgfx_vertex_decl_end(ref data); return this; } /// /// Gets the byte offset of a particular attribute in the layout. /// /// The attribute for which to get the offset. /// The offset of the attribute, in bytes. public unsafe int GetOffset (VertexAttributeUsage attribute) { fixed (Data* ptr = &data) return ptr->Offset[(int)attribute]; } /// /// Determines whether the layout contains the given attribute. /// /// The attribute to check/ /// true if the layout contains the attribute; otherwise, false. public unsafe bool HasAttribute (VertexAttributeUsage attribute) { fixed (Data* ptr = &data) return ptr->Attributes[(int)attribute] != ushort.MaxValue; } internal unsafe struct Data { const int MaxAttribCount = 18; public uint Hash; public ushort Stride; public fixed ushort Offset[MaxAttribCount]; public fixed ushort Attributes[MaxAttribCount]; } } /// /// Contains details about an installed graphics adapter. /// public struct Adapter { /// /// Represents the default adapter for the system. /// public static readonly Adapter Default = new Adapter(Vendor.None, 0); /// /// The IHV that published the adapter. /// public readonly Vendor Vendor; /// /// A vendor-specific identifier for the adapter type. /// public readonly int DeviceId; /// /// Initializes a new instance of the struct. /// /// The vendor. /// The device ID. public Adapter (Vendor vendor, int deviceId) { Vendor = vendor; DeviceId = deviceId; } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Vendor: {0}, Device: {0}", Vendor, DeviceId); } } /// /// Represents a framebuffer attachment. /// public struct Attachment { /// /// Access control for using the attachment. /// public ComputeBufferAccess Access; /// /// The attachment texture handle. /// public Texture Texture; /// /// The texture mip level. /// public int Mip; /// /// Cube map face or depth layer/slice. /// public int Layer; /// /// Additional flags for framebuffer resolve. /// public ResolveFlags Resolve; } /// /// Contains information about the capabilities of the rendering device. /// public unsafe struct Capabilities { Caps* data; /// /// The currently active rendering backend API. /// public RendererBackend Backend { get { return data->Backend; } } /// /// A set of extended features supported by the device. /// public DeviceFeatures SupportedFeatures { get { return data->Supported; } } /// /// The maximum number of draw calls in a single frame. /// public int MaxDrawCalls { get { return (int)data->MaxDrawCalls; } } /// /// The maximum number of texture blits in a single frame. /// public int MaxBlits { get { return (int)data->MaxBlits; } } /// /// The maximum size of a texture, in pixels. /// public int MaxTextureSize { get { return (int)data->MaxTextureSize; } } /// /// The maximum layers in a texture. /// public int MaxTextureLayers { get { return (int)data->MaxTextureLayers; } } /// /// The maximum number of render views supported. /// public int MaxViews { get { return (int)data->MaxViews; } } /// /// The maximum number of frame buffers that can be allocated. /// public int MaxFramebuffers { get { return (int)data->MaxFramebuffers; } } /// /// The maximum number of attachments to a single framebuffer. /// public int MaxFramebufferAttachments { get { return (int)data->MaxFramebufferAttachements; } } /// /// The maximum number of programs that can be allocated. /// public int MaxPrograms { get { return (int)data->MaxPrograms; } } /// /// The maximum number of shaders that can be allocated. /// public int MaxShaders { get { return (int)data->MaxShaders; } } /// /// The maximum number of textures that can be allocated. /// public int MaxTextures { get { return (int)data->MaxTextures; } } /// /// The maximum number of texture samplers that can be allocated. /// public int MaxTextureSamplers { get { return (int)data->MaxTextureSamplers; } } /// /// The maximum number of compute bindings that can be allocated. /// public int MaxComputeBindings { get { return (int)data->MaxComputeBindings; } } /// /// The maximum number of vertex declarations that can be allocated. /// public int MaxVertexDecls { get { return (int)data->MaxVertexDecls; } } /// /// The maximum number of vertex streams that can be used. /// public int MaxVertexStreams { get { return (int)data->MaxVertexStreams; } } /// /// The maximum number of index buffers that can be allocated. /// public int MaxIndexBuffers { get { return (int)data->MaxIndexBuffers; } } /// /// The maximum number of vertex buffers that can be allocated. /// public int MaxVertexBuffers { get { return (int)data->MaxVertexBuffers; } } /// /// The maximum number of dynamic index buffers that can be allocated. /// public int MaxDynamicIndexBuffers { get { return (int)data->MaxDynamicIndexBuffers; } } /// /// The maximum number of dynamic vertex buffers that can be allocated. /// public int MaxDynamicVertexBuffers { get { return (int)data->MaxDynamicVertexBuffers; } } /// /// The maximum number of uniforms that can be used. /// public int MaxUniforms { get { return (int)data->MaxUniforms; } } /// /// The maximum number of occlusion queries that can be used. /// public int MaxOcclusionQueries { get { return (int)data->MaxOcclusionQueries; } } /// /// The maximum number of encoder threads. /// public int MaxEncoders { get { return (int)data->MaxEncoders; } } /// /// The amount of transient vertex buffer space reserved. /// public int TransientVertexBufferSize { get { return (int)data->TransientVbSize; } } /// /// The amount of transient index buffer space reserved. /// public int TransientIndexBufferSize { get { return (int)data->TransientIbSize; } } /// /// Indicates whether depth coordinates in NDC range from -1 to 1 (true) or 0 to 1 (false). /// public bool HomogeneousDepth { get { return data->HomogeneousDepth != 0; } } /// /// Indicates whether the coordinate system origin is at the bottom left or top left. /// public bool OriginBottomLeft { get { return data->OriginBottomLeft != 0; } } /// /// Details about the currently active graphics adapter. /// public Adapter CurrentAdapter { get { return new Adapter((Vendor)data->VendorId, data->DeviceId); } } /// /// A list of all graphics adapters installed on the system. /// public AdapterCollection Adapters { get { return new AdapterCollection(data->GPUs, data->GPUCount); } } static Capabilities() { Debug.Assert(Caps.TextureFormatCount == Enum.GetValues(typeof(TextureFormat)).Length); } internal Capabilities (Caps* data) { this.data = data; } /// /// Checks device support for a specific texture format. /// /// The format to check. /// The level of support for the given format. public TextureFormatSupport CheckTextureSupport (TextureFormat format) { return (TextureFormatSupport)data->Formats[(int)format]; } /// /// Provides access to a collection of adapters. /// public unsafe struct AdapterCollection : IReadOnlyList { ushort* data; int count; /// /// Accesses the element at the specified index. /// /// The index of the element to retrieve. /// The element at the given index. public Adapter this[int index] { get { return new Adapter((Vendor)data[index * 2], data[index * 2 + 1]); } } /// /// The number of elements in the collection. /// public int Count { get { return count; } } internal AdapterCollection (ushort* data, int count) { this.data = data; this.count = count; } /// /// Gets an enumerator for the collection. /// /// A collection enumerator. public Enumerator GetEnumerator () { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator(); } /// /// Implements an enumerator for an AdapterCollection. /// public struct Enumerator : IEnumerator { AdapterCollection collection; int index; /// /// The current enumerated item. /// public Adapter Current { get { return collection[index]; } } object IEnumerator.Current { get { return Current; } } internal Enumerator (AdapterCollection collection) { this.collection = collection; index = -1; } /// /// Advances to the next item in the sequence. /// /// true if there are more items in the collection; otherwise, false. public bool MoveNext () { var newIndex = index + 1; if (newIndex >= collection.Count) return false; index = newIndex; return true; } /// /// Empty; does nothing. /// public void Dispose () { } /// /// Not implemented. /// public void Reset () { throw new NotImplementedException(); } } } #pragma warning disable 649 internal unsafe struct Caps { public const int TextureFormatCount = 85; public RendererBackend Backend; public DeviceFeatures Supported; public ushort VendorId; public ushort DeviceId; public byte HomogeneousDepth; public byte OriginBottomLeft; public byte GPUCount; public fixed ushort GPUs[8]; public uint MaxDrawCalls; public uint MaxBlits; public uint MaxTextureSize; public uint MaxTextureLayers; public uint MaxViews; public uint MaxFramebuffers; public uint MaxFramebufferAttachements; public uint MaxPrograms; public uint MaxShaders; public uint MaxTextures; public uint MaxTextureSamplers; public uint MaxComputeBindings; public uint MaxVertexDecls; public uint MaxVertexStreams; public uint MaxIndexBuffers; public uint MaxVertexBuffers; public uint MaxDynamicIndexBuffers; public uint MaxDynamicVertexBuffers; public uint MaxUniforms; public uint MaxOcclusionQueries; public uint MaxEncoders; public uint TransientVbSize; public uint TransientIbSize; public fixed ushort Formats[TextureFormatCount]; } #pragma warning restore 649 } /// /// Represents a dynamically updateable index buffer. /// public unsafe struct DynamicIndexBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly DynamicIndexBuffer Invalid = new DynamicIndexBuffer(); /// /// Initializes a new instance of the struct. /// /// The number of indices that can fit in the buffer. /// Flags used to control buffer behavior. public DynamicIndexBuffer (int indexCount, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_dynamic_index_buffer(indexCount, flags); } /// /// Initializes a new instance of the struct. /// /// The initial index data with which to populate the buffer. /// Flags used to control buffer behavior. public DynamicIndexBuffer (MemoryBlock memory, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_dynamic_index_buffer_mem(memory.ptr, flags); } /// /// Updates the data in the buffer. /// /// Index of the first index to update. /// The new index data with which to fill the buffer. public void Update (int startIndex, MemoryBlock memory) { NativeMethods.bgfx_update_dynamic_index_buffer(handle, startIndex, memory.ptr); } /// /// Releases the index buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_dynamic_index_buffer(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (DynamicIndexBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as DynamicIndexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(DynamicIndexBuffer left, DynamicIndexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(DynamicIndexBuffer left, DynamicIndexBuffer right) { return !left.Equals(right); } } /// /// Represents a dynamically updateable vertex buffer. /// public unsafe struct DynamicVertexBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly DynamicVertexBuffer Invalid = new DynamicVertexBuffer(); /// /// Initializes a new instance of the struct. /// /// The number of vertices that fit in the buffer. /// The layout of the vertex data. /// Flags used to control buffer behavior. public DynamicVertexBuffer (int vertexCount, VertexLayout layout, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_dynamic_vertex_buffer(vertexCount, ref layout.data, flags); } /// /// Initializes a new instance of the struct. /// /// The initial vertex data with which to populate the buffer. /// The layout of the vertex data. /// Flags used to control buffer behavior. public DynamicVertexBuffer (MemoryBlock memory, VertexLayout layout, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_dynamic_vertex_buffer_mem(memory.ptr, ref layout.data, flags); } /// /// Updates the data in the buffer. /// /// Index of the first vertex to update. /// The new vertex data with which to fill the buffer. public void Update (int startVertex, MemoryBlock memory) { NativeMethods.bgfx_update_dynamic_vertex_buffer(handle, startVertex, memory.ptr); } /// /// Releases the vertex buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_dynamic_vertex_buffer(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (DynamicVertexBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as DynamicVertexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(DynamicVertexBuffer left, DynamicVertexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(DynamicVertexBuffer left, DynamicVertexBuffer right) { return !left.Equals(right); } } /// /// An interface for encoding a list of commands from multiple threads. /// Dispose of the encoder to finish submitting calls from the current thread. /// public unsafe struct Encoder : IDisposable, IEquatable { internal readonly IntPtr ptr; internal Encoder (IntPtr ptr) { this.ptr = ptr; } /// /// Sets a marker that can be used for debugging purposes. /// /// The user-defined name of the marker. public void SetDebugMarker (string marker) { NativeMethods.bgfx_encoder_set_marker(ptr, marker); } /// /// Set rendering states used to draw primitives. /// /// The set of states to set. public void SetRenderState (RenderState state) { NativeMethods.bgfx_encoder_set_state(ptr, (ulong)state, 0); } /// /// Set rendering states used to draw primitives. /// /// The set of states to set. /// The color used for "factor" blending modes. public void SetRenderState (RenderState state, int colorRgba) { NativeMethods.bgfx_encoder_set_state(ptr, (ulong)state, colorRgba); } /// /// Sets stencil test state. /// /// The stencil state to use for front faces. public void SetStencil (StencilFlags frontFace) { SetStencil(frontFace, StencilFlags.None); } /// /// Sets stencil test state. /// /// The stencil state to use for front faces. /// The stencil state to use for back faces. public void SetStencil (StencilFlags frontFace, StencilFlags backFace) { NativeMethods.bgfx_encoder_set_stencil(ptr, (uint)frontFace, (uint)backFace); } /// /// Sets the scissor rectangle to use for clipping primitives. /// /// The X coordinate of the scissor rectangle. /// The Y coordinate of the scissor rectangle. /// The width of the rectangle. /// The height of the rectangle. /// /// An index into the scissor cache to allow reusing the rectangle in other calls. /// public int SetScissor (int x, int y, int width, int height) { return NativeMethods.bgfx_encoder_set_scissor(ptr, (ushort)x, (ushort)y, (ushort)width, (ushort)height); } /// /// Sets a scissor rectangle from the cache. /// /// The index of the cached scissor rectangle, or -1 to unset. public void SetScissor (int cacheIndex = -1) { NativeMethods.bgfx_encoder_set_scissor_cached(ptr, (ushort)cacheIndex); } /// /// Sets the model transform to use for drawing primitives. /// /// A pointer to one or more matrices to set. /// The number of matrices in the array. /// An index into the matrix cache to allow reusing the matrix in other calls. public int SetTransform (float* matrix, int count = 1) { return NativeMethods.bgfx_encoder_set_transform(ptr, matrix, (ushort)count); } /// /// Sets a model transform from the cache. /// /// The index of the cached matrix. /// The number of matrices to set from the cache. public void SetTransform (int cacheIndex, int count = 1) { NativeMethods.bgfx_encoder_set_transform_cached(ptr, cacheIndex, (ushort)count); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public void SetUniform (Uniform uniform, float value, int arraySize = 1) { NativeMethods.bgfx_encoder_set_uniform(ptr, uniform.handle, &value, (ushort)arraySize); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public void SetUniform (Uniform uniform, void* value, int arraySize = 1) { NativeMethods.bgfx_encoder_set_uniform(ptr, uniform.handle, value, (ushort)arraySize); } /// /// Sets the value of a uniform parameter. /// /// The uniform to set. /// A pointer to the uniform's data. /// The size of the data array, if the uniform is an array. public void SetUniform (Uniform uniform, IntPtr value, int arraySize = 1) { NativeMethods.bgfx_encoder_set_uniform(ptr, uniform.handle, value.ToPointer(), (ushort)arraySize); } /// /// Sets a texture to use for drawing primitives. /// /// The texture unit to set. /// The sampler uniform. /// The texture to set. public void SetTexture (byte textureUnit, Uniform sampler, Texture texture) { NativeMethods.bgfx_encoder_set_texture(ptr, textureUnit, sampler.handle, texture.handle, uint.MaxValue); } /// /// Sets a texture to use for drawing primitives. /// /// The texture unit to set. /// The sampler uniform. /// The texture to set. /// Sampling flags that override the default flags in the texture itself. public void SetTexture (byte textureUnit, Uniform sampler, Texture texture, TextureFlags flags) { NativeMethods.bgfx_encoder_set_texture(ptr, textureUnit, sampler.handle, texture.handle, (uint)flags); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public void SetIndexBuffer (IndexBuffer indexBuffer) { NativeMethods.bgfx_encoder_set_index_buffer(ptr, indexBuffer.handle, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public void SetIndexBuffer (IndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_encoder_set_index_buffer(ptr, indexBuffer.handle, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public void SetVertexBuffer (int stream, VertexBuffer vertexBuffer) { NativeMethods.bgfx_encoder_set_vertex_buffer(ptr, (byte)stream, vertexBuffer.handle, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public void SetVertexBuffer (int stream, VertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_encoder_set_vertex_buffer(ptr, (byte)stream, vertexBuffer.handle, firstVertex, count); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public void SetIndexBuffer (DynamicIndexBuffer indexBuffer) { NativeMethods.bgfx_encoder_set_dynamic_index_buffer(ptr, indexBuffer.handle, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public void SetIndexBuffer (DynamicIndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_encoder_set_dynamic_index_buffer(ptr, indexBuffer.handle, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public void SetVertexBuffer (int stream, DynamicVertexBuffer vertexBuffer) { NativeMethods.bgfx_encoder_set_dynamic_vertex_buffer(ptr, (byte)stream, vertexBuffer.handle, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public void SetVertexBuffer (int stream, DynamicVertexBuffer vertexBuffer, int startVertex, int count) { NativeMethods.bgfx_encoder_set_dynamic_vertex_buffer(ptr, (byte)stream, vertexBuffer.handle, startVertex, count); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. public void SetIndexBuffer (TransientIndexBuffer indexBuffer) { NativeMethods.bgfx_encoder_set_transient_index_buffer(ptr, ref indexBuffer, 0, -1); } /// /// Sets the index buffer to use for drawing primitives. /// /// The index buffer to set. /// The first index in the buffer to use. /// The number of indices to pull from the buffer. public void SetIndexBuffer (TransientIndexBuffer indexBuffer, int firstIndex, int count) { NativeMethods.bgfx_encoder_set_transient_index_buffer(ptr, ref indexBuffer, firstIndex, count); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. public void SetVertexBuffer (int stream, TransientVertexBuffer vertexBuffer) { NativeMethods.bgfx_encoder_set_transient_vertex_buffer(ptr, (byte)stream, ref vertexBuffer, 0, -1); } /// /// Sets the vertex buffer to use for drawing primitives. /// /// The index of the vertex stream to set. /// The vertex buffer to set. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public void SetVertexBuffer (int stream, TransientVertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_encoder_set_transient_vertex_buffer(ptr, (byte)stream, ref vertexBuffer, firstVertex, count); } /// /// Sets the number of auto-generated vertices for use with gl_VertexID. /// /// The number of auto-generated vertices. public void SetVertexCount (int count) { NativeMethods.bgfx_encoder_set_vertex_count(ptr, count); } /// /// Sets instance data to use for drawing primitives. /// /// The instance data. /// The starting offset in the buffer. /// The number of entries to pull from the buffer. public void SetInstanceDataBuffer (ref InstanceDataBuffer instanceData, int start = 0, int count = -1) { NativeMethods.bgfx_encoder_set_instance_data_buffer(ptr, ref instanceData.data, (uint)start, (uint)count); } /// /// Sets instance data to use for drawing primitives. /// /// The vertex buffer containing instance data. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public void SetInstanceDataBuffer (VertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_encoder_set_instance_data_from_vertex_buffer(ptr, vertexBuffer.handle, firstVertex, count); } /// /// Sets instance data to use for drawing primitives. /// /// The vertex buffer containing instance data. /// The index of the first vertex to use. /// The number of vertices to pull from the buffer. public void SetInstanceDataBuffer (DynamicVertexBuffer vertexBuffer, int firstVertex, int count) { NativeMethods.bgfx_encoder_set_instance_data_from_dynamic_vertex_buffer(ptr, vertexBuffer.handle, firstVertex, count); } /// /// Marks a view as "touched", ensuring that its background is cleared even if nothing is rendered. /// /// The index of the view to touch. /// The number of draw calls. public int Touch (ushort id) { return NativeMethods.bgfx_encoder_touch(ptr, id); } /// /// Submits the current batch of primitives for rendering. /// /// The index of the view to submit. /// The program with which to render. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public int Submit (ushort id, Program program, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_encoder_submit(ptr, id, program.handle, depth, preserveState); } /// /// Submits the current batch of primitives for rendering. /// /// The index of the view to submit. /// The program with which to render. /// An occlusion query to use as a predicate during rendering. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public int Submit (ushort id, Program program, OcclusionQuery query, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_encoder_submit_occlusion_query(ptr, id, program.handle, query.handle, depth, preserveState); } /// /// Submits an indirect batch of drawing commands to be used for rendering. /// /// The index of the view to submit. /// The program with which to render. /// The buffer containing drawing commands. /// The index of the first command to process. /// The number of commands to process from the buffer. /// A depth value to use for sorting the batch. /// true to preserve internal draw state after the call. /// The number of draw calls. public int Submit (ushort id, Program program, IndirectBuffer indirectBuffer, int startIndex = 0, int count = 1, int depth = 0, bool preserveState = false) { return NativeMethods.bgfx_encoder_submit_indirect(ptr, id, program.handle, indirectBuffer.handle, (ushort)startIndex, (ushort)count, depth, preserveState); } /// /// Sets a texture mip as a compute image. /// /// The buffer stage to set. /// The texture to set. /// The index of the mip level within the texture to set. /// The format of the buffer data. /// Access control flags. public void SetComputeImage (byte stage, Texture texture, byte mip, ComputeBufferAccess access, TextureFormat format = TextureFormat.Unknown) { NativeMethods.bgfx_encoder_set_image(ptr, stage, texture.handle, mip, format, access); } /// /// Sets an index buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public void SetComputeBuffer (byte stage, IndexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_encoder_set_compute_index_buffer(ptr, stage, buffer.handle, access); } /// /// Sets a verterx buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public void SetComputeBuffer (byte stage, VertexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_encoder_set_compute_vertex_buffer(ptr, stage, buffer.handle, access); } /// /// Sets a dynamic index buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public void SetComputeBuffer (byte stage, DynamicIndexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_encoder_set_compute_dynamic_index_buffer(ptr, stage, buffer.handle, access); } /// /// Sets a dynamic vertex buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public void SetComputeBuffer (byte stage, DynamicVertexBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_encoder_set_compute_dynamic_vertex_buffer(ptr, stage, buffer.handle, access); } /// /// Sets an indirect buffer as a compute resource. /// /// The resource stage to set. /// The buffer to set. /// Access control flags. public void SetComputeBuffer (byte stage, IndirectBuffer buffer, ComputeBufferAccess access) { NativeMethods.bgfx_encoder_set_compute_indirect_buffer(ptr, stage, buffer.handle, access); } /// /// Dispatches a compute job. /// /// The index of the view to dispatch. /// The shader program to use. /// The size of the job in the first dimension. /// The size of the job in the second dimension. /// The size of the job in the third dimension. public void Dispatch (ushort id, Program program, int xCount = 1, int yCount = 1, int zCount = 1) { NativeMethods.bgfx_encoder_dispatch(ptr, id, program.handle, (uint)xCount, (uint)yCount, (uint)zCount); } /// /// Dispatches an indirect compute job. /// /// The index of the view to dispatch. /// The shader program to use. /// The buffer containing drawing commands. /// The index of the first command to process. /// The number of commands to process from the buffer. public void Dispatch (ushort id, Program program, IndirectBuffer indirectBuffer, int startIndex = 0, int count = 1) { NativeMethods.bgfx_encoder_dispatch_indirect(ptr, id, program.handle, indirectBuffer.handle, (ushort)startIndex, (ushort)count); } /// /// Discards all previously set state for the draw call. /// public void Discard () { NativeMethods.bgfx_encoder_discard(ptr); } /// /// Finishes submission of commands from this encoder. /// public void Dispose () { NativeMethods.bgfx_end(ptr); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (Encoder other) { return ptr == other.ptr; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as Encoder?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return ptr.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return ptr.ToString(); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator == (Encoder left, Encoder right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator != (Encoder left, Encoder right) { return !left.Equals(right); } } /// /// An aggregated frame buffer, with one or more attached texture surfaces. /// public unsafe struct FrameBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly FrameBuffer Invalid = new FrameBuffer(); /// /// Initializes a new instance of the struct. /// /// The width of the render target. /// The height of the render target. /// The format of the new surface. /// Texture sampling flags. public FrameBuffer (int width, int height, TextureFormat format, TextureFlags flags = TextureFlags.ClampU | TextureFlags.ClampV) { handle = NativeMethods.bgfx_create_frame_buffer((ushort)width, (ushort)height, format, flags); } /// /// Initializes a new instance of the struct. /// /// The amount to scale when the backbuffer resizes. /// The format of the new surface. /// Texture sampling flags. public FrameBuffer (BackbufferRatio ratio, TextureFormat format, TextureFlags flags = TextureFlags.ClampU | TextureFlags.ClampV) { handle = NativeMethods.bgfx_create_frame_buffer_scaled(ratio, format, flags); } /// /// Initializes a new instance of the struct. /// /// A set of attachments from which to build the frame buffer. /// if set to true, attached textures will be destroyed when the frame buffer is destroyed. public FrameBuffer (Attachment[] attachments, bool destroyTextures = false) { var count = (byte)attachments.Length; var native = stackalloc NativeAttachment[count]; for (int i = 0; i < count; i++) { var attachment = attachments[i]; native[i] = new NativeAttachment { access = attachment.Access, handle = attachment.Texture.handle, mip = (ushort)attachment.Mip, layer = (ushort)attachment.Layer, resolve = attachment.Resolve }; } handle = NativeMethods.bgfx_create_frame_buffer_from_attachment(count, native, destroyTextures); } /// /// Initializes a new instance of the struct. /// /// A set of textures from which to build the frame buffer. /// if set to true, attached textures will be destroyed when the frame buffer is destroyed. public FrameBuffer (Texture[] textures, bool destroyTextures = false) { var count = (byte)textures.Length; var native = stackalloc ushort[count]; for (int i = 0; i < count; i++) native[i] = textures[i].handle; handle = NativeMethods.bgfx_create_frame_buffer_from_handles(count, native, destroyTextures); } /// /// Initializes a new instance of the struct. /// /// The OS window handle to which the frame buffer is attached. /// The width of the render target. /// The height of the render target. /// A desired format for a depth buffer, if applicable. public FrameBuffer (IntPtr windowHandle, int width, int height, TextureFormat depthFormat = TextureFormat.UnknownDepth) { handle = NativeMethods.bgfx_create_frame_buffer_from_nwh(windowHandle, (ushort)width, (ushort)height, depthFormat); } /// /// Sets the name of the frame buffer, for debug display purposes. /// /// The name of the texture. public void SetName(string name) { NativeMethods.bgfx_set_frame_buffer_name(handle, name, int.MaxValue); } /// /// Releases the frame buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_frame_buffer(handle); } /// /// Gets the texture associated with a particular framebuffer attachment. /// /// The attachment index. /// The texture associated with the attachment. public Texture GetTexture (int attachment = 0) { var info = new Texture.TextureInfo(); return new Texture(NativeMethods.bgfx_get_texture(handle, (byte)attachment), ref info); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (FrameBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as FrameBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(FrameBuffer left, FrameBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(FrameBuffer left, FrameBuffer right) { return !left.Equals(right); } internal struct NativeAttachment { public ComputeBufferAccess access; public ushort handle; public ushort mip; public ushort layer; public ResolveFlags resolve; } } /// /// Represents a static index buffer. /// public unsafe struct IndexBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly IndexBuffer Invalid = new IndexBuffer(); /// /// Initializes a new instance of the struct. /// /// The 16-bit index data used to populate the buffer. /// Flags used to control buffer behavior. public IndexBuffer (MemoryBlock memory, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_index_buffer(memory.ptr, flags); } /// /// Sets the name of the index buffer, for debug display purposes. /// /// The name of the texture. public void SetName(string name) { NativeMethods.bgfx_set_index_buffer_name(handle, name, int.MaxValue); } /// /// Releases the index buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_index_buffer(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (IndexBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as IndexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(IndexBuffer left, IndexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(IndexBuffer left, IndexBuffer right) { return !left.Equals(right); } } /// /// Represents a buffer that can contain indirect drawing commands created and processed entirely on the GPU. /// public unsafe struct IndirectBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly IndirectBuffer Invalid = new IndirectBuffer(); /// /// Initializes a new instance of the struct. /// /// The number of commands that can fit in the buffer. public IndirectBuffer (int size) { handle = NativeMethods.bgfx_create_indirect_buffer(size); } /// /// Releases the index buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_indirect_buffer(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (IndirectBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as IndirectBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(IndirectBuffer left, IndirectBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(IndirectBuffer left, IndirectBuffer right) { return !left.Equals(right); } } /// /// Maintains a data buffer that contains instancing data. /// public unsafe struct InstanceDataBuffer : IEquatable { internal NativeStruct data; /// /// Represents an invalid handle. /// public static readonly InstanceDataBuffer Invalid = new InstanceDataBuffer(); /// /// A pointer that can be filled with instance data. /// public IntPtr Data { get { return data.data; } } /// /// The size of the data buffer. /// public int Size { get { return data.size; } } /// /// Initializes a new instance of the struct. /// /// The number of elements in the buffer. /// The stride of each element. public InstanceDataBuffer (int count, int stride) { NativeMethods.bgfx_alloc_instance_data_buffer(out data, count, (ushort)stride); } /// /// Gets the available space that can be used to allocate an instance buffer. /// /// The number of elements required. /// The stride of each element. /// The number of available elements. public static int GetAvailableSpace (int count, int stride) { return NativeMethods.bgfx_get_avail_instance_data_buffer(count, (ushort)stride); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (InstanceDataBuffer other) { return data.data == other.data.data && data.offset == other.data.offset && data.size == other.data.size; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as InstanceDataBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return (data.data.GetHashCode() ^ data.offset) >> 13 ^ data.size; } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Size: {0}", Size); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(InstanceDataBuffer left, InstanceDataBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(InstanceDataBuffer left, InstanceDataBuffer right) { return !left.Equals(right); } #pragma warning disable 649 internal struct NativeStruct { public IntPtr data; public int size; public int offset; public ushort stride; public ushort num; public ushort handle; } #pragma warning restore 649 } /// /// Exposes internal API data for interop scenarios. /// public struct InternalData { /// /// Pointer to internal Bgfx capabilities structure. Use instead. /// public IntPtr Caps; /// /// The underlying API's device context (OpenGL, Direct3D, etc). /// public IntPtr Context; } /// /// Represents a block of memory managed by the graphics API. /// public unsafe struct MemoryBlock : IEquatable { internal readonly DataPtr* ptr; /// /// Represents an invalid handle. /// public static readonly MemoryBlock Invalid = new MemoryBlock(); /// /// The pointer to the raw data. /// public IntPtr Data { get { return ptr == null ? IntPtr.Zero : ptr->Data; } } /// /// The size of the block, in bytes. /// public int Size { get { return ptr == null ? 0 : ptr->Size; } } MemoryBlock (DataPtr* ptr) { this.ptr = ptr; } /// /// Initializes a new instance of the struct. /// /// The size of the block, in bytes. public MemoryBlock (int size) { ptr = NativeMethods.bgfx_alloc(size); } /// /// Initializes a new instance of the struct. /// /// A pointer to the initial data to copy into the new block. /// The size of the block, in bytes. public MemoryBlock (IntPtr data, int size) { ptr = NativeMethods.bgfx_copy(data, size); } /// /// Copies a managed array into a native graphics memory block. /// /// The type of data in the array. /// The array to copy. /// The native memory block containing the copied data. public static MemoryBlock FromArray(T[] data) where T : struct { if (data == null || data.Length == 0) throw new ArgumentNullException("data"); var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var block = new MemoryBlock(gcHandle.AddrOfPinnedObject(), Marshal.SizeOf() * data.Length); gcHandle.Free(); return block; } /// /// Creates a reference to the given data. /// /// The type of data in the array. /// The array to reference. /// The native memory block referring to the data. /// /// The array must not be modified for at least 2 rendered frames. /// public static MemoryBlock MakeRef(T[] data) where T : struct { if (data == null || data.Length == 0) throw new ArgumentNullException("data"); var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned); return MakeRef(gcHandle.AddrOfPinnedObject(), Marshal.SizeOf() * data.Length, GCHandle.ToIntPtr(gcHandle), ReleaseHandleCallback); } /// /// Makes a reference to the given memory block. /// /// A pointer to the memory. /// The size of the memory block. /// Arbitrary user data passed to the release callback. /// A function that will be called when the data is ready to be released. /// A new memory block referring to the given data. /// /// The memory referred to by the returned memory block must not be modified /// or released until the callback fires. /// public static MemoryBlock MakeRef (IntPtr data, int size, IntPtr userData, ReleaseCallback callback) { return new MemoryBlock(NativeMethods.bgfx_make_ref_release(data, size, Marshal.GetFunctionPointerForDelegate(callback), userData)); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (MemoryBlock other) { return ptr == other.ptr; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as MemoryBlock?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return new IntPtr(ptr).GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Size: {0}", Size); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(MemoryBlock left, MemoryBlock right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(MemoryBlock left, MemoryBlock right) { return !left.Equals(right); } #pragma warning disable 649 internal struct DataPtr { public IntPtr Data; public int Size; } #pragma warning restore 649 static ReleaseCallback ReleaseHandleCallback = ReleaseHandle; static void ReleaseHandle (IntPtr userData) { var handle = GCHandle.FromIntPtr(userData); handle.Free(); } } /// /// Represents an occlusion query. /// public unsafe struct OcclusionQuery : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly OcclusionQuery Invalid = new OcclusionQuery(); /// /// Gets the result of the query. /// public OcclusionQueryResult Result { get { return NativeMethods.bgfx_get_result(handle, null); } } /// /// Gets the number of pixels that passed the test. Only valid /// if is also valid. /// public int PassingPixels { get { int pixels = 0; NativeMethods.bgfx_get_result(handle, &pixels); return pixels; } } OcclusionQuery (ushort handle) { this.handle = handle; } /// /// Creates a new query. /// /// The new occlusion query. public static OcclusionQuery Create() { return new OcclusionQuery(NativeMethods.bgfx_create_occlusion_query()); } /// /// Releases the query. /// public void Dispose () { NativeMethods.bgfx_destroy_occlusion_query(handle); } /// /// Sets the condition for which the query should check. /// /// true for visible; false for invisible. public void SetCondition (bool visible) { NativeMethods.bgfx_set_condition(handle, visible); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (OcclusionQuery other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as OcclusionQuery?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator == (OcclusionQuery left, OcclusionQuery right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator != (OcclusionQuery left, OcclusionQuery right) { return !left.Equals(right); } } /// /// Contains various performance metrics tracked by the library. /// public unsafe struct PerfStats { Stats* data; /// /// CPU time between two calls. /// public long CpuTimeFrame { get { return data->CpuTimeFrame; } } /// /// CPU frame start time. /// public long CpuTimeStart { get { return data->CpuTimeBegin; } } /// /// CPU frame end time. /// public long CpuTimeEnd { get { return data->CpuTimeEnd; } } /// /// CPU timer frequency. /// public long CpuTimerFrequency { get { return data->CpuTimerFrequency; } } /// /// Elapsed CPU time. /// public TimeSpan CpuElapsed { get { return TimeSpan.FromSeconds((double)(CpuTimeEnd - CpuTimeStart) / CpuTimerFrequency); } } /// /// GPU frame start time. /// public long GpuTimeStart { get { return data->GpuTimeBegin; } } /// /// GPU frame end time. /// public long GpuTimeEnd { get { return data->GpuTimeEnd; } } /// /// GPU timer frequency. /// public long GpuTimerFrequency { get { return data->GpuTimerFrequency; } } /// /// Elapsed GPU time. /// public TimeSpan GpuElapsed { get { return TimeSpan.FromSeconds((double)(GpuTimeEnd - GpuTimeStart) / GpuTimerFrequency); } } /// /// Time spent waiting for the render thread. /// public long WaitingForRender { get { return data->WaitRender; } } /// /// Time spent waiting for the submit thread. /// public long WaitingForSubmit { get { return data->WaitSubmit; } } /// /// The number of draw calls submitted. /// public int DrawCallsSubmitted { get { return data->NumDraw; } } /// /// The number of compute calls submitted. /// public int ComputeCallsSubmitted { get { return data->NumCompute; } } /// /// The number of blit calls submitted. /// public int BlitCallsSubmitted { get { return data->NumBlit; } } /// /// Maximum observed GPU driver latency. /// public int MaxGpuLatency { get { return data->MaxGpuLatency; } } /// /// Number of allocated dynamic index buffers. /// public int DynamicIndexBufferCount { get { return data->NumDynamicIndexBuffers; } } /// /// Number of allocated dynamic vertex buffers. /// public int DynamicVertexBufferCount { get { return data->NumDynamicVertexBuffers; } } /// /// Number of allocated frame buffers. /// public int FrameBufferCount { get { return data->NumFrameBuffers; } } /// /// Number of allocated index buffers. /// public int IndexBufferCount { get { return data->NumIndexBuffers; } } /// /// Number of allocated occlusion queries. /// public int OcclusionQueryCount { get { return data->NumOcclusionQueries; } } /// /// Number of allocated shader programs. /// public int ProgramCount { get { return data->NumPrograms; } } /// /// Number of allocated shaders. /// public int ShaderCount { get { return data->NumShaders; } } /// /// Number of allocated textures. /// public int TextureCount { get { return data->NumTextures; } } /// /// Number of allocated uniforms. /// public int UniformCount { get { return data->NumUniforms; } } /// /// Number of allocated vertex buffers. /// public int VertexBufferCount { get { return data->NumVertexBuffers; } } /// /// Number of allocated vertex declarations. /// public int VertexDeclarationCount { get { return data->NumVertexDecls; } } /// /// The amount of memory used by textures. /// public long TextureMemoryUsed { get { return data->TextureMemoryUsed; } } /// /// The amount of memory used by render targets. /// public long RenderTargetMemoryUsed { get { return data->RtMemoryUsed; } } /// /// The number of transient vertex buffers used. /// public int TransientVertexBuffersUsed { get { return data->TransientVbUsed; } } /// /// The number of transient index buffers used. /// public int TransientIndexBuffersUsed { get { return data->TransientIbUsed; } } /// /// Maximum available GPU memory. /// public long MaxGpuMemory { get { return data->GpuMemoryMax; } } /// /// The amount of GPU memory currently in use. /// public long GpuMemoryUsed { get { return data->GpuMemoryUsed; } } /// /// The width of the back buffer. /// public int BackbufferWidth { get { return data->Width; } } /// /// The height of the back buffer. /// public int BackbufferHeight { get { return data->Height; } } /// /// The width of the debug text buffer. /// public int TextBufferWidth { get { return data->TextWidth; } } /// /// The height of the debug text buffer. /// public int TextBufferHeight { get { return data->TextHeight; } } /// /// Gets a collection of statistics for each rendering view. /// public ViewStatsCollection Views { get { return new ViewStatsCollection(data->ViewStats, data->NumViews); } } static PerfStats() { Debug.Assert(Stats.NumTopologies == Enum.GetValues(typeof(Topology)).Length); } internal PerfStats (Stats* data) { this.data = data; } /// /// Gets the number of primitives rendered with the given topology. /// /// The topology whose primitive count should be returned. /// The number of primitives rendered. public int GetPrimitiveCount(Topology topology) { return (int)data->NumPrims[(int)topology]; } /// /// Contains perf metrics for a single rendering view. /// public struct ViewStats { ViewStatsNative* data; /// /// The name of the view. /// public string Name { get { return new string(data->Name); } } /// /// The amount of CPU time elapsed during processing of this view. /// public long CpuTimeElapsed { get { return (long)data->CpuTimeElapsed; } } /// /// The amount of GPU time elapsed during processing of this view. /// public long GpuTimeElapsed { get { return (long)data->GpuTimeElapsed; } } internal ViewStats(ViewStatsNative* data) { this.data = data; } } /// /// Provides access to a collection of view statistics. /// public struct ViewStatsCollection : IReadOnlyList { ViewStatsNative* data; int count; /// /// Accesses the element at the specified index. /// /// The index of the element to retrieve. /// The element at the given index. public ViewStats this[int index] { get { return new ViewStats(data + index); } } /// /// The number of elements in the collection. /// public int Count { get { return count; } } internal ViewStatsCollection(ViewStatsNative* data, int count) { this.data = data; this.count = count; } /// /// Gets an enumerator for the collection. /// /// A collection enumerator. public Enumerator GetEnumerator() { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Implements an enumerator for a ViewStatsCollection. /// public struct Enumerator : IEnumerator { ViewStatsCollection collection; int index; /// /// The current enumerated item. /// public ViewStats Current { get { return collection[index]; } } object IEnumerator.Current { get { return Current; } } internal Enumerator(ViewStatsCollection collection) { this.collection = collection; index = -1; } /// /// Advances to the next item in the sequence. /// /// true if there are more items in the collection; otherwise, false. public bool MoveNext() { var newIndex = index + 1; if (newIndex >= collection.Count) return false; index = newIndex; return true; } /// /// Empty; does nothing. /// public void Dispose() { } /// /// Not implemented. /// public void Reset() { throw new NotImplementedException(); } } } /// /// Contains perf metrics for a single encoder instance. /// public struct EncoderStats { EncoderStatsNative* data; /// /// CPU frame start time. /// public long CpuTimeStart { get { return data->CpuTimeBegin; } } /// /// CPU frame end time. /// public long CpuTimeEnd { get { return data->CpuTimeEnd; } } internal EncoderStats (EncoderStatsNative* data) { this.data = data; } } /// /// Provides access to a collection of encoder statistics. /// public struct EncoderStatsCollection : IReadOnlyList { EncoderStatsNative* data; int count; /// /// Accesses the element at the specified index. /// /// The index of the element to retrieve. /// The element at the given index. public EncoderStats this[int index] { get { return new EncoderStats(data + index); } } /// /// The number of elements in the collection. /// public int Count { get { return count; } } internal EncoderStatsCollection (EncoderStatsNative* data, int count) { this.data = data; this.count = count; } /// /// Gets an enumerator for the collection. /// /// A collection enumerator. public Enumerator GetEnumerator () { return new Enumerator(this); } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator(); } /// /// Implements an enumerator for an EncoderStatsCollection. /// public struct Enumerator : IEnumerator { EncoderStatsCollection collection; int index; /// /// The current enumerated item. /// public EncoderStats Current { get { return collection[index]; } } object IEnumerator.Current { get { return Current; } } internal Enumerator (EncoderStatsCollection collection) { this.collection = collection; index = -1; } /// /// Advances to the next item in the sequence. /// /// true if there are more items in the collection; otherwise, false. public bool MoveNext () { var newIndex = index + 1; if (newIndex >= collection.Count) return false; index = newIndex; return true; } /// /// Empty; does nothing. /// public void Dispose () { } /// /// Not implemented. /// public void Reset () { throw new NotImplementedException(); } } } #pragma warning disable 649 internal struct ViewStatsNative { public fixed char Name[256]; public ushort View; public ulong CpuTimeElapsed; public ulong GpuTimeElapsed; } internal struct EncoderStatsNative { public long CpuTimeBegin; public long CpuTimeEnd; } internal struct Stats { public const int NumTopologies = 5; public long CpuTimeFrame; public long CpuTimeBegin; public long CpuTimeEnd; public long CpuTimerFrequency; public long GpuTimeBegin; public long GpuTimeEnd; public long GpuTimerFrequency; public long WaitRender; public long WaitSubmit; public int NumDraw; public int NumCompute; public int NumBlit; public int MaxGpuLatency; public ushort NumDynamicIndexBuffers; public ushort NumDynamicVertexBuffers; public ushort NumFrameBuffers; public ushort NumIndexBuffers; public ushort NumOcclusionQueries; public ushort NumPrograms; public ushort NumShaders; public ushort NumTextures; public ushort NumUniforms; public ushort NumVertexBuffers; public ushort NumVertexDecls; public long TextureMemoryUsed; public long RtMemoryUsed; public int TransientVbUsed; public int TransientIbUsed; public fixed uint NumPrims[NumTopologies]; public long GpuMemoryMax; public long GpuMemoryUsed; public ushort Width; public ushort Height; public ushort TextWidth; public ushort TextHeight; public ushort NumViews; public ViewStatsNative* ViewStats; public byte NumEncoders; public EncoderStatsNative* EncoderStats; } #pragma warning restore 649 } /// /// Contains platform-specific data used to hook into the bgfx library. /// public struct PlatformData { /// /// EGL native display type. /// public IntPtr DisplayType; /// /// Platform window handle. /// public IntPtr WindowHandle; /// /// Device context to use instead of letting the library create its own. /// public IntPtr Context; /// /// Backbuffer pointer to use instead of letting the library create its own. /// public IntPtr Backbuffer; /// /// Depth-stencil pointer to use instead of letting the library create its own. /// public IntPtr BackbufferDepthStencil; } /// /// Represents a compiled and linked shader program. /// public struct Program : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly Program Invalid = new Program(); /// /// Initializes a new instance of the struct. /// /// The vertex shader. /// The fragment shader. /// if set to true, the shaders will be released after creating the program. public Program (Shader vertexShader, Shader fragmentShader, bool destroyShaders = false) { handle = NativeMethods.bgfx_create_program(vertexShader.handle, fragmentShader.handle, destroyShaders); } /// /// Initializes a new instance of the struct. /// /// The compute shader. /// if set to true, the compute shader will be released after creating the program. public Program (Shader computeShader, bool destroyShaders = false) { handle = NativeMethods.bgfx_create_compute_program(computeShader.handle, destroyShaders); } /// /// Releases the program. /// public void Dispose () { NativeMethods.bgfx_destroy_program(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (Program other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as Program?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(Program left, Program right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(Program left, Program right) { return !left.Equals(right); } } /// /// Specifies state information used to configure rendering operations. /// public struct RenderState : IEquatable { const int AlphaRefShift = 40; const int PointSizeShift = 52; const ulong AlphaRefMask = 0x0000ff0000000000; const ulong PointSizeMask = 0x0ff0000000000000; readonly ulong value; /// /// No state bits set. /// public static readonly RenderState None = 0; /// /// Enable writing the Red color channel to the framebuffer. /// public static readonly RenderState WriteR = 0x0000000000000001; /// /// Enable writing the Green color channel to the framebuffer. /// public static readonly RenderState WriteG = 0x0000000000000002; /// /// Enable writing the Blue color channel to the framebuffer. /// public static readonly RenderState WriteB = 0x0000000000000004; /// /// Enable writing alpha data to the framebuffer. /// public static readonly RenderState WriteA = 0x0000000000000008; /// /// Enable writing to the depth buffer. /// public static readonly RenderState WriteZ = 0x0000004000000000; /// /// Enable writing all three color channels to the framebuffer. /// public static readonly RenderState WriteRGB = WriteR | WriteG | WriteB; /// /// Use a "less than" comparison to pass the depth test. /// public static readonly RenderState DepthTestLess = 0x0000000000000010; /// /// Use a "less than or equal to" comparison to pass the depth test. /// public static readonly RenderState DepthTestLessEqual = 0x0000000000000020; /// /// Pass the depth test if both values are equal. /// public static readonly RenderState DepthTestEqual = 0x0000000000000030; /// /// Use a "greater than or equal to" comparison to pass the depth test. /// public static readonly RenderState DepthTestGreaterEqual = 0x0000000000000040; /// /// Use a "greater than" comparison to pass the depth test. /// public static readonly RenderState DepthTestGreater = 0x0000000000000050; /// /// Pass the depth test if both values are not equal. /// public static readonly RenderState DepthTestNotEqual = 0x0000000000000060; /// /// Never pass the depth test. /// public static readonly RenderState DepthTestNever = 0x0000000000000070; /// /// Always pass the depth test. /// public static readonly RenderState DepthTestAlways = 0x0000000000000080; /// /// Use a value of 0 as an input to a blend equation. /// public static readonly RenderState BlendZero = 0x0000000000001000; /// /// Use a value of 1 as an input to a blend equation. /// public static readonly RenderState BlendOne = 0x0000000000002000; /// /// Use the source pixel color as an input to a blend equation. /// public static readonly RenderState BlendSourceColor = 0x0000000000003000; /// /// Use one minus the source pixel color as an input to a blend equation. /// public static readonly RenderState BlendInverseSourceColor = 0x0000000000004000; /// /// Use the source pixel alpha as an input to a blend equation. /// public static readonly RenderState BlendSourceAlpha = 0x0000000000005000; /// /// Use one minus the source pixel alpha as an input to a blend equation. /// public static readonly RenderState BlendInverseSourceAlpha = 0x0000000000006000; /// /// Use the destination pixel alpha as an input to a blend equation. /// public static readonly RenderState BlendDestinationAlpha = 0x0000000000007000; /// /// Use one minus the destination pixel alpha as an input to a blend equation. /// public static readonly RenderState BlendInverseDestinationAlpha = 0x0000000000008000; /// /// Use the destination pixel color as an input to a blend equation. /// public static readonly RenderState BlendDestinationColor = 0x0000000000009000; /// /// Use one minus the destination pixel color as an input to a blend equation. /// public static readonly RenderState BlendInverseDestinationColor = 0x000000000000a000; /// /// Use the source pixel alpha (saturated) as an input to a blend equation. /// public static readonly RenderState BlendSourceAlphaSaturate = 0x000000000000b000; /// /// Use an application supplied blending factor as an input to a blend equation. /// public static readonly RenderState BlendFactor = 0x000000000000c000; /// /// Use one minus an application supplied blending factor as an input to a blend equation. /// public static readonly RenderState BlendInverseFactor = 0x000000000000d000; /// /// Blend equation: A + B /// public static readonly RenderState BlendEquationAdd = 0x0000000000000000; /// /// Blend equation: B - A /// public static readonly RenderState BlendEquationSub = 0x0000000010000000; /// /// Blend equation: A - B /// public static readonly RenderState BlendEquationReverseSub = 0x0000000020000000; /// /// Blend equation: min(a, b) /// public static readonly RenderState BlendEquationMin = 0x0000000030000000; /// /// Blend equation: max(a, b) /// public static readonly RenderState BlendEquationMax = 0x0000000040000000; /// /// Enable independent blending of simultaenous render targets. /// public static readonly RenderState BlendIndependent = 0x0000000400000000; /// /// Enable alpha to coverage blending. /// public static readonly RenderState BlendAlphaToCoverage = 0x0000000800000000; /// /// Don't perform culling of back faces. /// public static readonly RenderState NoCulling = 0x0000000000000000; /// /// Perform culling of clockwise faces. /// public static readonly RenderState CullClockwise = 0x0000001000000000; /// /// Perform culling of counter-clockwise faces. /// public static readonly RenderState CullCounterclockwise = 0x0000002000000000; /// /// Primitive topology: triangle list. /// public static readonly RenderState PrimitiveTriangles = 0x0000000000000000; /// /// Primitive topology: triangle strip. /// public static readonly RenderState PrimitiveTriangleStrip = 0x0001000000000000; /// /// Primitive topology: line list. /// public static readonly RenderState PrimitiveLines = 0x0002000000000000; /// /// Primitive topology: line strip. /// public static readonly RenderState PrimitiveLineStrip = 0x0003000000000000; /// /// Primitive topology: point list. /// public static readonly RenderState PrimitivePoints = 0x0004000000000000; /// /// Enable multisampling. /// public static readonly RenderState Multisampling = 0x1000000000000000; /// /// Enable line antialiasing. /// public static readonly RenderState LineAA = 0x2000000000000000; /// /// Enable conservative rasterization. /// public static readonly RenderState ConservativeRasterization = 0x4000000000000000; /// /// Provides a set of sane defaults. /// public static readonly RenderState Default = WriteRGB | WriteA | WriteZ | DepthTestLess | CullClockwise | Multisampling; /// /// Predefined blend effect: additive blending. /// public static readonly RenderState BlendAdd = BlendFunction(BlendOne, BlendOne); /// /// Predefined blend effect: alpha blending. /// public static readonly RenderState BlendAlpha = BlendFunction(BlendSourceAlpha, BlendInverseSourceAlpha); /// /// Predefined blend effect: "darken" blending. /// public static readonly RenderState BlendDarken = BlendFunction(BlendOne, BlendOne) | BlendEquation(BlendEquationMin); /// /// Predefined blend effect: "lighten" blending. /// public static readonly RenderState BlendLighten = BlendFunction(BlendOne, BlendOne) | BlendEquation(BlendEquationMax); /// /// Predefined blend effect: multiplicative blending. /// public static readonly RenderState BlendMultiply = BlendFunction(BlendDestinationColor, BlendZero); /// /// Predefined blend effect: normal blending based on alpha. /// public static readonly RenderState BlendNormal = BlendFunction(BlendOne, BlendInverseSourceAlpha); /// /// Predefined blend effect: "screen" blending. /// public static readonly RenderState BlendScreen = BlendFunction(BlendOne, BlendInverseSourceColor); /// /// Predefined blend effect: "linear burn" blending. /// public static readonly RenderState BlendLinearBurn = BlendFunction(BlendDestinationColor, BlendInverseDestinationColor) | BlendEquation(BlendEquationSub); /// /// Initializes a new instance of the struct. /// /// The integer value of the state. public RenderState (long value) { this.value = (ulong)value; } /// /// Encodes an alpha reference value in a render state. /// /// The alpha reference value. /// The encoded render state. public static RenderState AlphaRef (byte alpha) { return (((ulong)alpha) << AlphaRefShift) & AlphaRefMask; } /// /// Encodes a point size value in a render state. /// /// The point size. /// The encoded render state. public static RenderState PointSize (byte size) { return (((ulong)size) << PointSizeShift) & PointSizeMask; } /// /// Builds a render state for a blend function. /// /// The source blend operation. /// The destination blend operation. /// The render state for the blend function. public static RenderState BlendFunction (RenderState source, RenderState destination) { return BlendFunction(source, destination, source, destination); } /// /// Builds a render state for a blend function. /// /// The source color blend operation. /// The destination color blend operation. /// The source alpha blend operation. /// The destination alpha blend operation. /// /// The render state for the blend function. /// public static RenderState BlendFunction (RenderState sourceColor, RenderState destinationColor, RenderState sourceAlpha, RenderState destinationAlpha) { return (sourceColor | (destinationColor << 4)) | ((sourceAlpha | (destinationAlpha << 4)) << 8); } /// /// Builds a render state for a blend equation. /// /// The equation. /// /// The render state for the blend equation. /// public static RenderState BlendEquation (RenderState equation) { return BlendEquation(equation, equation); } /// /// Builds a render state for a blend equation. /// /// The source equation. /// The alpha equation. /// /// The render state for the blend equation. /// public static RenderState BlendEquation (RenderState sourceEquation, RenderState alphaEquation) { return sourceEquation | (alphaEquation << 3); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return value.GetHashCode(); } /// /// Determines whether the specific value is equal to this instance. /// /// The value to compare with this instance. /// true if the value is equal to this instance; otherwise, false. public bool Equals (RenderState other) { return value == other.value; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var state = obj as RenderState?; if (state == null) return false; return Equals(state); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(RenderState left, RenderState right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(RenderState left, RenderState right) { return !left.Equals(right); } /// /// Performs an implicit conversion from ulong. /// /// The value to convert. public static implicit operator RenderState (ulong value) { return new RenderState((long)value); } /// /// Performs an explicit conversion to ulong. /// /// The value to convert. public static explicit operator ulong (RenderState state) { return state.value; } /// /// Implements the bitwise-or operator. /// /// The left side of the operator. /// The right side of the operator. /// /// The result of the operator. /// public static RenderState operator |(RenderState left, RenderState right) { return left.value | right.value; } /// /// Implements the bitwise-and operator. /// /// The left side of the operator. /// The right side of the operator. /// /// The result of the operator. /// public static RenderState operator &(RenderState left, RenderState right) { return left.value & right.value; } /// /// Implements the bitwise-complement operator. /// /// The operand. /// /// The result of the operator. /// public static RenderState operator ~(RenderState state) { return ~state.value; } /// /// Implements the left shift operator. /// /// The value to shift. /// The amount to shift. /// /// The result of the operator. /// public static RenderState operator <<(RenderState state, int amount) { return state.value << amount; } /// /// Implements the right shift operator. /// /// The value to shift. /// The amount to shift. /// /// The result of the operator. /// public static RenderState operator >>(RenderState state, int amount) { return state.value >> amount; } } /// /// Represents a single compiled shader component. /// public unsafe struct Shader : IDisposable, IEquatable { Uniform[] uniforms; internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly Shader Invalid = new Shader(); /// /// The set of uniforms exposed by the shader. /// public IReadOnlyList Uniforms { get { if (uniforms == null) { var count = NativeMethods.bgfx_get_shader_uniforms(handle, null, 0); uniforms = new Uniform[count]; NativeMethods.bgfx_get_shader_uniforms(handle, uniforms, count); } return uniforms; } } /// /// Initializes a new instance of the struct. /// /// The compiled shader memory. public Shader (MemoryBlock memory) { handle = NativeMethods.bgfx_create_shader(memory.ptr); uniforms = null; } /// /// Releases the shader. /// public void Dispose () { NativeMethods.bgfx_destroy_shader(handle); } /// /// Sets the name of the shader, for debug display purposes. /// /// The name of the shader. public void SetName(string name) { NativeMethods.bgfx_set_shader_name(handle, name, int.MaxValue); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (Shader other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as Shader?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(Shader left, Shader right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(Shader left, Shader right) { return !left.Equals(right); } } /// /// Specifies state information used to configure rendering operations. /// public struct StencilFlags : IEquatable { const int ReadMaskShift = 8; const uint RefMask = 0x000000ff; const uint ReadMaskMask = 0x0000ff00; readonly uint value; /// /// No state bits set. /// public static readonly StencilFlags None = 0; /// /// Perform a "less than" stencil test. /// public static readonly StencilFlags TestLess = 0x00010000; /// /// Perform a "less than or equal" stencil test. /// public static readonly StencilFlags TestLessEqual = 0x00020000; /// /// Perform an equality stencil test. /// public static readonly StencilFlags TestEqual = 0x00030000; /// /// Perform a "greater than or equal" stencil test. /// public static readonly StencilFlags TestGreaterEqual = 0x00040000; /// /// Perform a "greater than" stencil test. /// public static readonly StencilFlags TestGreater = 0x00050000; /// /// Perform an inequality stencil test. /// public static readonly StencilFlags TestNotEqual = 0x00060000; /// /// Never pass the stencil test. /// public static readonly StencilFlags TestNever = 0x00070000; /// /// Always pass the stencil test. /// public static readonly StencilFlags TestAlways = 0x00080000; /// /// On failing the stencil test, zero out the stencil value. /// public static readonly StencilFlags FailSZero = 0x00000000; /// /// On failing the stencil test, keep the old stencil value. /// public static readonly StencilFlags FailSKeep = 0x00100000; /// /// On failing the stencil test, replace the stencil value. /// public static readonly StencilFlags FailSReplace = 0x00200000; /// /// On failing the stencil test, increment the stencil value. /// public static readonly StencilFlags FailSIncrement = 0x00300000; /// /// On failing the stencil test, increment the stencil value (with saturation). /// public static readonly StencilFlags FailSIncrementSaturate = 0x00400000; /// /// On failing the stencil test, decrement the stencil value. /// public static readonly StencilFlags FailSDecrement = 0x00500000; /// /// On failing the stencil test, decrement the stencil value (with saturation). /// public static readonly StencilFlags FailSDecrementSaturate = 0x00600000; /// /// On failing the stencil test, invert the stencil value. /// public static readonly StencilFlags FailSInvert = 0x00700000; /// /// On failing the stencil test, zero out the depth value. /// public static readonly StencilFlags FailZZero = 0x00000000; /// /// On failing the stencil test, keep the depth value. /// public static readonly StencilFlags FailZKeep = 0x01000000; /// /// On failing the stencil test, replace the depth value. /// public static readonly StencilFlags FailZReplace = 0x02000000; /// /// On failing the stencil test, increment the depth value. /// public static readonly StencilFlags FailZIncrement = 0x03000000; /// /// On failing the stencil test, increment the depth value (with saturation). /// public static readonly StencilFlags FailZIncrementSaturate = 0x04000000; /// /// On failing the stencil test, decrement the depth value. /// public static readonly StencilFlags FailZDecrement = 0x05000000; /// /// On failing the stencil test, decrement the depth value (with saturation). /// public static readonly StencilFlags FailZDecrementSaturate = 0x06000000; /// /// On failing the stencil test, invert the depth value. /// public static readonly StencilFlags FailZInvert = 0x07000000; /// /// On passing the stencil test, zero out the depth value. /// public static readonly StencilFlags PassZZero = 0x00000000; /// /// On passing the stencil test, keep the old depth value. /// public static readonly StencilFlags PassZKeep = 0x10000000; /// /// On passing the stencil test, replace the depth value. /// public static readonly StencilFlags PassZReplace = 0x20000000; /// /// On passing the stencil test, increment the depth value. /// public static readonly StencilFlags PassZIncrement = 0x30000000; /// /// On passing the stencil test, increment the depth value (with saturation). /// public static readonly StencilFlags PassZIncrementSaturate = 0x40000000; /// /// On passing the stencil test, decrement the depth value. /// public static readonly StencilFlags PassZDecrement = 0x50000000; /// /// On passing the stencil test, decrement the depth value (with saturation). /// public static readonly StencilFlags PassZDecrementSaturate = 0x60000000; /// /// On passing the stencil test, invert the depth value. /// public static readonly StencilFlags PassZInvert = 0x70000000; /// /// Initializes a new instance of the struct. /// /// The integer value of the state. public StencilFlags (int value) { this.value = (uint)value; } /// /// Encodes a reference value in a stencil state. /// /// The stencil reference value. /// The encoded stencil state. public static StencilFlags ReferenceValue (byte reference) { return reference & RefMask; } /// /// Encodes a read mask in a stencil state. /// /// The mask. /// /// The encoded stencil state. /// public static StencilFlags ReadMask (byte mask) { return (((uint)mask) << ReadMaskShift) & ReadMaskMask; } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return value.GetHashCode(); } /// /// Determines whether the specific value is equal to this instance. /// /// The value to compare with this instance. /// true if the value is equal to this instance; otherwise, false. public bool Equals (StencilFlags other) { return value == other.value; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var state = obj as StencilFlags?; if (state == null) return false; return Equals(state); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(StencilFlags left, StencilFlags right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(StencilFlags left, StencilFlags right) { return !left.Equals(right); } /// /// Performs an implicit conversion from uint. /// /// The value to convert. public static implicit operator StencilFlags (uint value) { return new StencilFlags((int)value); } /// /// Performs an explicit conversion to uint. /// /// The value to convert. public static explicit operator uint (StencilFlags state) { return state.value; } /// /// Implements the bitwise-or operator. /// /// The left side of the operator. /// The right side of the operator. /// /// The result of the operator. /// public static StencilFlags operator |(StencilFlags left, StencilFlags right) { return left.value | right.value; } /// /// Implements the bitwise-and operator. /// /// The left side of the operator. /// The right side of the operator. /// /// The result of the operator. /// public static StencilFlags operator &(StencilFlags left, StencilFlags right) { return left.value & right.value; } /// /// Implements the bitwise-complement operator. /// /// The operand. /// /// The result of the operator. /// public static StencilFlags operator ~(StencilFlags state) { return ~state.value; } /// /// Implements the left shift operator. /// /// The value to shift. /// The amount to shift. /// /// The result of the operator. /// public static StencilFlags operator <<(StencilFlags state, int amount) { return state.value << amount; } /// /// Implements the right shift operator. /// /// The value to shift. /// The amount to shift. /// /// The result of the operator. /// public static StencilFlags operator >>(StencilFlags state, int amount) { return state.value >> amount; } } /// /// Maintains a transient index buffer. /// /// /// The contents of the buffer are valid for the current frame only. /// You must call SetVertexBuffer with the buffer or a leak could occur. /// public unsafe struct TransientIndexBuffer : IEquatable { readonly IntPtr data; int size; int startIndex; readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly TransientIndexBuffer Invalid = new TransientIndexBuffer(); /// /// A pointer that can be filled with index data. /// public IntPtr Data { get { return data; } } /// /// The size of the buffer. /// public int Count { get { return size; } } /// /// Initializes a new instance of the struct. /// /// The number of 16-bit indices that fit in the buffer. public TransientIndexBuffer (int indexCount) { NativeMethods.bgfx_alloc_transient_index_buffer(out this, indexCount); } /// /// Gets the available space in the global transient index buffer. /// /// The number of 16-bit indices required. /// The number of available indices. public static int GetAvailableSpace (int count) { return NativeMethods.bgfx_get_avail_transient_index_buffer(count); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (TransientIndexBuffer other) { return handle == other.handle && data == other.data; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as TransientIndexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode() >> 13 ^ data.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Count: {0}", Count); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(TransientIndexBuffer left, TransientIndexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(TransientIndexBuffer left, TransientIndexBuffer right) { return !left.Equals(right); } } /// /// Maintains a transient vertex buffer. /// /// /// The contents of the buffer are valid for the current frame only. /// You must call SetVertexBuffer with the buffer or a leak could occur. /// public unsafe struct TransientVertexBuffer : IEquatable { readonly IntPtr data; int size; int startVertex; ushort stride; readonly ushort handle; ushort decl; /// /// Represents an invalid handle. /// public static readonly TransientVertexBuffer Invalid = new TransientVertexBuffer(); /// /// A pointer that can be filled with vertex data. /// public IntPtr Data { get { return data; } } /// /// The size of the buffer. /// public int Count { get { return size; } } /// /// Initializes a new instance of the struct. /// /// The number of vertices that fit in the buffer. /// The layout of the vertex data. public TransientVertexBuffer (int vertexCount, VertexLayout layout) { NativeMethods.bgfx_alloc_transient_vertex_buffer(out this, vertexCount, ref layout.data); } /// /// Gets the available space in the global transient vertex buffer. /// /// The number of vertices required. /// The layout of each vertex. /// The number of available vertices. public static int GetAvailableSpace (int count, VertexLayout layout) { return NativeMethods.bgfx_get_avail_transient_vertex_buffer(count, ref layout.data); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (TransientVertexBuffer other) { return handle == other.handle && data == other.data; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as TransientVertexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode() >> 13 ^ data.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(TransientVertexBuffer left, TransientVertexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(TransientVertexBuffer left, TransientVertexBuffer right) { return !left.Equals(right); } } /// /// Represents a shader uniform. /// public unsafe struct Uniform : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly Uniform Invalid = new Uniform(); /// /// The name of the uniform. /// public string Name { get { Info info; NativeMethods.bgfx_get_uniform_info(handle, out info); return Marshal.PtrToStringAnsi(new IntPtr(info.name)); } } /// /// The type of the data represented by the uniform. /// public UniformType Type { get { Info info; NativeMethods.bgfx_get_uniform_info(handle, out info); return info.type; } } /// /// Size of the array, if the uniform is an array type. /// public int ArraySize { get { Info info; NativeMethods.bgfx_get_uniform_info(handle, out info); return info.arraySize; } } /// /// Initializes a new instance of the struct. /// /// The name of the uniform. /// The type of data represented by the uniform. /// Size of the array, if the uniform is an array type. /// /// Predefined uniform names: /// u_viewRect vec4(x, y, width, height) - view rectangle for current view. /// u_viewTexel vec4 (1.0/width, 1.0/height, undef, undef) - inverse width and height /// u_view mat4 - view matrix /// u_invView mat4 - inverted view matrix /// u_proj mat4 - projection matrix /// u_invProj mat4 - inverted projection matrix /// u_viewProj mat4 - concatenated view projection matrix /// u_invViewProj mat4 - concatenated inverted view projection matrix /// u_model mat4[BGFX_CONFIG_MAX_BONES] - array of model matrices. /// u_modelView mat4 - concatenated model view matrix, only first model matrix from array is used. /// u_modelViewProj mat4 - concatenated model view projection matrix. /// u_alphaRef float - alpha reference value for alpha test. /// public Uniform (string name, UniformType type, int arraySize = 1) { handle = NativeMethods.bgfx_create_uniform(name, type, (ushort)arraySize); } /// /// Releases the uniform. /// public void Dispose () { NativeMethods.bgfx_destroy_uniform(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (Uniform other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as Uniform?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(Uniform left, Uniform right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(Uniform left, Uniform right) { return !left.Equals(right); } internal struct Info { public fixed sbyte name[256]; public UniformType type; public ushort arraySize; } } /// /// Represents a static vertex buffer. /// public unsafe struct VertexBuffer : IDisposable, IEquatable { internal readonly ushort handle; /// /// Represents an invalid handle. /// public static readonly VertexBuffer Invalid = new VertexBuffer(); /// /// Initializes a new instance of the struct. /// /// The vertex data with which to populate the buffer. /// The layout of the vertex data. /// Flags used to control buffer behavior. public VertexBuffer (MemoryBlock memory, VertexLayout layout, BufferFlags flags = BufferFlags.None) { handle = NativeMethods.bgfx_create_vertex_buffer(memory.ptr, ref layout.data, flags); } /// /// Sets the name of the vertex buffer, for debug display purposes. /// /// The name of the texture. public void SetName(string name) { NativeMethods.bgfx_set_vertex_buffer_name(handle, name, int.MaxValue); } /// /// Releases the vertex buffer. /// public void Dispose () { NativeMethods.bgfx_destroy_vertex_buffer(handle); } /// /// Determines whether the specified object is equal to this instance. /// /// The object to compare with this instance. /// true if the specified object is equal to this instance; otherwise, false. public bool Equals (VertexBuffer other) { return handle == other.handle; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals (object obj) { var other = obj as VertexBuffer?; if (other == null) return false; return Equals(other); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode () { return handle.GetHashCode(); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString () { return string.Format("Handle: {0}", handle); } /// /// Implements the equality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are equal; otherwise, false. /// public static bool operator ==(VertexBuffer left, VertexBuffer right) { return left.Equals(right); } /// /// Implements the inequality operator. /// /// The left side of the operator. /// The right side of the operator. /// /// true if the two objects are not equal; otherwise, false. /// public static bool operator !=(VertexBuffer left, VertexBuffer right) { return !left.Equals(right); } } /// /// Specifies scaling relative to the size of the backbuffer. /// public enum BackbufferRatio { /// /// Surface is equal to the backbuffer size. /// Equal, /// /// Surface is half the backbuffer size. /// Half, /// /// Surface is a quater of the backbuffer size. /// Quater, /// /// Surface is an eighth of the backbuffer size. /// Eighth, /// /// Surface is a sixteenth of the backbuffer size. /// Sixteenth, /// /// Surface is double the backbuffer size. /// Double } /// /// Specifies various flags that control vertex and index buffer behavior. /// [Flags] public enum BufferFlags : short { /// /// No flags specified. /// None, /// /// Specifies the format of data in a compute buffer as being 8x1. /// ComputeFormat8x1 = 0x1, /// /// Specifies the format of data in a compute buffer as being 8x2. /// ComputeFormat8x2 = 0x2, /// /// Specifies the format of data in a compute buffer as being 8x4. /// ComputeFormat8x4 = 0x3, /// /// Specifies the format of data in a compute buffer as being 16x1. /// ComputeFormat16x1 = 0x4, /// /// Specifies the format of data in a compute buffer as being 16x2. /// ComputeFormat16x2 = 0x5, /// /// Specifies the format of data in a compute buffer as being 16x4. /// ComputeFormat16x4 = 0x6, /// /// Specifies the format of data in a compute buffer as being 32x1. /// ComputeFormat32x1 = 0x7, /// /// Specifies the format of data in a compute buffer as being 32x2. /// ComputeFormat32x2 = 0x8, /// /// Specifies the format of data in a compute buffer as being 32x4. /// ComputeFormat32x4 = 0x9, /// /// Specifies the type of data in a compute buffer as being unsigned integers. /// ComputeTypeInt = 0x10, /// /// Specifies the type of data in a compute buffer as being signed integers. /// ComputeTypeUInt = 0x20, /// /// Specifies the type of data in a compute buffer as being floating point values. /// ComputeTypeFloat = 0x30, /// /// Buffer will be read by a compute shader. /// ComputeRead = 0x100, /// /// Buffer will be written into by a compute shader. It cannot be accessed by the CPU. /// ComputeWrite = 0x200, /// /// Buffer is the source of indirect draw commands. /// DrawIndirect = 0x400, /// /// Buffer will resize on update if a different quantity of data is passed. If this flag is not set /// the data will be trimmed to fit in the existing buffer size. Effective only for dynamic buffers. /// AllowResize = 0x800, /// /// Buffer is using 32-bit indices. Useful only for index buffers. /// Index32 = 0x1000, /// /// Buffer will be read and written by a compute shader. /// ComputeReadWrite = ComputeRead | ComputeWrite } /// /// Specifies flags for clearing surfaces. /// [Flags] public enum ClearTargets : short { /// /// Don't clear anything. /// None = 0, /// /// Clear the color channels. /// Color = 0x1, /// /// Clear the depth buffer. /// Depth = 0x2, /// /// Clear the stencil buffer. /// Stencil = 0x4, /// /// Discard the first color framebuffer. /// DiscardColor0 = 0x8, /// /// Discard the second color framebuffer. /// DiscardColor1 = 0x10, /// /// Discard the third color framebuffer. /// DiscardColor2 = 0x20, /// /// Discard the fourth color framebuffer. /// DiscardColor3 = 0x40, /// /// Discard the fifth color framebuffer. /// DiscardColor4 = 0x80, /// /// Discard the sixth color framebuffer. /// DiscardColor5 = 0x100, /// /// Discard the seventh color framebuffer. /// DiscardColor6 = 0x200, /// /// Discard the eighth color framebuffer. /// DiscardColor7 = 0x400, /// /// Discard the depth buffer. /// DiscardDepth = 0x800, /// /// Discard the stencil buffer. /// DiscardStencil = 0x1000, } /// /// Describes access rights for a compute buffer. /// public enum ComputeBufferAccess { /// /// The buffer can only be read. /// Read, /// /// The buffer can only be written to. /// Write, /// /// The buffer can be read and written. /// ReadWrite } /// /// Addresses a particular face of a cube map. /// public enum CubeMapFace : byte { /// /// The right face. /// Right, /// /// The left face. /// Left, /// /// The top face. /// Top, /// /// The bottom face. /// Bottom, /// /// The front face. /// Front, /// /// The back face. /// Back } /// /// Specifies debug text colors. /// public enum DebugColor { /// /// Black. /// Black, /// /// Blue. /// Blue, /// /// Green. /// Green, /// /// Cyan. /// Cyan, /// /// Red. /// Red, /// /// Magenta. /// Magenta, /// /// Brown. /// Brown, /// /// Light gray. /// LightGray, /// /// Dark gray. /// DarkGray, /// /// Light blue. /// LightBlue, /// /// Light green. /// LightGreen, /// /// Light cyan. /// LightCyan, /// /// Light red. /// LightRed, /// /// Light magenta. /// LightMagenta, /// /// Yellow. /// Yellow, /// /// White. /// White } /// /// Specifies various debug options. /// [Flags] public enum DebugFeatures { /// /// Don't enable any debugging features. /// None = 0, /// /// Force wireframe rendering. /// Wireframe = 0x1, /// /// When set, all rendering calls are skipped. This is useful when profiling to /// find bottlenecks between the CPU and GPU. /// InfinitelyFastHardware = 0x2, /// /// Display internal statistics. /// DisplayStatistics = 0x4, /// /// Display debug text. /// DisplayText = 0x8, /// /// Enable the internal library performance profiler. /// Profiler = 0x10 } /// /// Specifies various capabilities supported by the rendering device. /// [Flags] public enum DeviceFeatures : long { /// /// No extra features supported. /// None = 0, /// /// Device supports alpha to coverage. /// AlphaToCoverage = 0x1, /// /// Device supports independent blending of simultaneous render targets. /// BlendIndependent = 0x2, /// /// Device supports compute shaders. /// Compute = 0x4, /// /// Device supports conservative rasterization. /// ConservativeRasterization = 0x8, /// /// Device supports indirect drawing via GPU buffers. /// DrawIndirect = 0x10, /// /// Fragment shaders can access depth values. /// FragmentDepth = 0x20, /// /// Device supports ordering of fragment output. /// FragmentOrdering = 0x40, /// /// Read/write framebuffer attachments are supported. /// FramebufferRW = 0x80, /// /// A graphics debugger is present. /// GraphicsDebugger = 0x100, /// /// Devices supports HDR10 rendering. /// HDR10 = 0x400, /// /// Device supports high-DPI rendering. /// HighDPI = 0x800, /// /// Device supports 32-bit indices. /// Index32 = 0x1000, /// /// Device supports instancing. /// Instancing = 0x2000, /// /// Device supports occlusion queries. /// OcclusionQuery = 0x4000, /// /// Device supports multithreaded rendering. /// RendererMultithreaded = 0x8000, /// /// Indicates whether the device can render to multiple swap chains. /// SwapChain = 0x10000, /// /// Device supports 2D texture arrays. /// Texture2DArray = 0x20000, /// /// Device supports 3D textures. /// Texture3D = 0x40000, /// /// Device supports texture blits. /// TextureBlit = 0x80000, /// /// Device supports other texture comparison modes. /// TextureCompareExtended = 0x100000, /// /// Device supports "Less than or equal to" texture comparison mode. /// TextureCompareLessEqual = 0x200000, /// /// Device supports all texture comparison modes. /// TextureCompareAll = TextureCompareLessEqual | TextureCompareExtended, /// /// Device supports cubemap texture arrays. /// TextureCubeArray = 0x400000, /// /// Device supports directly accessing texture data. /// TextureDirectAccess = 0x800000, /// /// Device supports reading back texture data. /// TextureReadBack = 0x1000000, /// /// Device supports 16-bit floats as vertex attributes. /// VertexAttributeHalf = 0x2000000, /// /// UInt10 vertex attributes are supported. /// VertexAttributeUInt10 = 0x4000000, /// /// Devices supports rendering with VertexID only. /// VertexID = 0x8000000 } /// /// Specifies various error types that can be reported by bgfx. /// public enum ErrorType { /// /// A debug check failed; the program can safely continue, but the issue should be investigated. /// DebugCheck, /// /// The program tried to compile an invalid shader. /// InvalidShader, /// /// An error occurred during bgfx library initialization. /// UnableToInitialize, /// /// Failed while trying to create a texture. /// UnableToCreateTexture, /// /// The graphics device was lost and the library was unable to recover. /// DeviceLost } /// /// Specifies results of an occlusion query. /// public enum OcclusionQueryResult { /// /// Objects are invisible. /// Invisible, /// /// Objects are visible. /// Visible, /// /// Result is not ready or is unknown. /// NoResult } /// /// Specifies the supported rendering backend APIs. /// public enum RendererBackend { /// /// No backend given. /// Noop, /// /// Direct3D 9 /// Direct3D9, /// /// Direct3D 11 /// Direct3D11, /// /// Direct3D 12 /// Direct3D12, /// /// PlayStation 4's GNM /// GNM, /// /// Apple Metal. /// Metal, /// /// OpenGL ES /// OpenGLES, /// /// OpenGL /// OpenGL, /// /// Vulkan /// Vulkan, /// /// Used during initialization; specifies that the library should /// pick the best renderer for the running hardware and OS. /// Default } /// /// Specifies results of manually rendering a single frame. /// public enum RenderFrameResult { /// /// No device context has been created yet. /// NoContext, /// /// The frame was rendered. /// Render, /// /// The internal semaphore timed out; rendering was skipped. /// Timeout, /// /// Rendering is done; the program should exit. /// Exiting } /// /// Specifies various settings to change during a reset call. /// [Flags] public enum ResetFlags { /// /// No features to change. /// None = 0, /// /// Not yet supported. /// Fullscreen = 0x1, /// /// Enable 2x multisampling. /// MSAA2x = 0x10, /// /// Enable 4x multisampling. /// MSAA4x = 0x20, /// /// Enable 8x multisampling. /// MSAA8x = 0x30, /// /// Enable 16x multisampling. /// MSAA16x = 0x40, /// /// Enable v-sync. /// Vsync = 0x80, /// /// Use the maximum anisotropic filtering level available. /// MaxAnisotropy = 0x100, /// /// Begin screen capture. /// Capture = 0x200, /// /// Flush all commands to the device after rendering. /// FlushAfterRender = 0x2000, /// /// Flip the backbuffer immediately after rendering for reduced latency. /// Only useful when multithreading is disabled. /// FlipAfterRender = 0x4000, /// /// Write data to the backbuffer in non-linear sRGB format. /// SrgbBackbuffer = 0x8000, /// /// Enable HDR10 rendering. /// HDR10 = 0x10000, /// /// Enable High-DPI rendering. /// HighDPI = 0x20000, /// /// Enables depth clamping. /// DepthClamp = 0x40000, /// /// Suspends rendering. /// Suspend = 0x80000 } /// /// Flags that control frame buffer resolve. /// public enum ResolveFlags : byte { /// /// No particular flags specified. /// None = 0, /// /// Automatically generate mipmaps. /// AutoGenMips = 0x1 } /// /// Specifies various texture flags. /// [Flags] public enum TextureFlags : long { /// /// No flags set. /// None = 0x00000000, /// /// Mirror the texture in the U coordinate. /// MirrorU = 0x00000001, /// /// Clamp the texture in the U coordinate. /// ClampU = 0x00000002, /// /// Use a border color for addresses outside the range in the U coordinate. /// BorderU = 0x00000003, /// /// Mirror the texture in the V coordinate. /// MirrorV = 0x00000004, /// /// Clamp the texture in the V coordinate. /// ClampV = 0x00000008, /// /// Use a border color for addresses outside the range in the V coordinate. /// BorderV = 0x0000000c, /// /// Mirror the texture in the W coordinate. /// MirrorW = 0x00000010, /// /// Clamp the texture in the W coordinate. /// ClampW = 0x00000020, /// /// Use a border color for addresses outside the range in the W coordinate. /// BorderW = 0x00000030, /// /// Mirror the texture in the U,V, and W coordinates. /// MirrorUVW = MirrorU | MirrorV | MirrorW, /// /// Clamp the texture in the U,V, and W coordinates. /// ClampUVW = ClampU | ClampV | ClampW, /// /// Use a border color for addresses outside the range in the U,V, and W coordinates. /// BorderUVW = BorderU | BorderV | BorderW, /// /// Use point filtering for texture minification. /// MinFilterPoint = 0x00000040, /// /// Use anisotropic filtering for texture minification. /// MinFilterAnisotropic = 0x00000080, /// /// Use point filtering for texture magnification. /// MagFilterPoint = 0x00000100, /// /// Use anisotropic filtering for texture magnification. /// MagFilterAnisotropic = 0x00000200, /// /// Use point filtering for texture mipmaps. /// MipFilterPoint = 0x00000400, /// /// Use point filtering for minification, magnification, and texture mipmaps. /// FilterPoint = MinFilterPoint | MagFilterPoint | MipFilterPoint, /// /// Use a "less than" operator when comparing textures. /// CompareLess = 0x00010000, /// /// Use a "less than or equal" operator when comparing textures. /// CompareLessEqual = 0x00020000, /// /// Use an equality operator when comparing textures. /// CompareEqual = 0x00030000, /// /// Use a "greater than or equal" operator when comparing textures. /// CompareGreaterEqual = 0x00040000, /// /// Use a "greater than" operator when comparing textures. /// CompareGreater = 0x00050000, /// /// Use an inequality operator when comparing textures. /// CompareNotEqual = 0x00060000, /// /// Never compare two textures as equal. /// CompareNever = 0x00070000, /// /// Always compare two textures as equal. /// CompareAlways = 0x00080000, /// /// Sample stencil instead of depth. /// SampleStencil = 0x100000, /// /// Perform MSAA sampling on the texture. /// MSAASample = 0x800000000, /// /// The texture will be used as a render target. /// RenderTarget = 0x1000000000, /// /// The render target texture support 2x multisampling. /// RenderTargetMultisample2x = 0x2000000000, /// /// The render target texture support 4x multisampling. /// RenderTargetMultisample4x = 0x3000000000, /// /// The render target texture support 8x multisampling. /// RenderTargetMultisample8x = 0x4000000000, /// /// The render target texture support 16x multisampling. /// RenderTargetMultisample16x = 0x5000000000, /// /// The texture is only writeable (render target). /// RenderTargetWriteOnly = 0x8000000000, /// /// Texture is the target of compute shader writes. /// ComputeWrite = 0x100000000000, /// /// Texture data is in non-linear sRGB format. /// Srgb = 0x200000000000, /// /// Texture can be used as the destination of a blit operation. /// BlitDestination = 0x400000000000, /// /// Texture data can be read back. /// ReadBack = 0x800000000000 } /// /// Specifies the format of a texture's data. /// /// /// Check Caps flags for hardware format support. /// public enum TextureFormat { /// /// Block compression with three color channels, 1 bit alpha. /// BC1, /// /// Block compression with three color channels, 4 bits alpha. /// BC2, /// /// Block compression with three color channels, 8 bits alpha. /// BC3, /// /// Block compression for 1-channel color. /// BC4, /// /// Block compression for 2-channel color. /// BC5, /// /// Block compression for three-channel HDR color. /// BC6H, /// /// Highest quality block compression. /// BC7, /// /// Original ETC block compression. /// ETC1, /// /// Improved ETC block compression (no alpha). /// ETC2, /// /// Improved ETC block compression with full alpha. /// ETC2A, /// /// Improved ETC block compression with 1-bit punchthrough alpha. /// ETC2A1, /// /// PVRTC1 compression (2 bits per pixel) /// PTC12, /// /// PVRTC1 compression (4 bits per pixel) /// PTC14, /// /// PVRTC1 compression with alpha (2 bits per pixel) /// PTC12A, /// /// PVRTC1 compression with alpha (4 bits per pixel) /// PTC14A, /// /// PVRTC2 compression with alpha (2 bits per pixel) /// PTC22, /// /// PVRTC2 compression with alpha (4 bits per pixel) /// PTC24, /// /// ATC RGB (4 bits per pixel) /// ATC, /// /// ATCE RGBA with explicit alpha (8 bits per pixel) /// ATCE, /// /// ATCE RGBA with interpolated alpha (8 bits per pixel) /// ATCI, /// /// ASTC 4x4 8.0 bpp /// ASTC4x4, /// /// ASTC 5x5 5.12 bpp /// ASTC5x5, /// /// ASTC 6x6 3.56 bpp /// ASTC6x6, /// /// ASTC 8x5 3.20 bpp /// ASTC8x5, /// /// ASTC 8x6 2.67 bpp /// ASTC8x6, /// /// ASTC 10x5 2.56 bpp /// ASTC10x5, /// /// Unknown texture format. /// Unknown, /// /// 1-bit single channel. /// R1, /// /// 8-bit single channel (alpha). /// A8, /// /// 8-bit single channel. /// R8, /// /// 8-bit single channel (integer). /// R8I, /// /// 8-bit single channel (unsigned). /// R8U, /// /// 8-bit single channel (signed). /// R8S, /// /// 16-bit single channel. /// R16, /// /// 16-bit single channel (integer). /// R16I, /// /// 16-bit single channel (unsigned). /// R16U, /// /// 16-bit single channel (float). /// R16F, /// /// 16-bit single channel (signed). /// R16S, /// /// 32-bit single channel (integer). /// R32I, /// /// 32-bit single channel (unsigned). /// R32U, /// /// 32-bit single channel (float). /// R32F, /// /// 8-bit two channel. /// RG8, /// /// 8-bit two channel (integer). /// RG8I, /// /// 8-bit two channel (unsigned). /// RG8U, /// /// 8-bit two channel (signed). /// RG8S, /// /// 16-bit two channel. /// RG16, /// /// 16-bit two channel (integer). /// RG16I, /// /// 16-bit two channel (unsigned). /// RG16U, /// /// 16-bit two channel (float). /// RG16F, /// /// 16-bit two channel (signed). /// RG16S, /// /// 32-bit two channel (integer). /// RG32I, /// /// 32-bit two channel (unsigned). /// RG32U, /// /// 32-bit two channel (float). /// RG32F, /// /// 8-bit three channel. /// RGB8, /// /// 8-bit three channel (integer). /// RGB8I, /// /// 8-bit three channel (unsigned). /// RGB8U, /// /// 8-bit three channel (signed). /// RGB8S, /// /// 9-bit three channel floating point with shared 5-bit exponent. /// RGB9E5F, /// /// 8-bit BGRA color. /// BGRA8, /// /// 8-bit RGBA color. /// RGBA8, /// /// 8-bit RGBA color (integer). /// RGBA8I, /// /// 8-bit RGBA color (unsigned). /// RGBA8U, /// /// 8-bit RGBA color (signed). /// RGBA8S, /// /// 16-bit RGBA color. /// RGBA16, /// /// 16-bit RGBA color (integer). /// RGBA16I, /// /// 16-bit RGBA color (unsigned). /// RGBA16U, /// /// 16-bit RGBA color (float). /// RGBA16F, /// /// 16-bit RGBA color (signed). /// RGBA16S, /// /// 32-bit RGBA color (integer). /// RGBA32I, /// /// 32-bit RGBA color (unsigned). /// RGBA32U, /// /// 32-bit RGBA color (float). /// RGBA32F, /// /// 5-6-6 color. /// R5G6B5, /// /// 4-bit RGBA color. /// RGBA4, /// /// 5-bit RGB color with 1-bit alpha. /// RGB5A1, /// /// 10-bit RGB color with 2-bit alpha. /// RGB10A2, /// /// 11-11-10 color (float). /// RG11B10F, /// /// Unknown depth format. /// UnknownDepth, /// /// 16-bit depth. /// D16, /// /// 24-bit depth. /// D24, /// /// 24-bit depth, 8-bit stencil. /// D24S8, /// /// 32-bit depth. /// D32, /// /// 16-bit depth (float). /// D16F, /// /// 24-bit depth (float). /// D24F, /// /// 32-bit depth (float). /// D32F, /// /// 8-bit stencil. /// D0S8 } /// /// Indicates the level of support for a specific texture format. /// [Flags] public enum TextureFormatSupport { /// /// The format is unsupported. /// Unsupported = 0x0, /// /// The format is supported for 2D color data and operations. /// Color2D = 0x1, /// /// The format is supported for 2D sRGB operations. /// Srgb2D = 0x2, /// /// The format is supported for 2D textures through library emulation. /// Emulated2D = 0x4, /// /// The format is supported for 3D color data and operations. /// Color3D = 0x8, /// /// The format is supported for 3D sRGB operations. /// Srgb3D = 0x10, /// /// The format is supported for 3D textures through library emulation. /// Emulated3D = 0x20, /// /// The format is supported for cube color data and operations. /// ColorCube = 0x40, /// /// The format is supported for cube sRGB operations. /// SrgbCube = 0x80, /// /// The format is supported for cube textures through library emulation. /// EmulatedCube = 0x100, /// /// The format is supported for vertex texturing. /// Vertex = 0x200, /// /// The format is supported for compute image operations. /// Image = 0x400, /// /// The format is supported for framebuffers. /// Framebuffer = 0x800, /// /// The format is supported for MSAA framebuffers. /// FramebufferMSAA = 0x1000, /// /// The format is supported for MSAA sampling. /// MSAA = 0x2000, /// /// The format supports auto-generated mipmaps. /// MipsAutogen = 0x4000 } /// /// Specifies possible primitive topologies. /// public enum Topology { /// /// List of triangles. /// TriangleList, /// /// Strip of triangles. /// TriangleStrip, /// /// List of lines. /// LineList, /// /// Strip of lines. /// LineStrip, /// /// List of points. /// PointList } /// /// Specifies the type of uniform data. /// public enum UniformType { /// /// Texture sampler. /// Sampler, /// /// 4D vector. /// Vector4 = 2, /// /// 3x3 matrix. /// Matrix3x3, /// ///4x4 matrix. /// Matrix4x4 } /// /// Specifies known vendor IDs. /// public enum Vendor { /// /// No vendor specified. /// None = 0, /// /// Special flag to use platform's software rasterizer, if available. /// SoftwareRasterizer = 0x1, /// /// AMD /// AMD = 0x1002, /// /// Intel /// Intel = 0x8086, /// /// NVIDIA /// Nvidia = 0x10de, /// /// Microsoft /// Microsoft = 0x1414 } /// /// Specifies data types for vertex attributes. /// public enum VertexAttributeType { /// /// One-byte unsigned integer. /// UInt8, /// /// 10-bit unsigned integer. /// /// /// Availability depends on Caps flags. /// UInt10, /// /// Two-byte signed integer. /// Int16, /// /// Two-byte float. /// /// /// Availability depends on Caps flags. /// Half, /// /// Four-byte float. /// Float } /// /// Specifies vertex attribute usages. /// public enum VertexAttributeUsage { /// /// Position data. /// Position, /// /// Normals. /// Normal, /// /// Tangents. /// Tangent, /// /// Bitangents. /// Bitangent, /// /// First color channel. /// Color0, /// /// Second color channel. /// Color1, /// /// Third color channel. /// Color2, /// /// Fourth color channel. /// Color3, /// /// Indices. /// Indices, /// /// Animation weights. /// Weight, /// /// First texture coordinate channel (arbitrary data). /// TexCoord0, /// /// Second texture coordinate channel (arbitrary data). /// TexCoord1, /// /// Third texture coordinate channel (arbitrary data). /// TexCoord2, /// /// Fourth texture coordinate channel (arbitrary data). /// TexCoord3, /// /// Fifth texture coordinate channel (arbitrary data). /// TexCoord4, /// /// Sixth texture coordinate channel (arbitrary data). /// TexCoord5, /// /// Seventh texture coordinate channel (arbitrary data). /// TexCoord6, /// /// Eighth texture coordinate channel (arbitrary data). /// TexCoord7 } /// /// Specifies possible sorting modes for a view. /// public enum ViewMode { /// /// Default sorting method. /// Default, /// /// Do each draw in the order it is issued. /// Sequential, /// /// Sort each draw by depth, ascending. /// DepthAscending, /// /// Sort each draw by depth, descending. /// DepthDescending } /// /// Delegate type for callback functions. /// /// User-provided data to the original allocation call. [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void ReleaseCallback (IntPtr userData); [SuppressUnmanagedCodeSecurity] unsafe static class NativeMethods { #pragma warning disable IDE1006 // Naming Styles [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_update_texture_2d (ushort handle, ushort layer, byte mip, ushort x, ushort y, ushort width, ushort height, MemoryBlock.DataPtr* memory, ushort pitch); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_update_texture_3d (ushort handle, byte mip, ushort x, ushort y, ushort z, ushort width, ushort height, ushort depth, MemoryBlock.DataPtr* memory); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_update_texture_cube (ushort handle, ushort layer, CubeMapFace side, byte mip, ushort x, ushort y, ushort width, ushort height, MemoryBlock.DataPtr* memory, ushort pitch); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_get_avail_transient_index_buffer (int num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_get_avail_transient_vertex_buffer (int num, ref VertexLayout.Data decl); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_get_avail_instance_data_buffer (int num, ushort stride); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_alloc_transient_index_buffer (out TransientIndexBuffer tib, int num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_alloc_transient_vertex_buffer (out TransientVertexBuffer tvb, int num, ref VertexLayout.Data decl); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool bgfx_alloc_transient_buffers (out TransientVertexBuffer tvb, ref VertexLayout.Data decl, ushort numVertices, out TransientIndexBuffer tib, ushort numIndices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_alloc_instance_data_buffer (out InstanceDataBuffer.NativeStruct ptr, int num, ushort stride); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_dispatch (ushort id, ushort program, uint numX, uint numY, uint numZ); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_dispatch_indirect (ushort id, ushort program, ushort indirectHandle, ushort start, ushort num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_texture (byte stage, ushort sampler, ushort texture, uint flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_image (byte stage, ushort texture, byte mip, TextureFormat format, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_compute_index_buffer (byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_compute_vertex_buffer (byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_compute_dynamic_index_buffer (byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_compute_dynamic_vertex_buffer (byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_compute_indirect_buffer (byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_frame_buffer (ushort width, ushort height, TextureFormat format, TextureFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_frame_buffer_name(ushort handle, [MarshalAs(UnmanagedType.LPStr)] string name, int len); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_frame_buffer_scaled (BackbufferRatio ratio, TextureFormat format, TextureFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_frame_buffer_from_handles (byte count, ushort* handles, [MarshalAs(UnmanagedType.U1)] bool destroyTextures); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_frame_buffer_from_attachment (byte count, FrameBuffer.NativeAttachment* attachment, [MarshalAs(UnmanagedType.U1)] bool destroyTextures); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_frame_buffer_from_nwh (IntPtr nwh, ushort width, ushort height, TextureFormat depthFormat); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_frame_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_frame_buffer (ushort id, ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_program (ushort vsh, ushort fsh, [MarshalAs(UnmanagedType.U1)] bool destroyShaders); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_compute_program (ushort csh, [MarshalAs(UnmanagedType.U1)] bool destroyShaders); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_program (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern Capabilities.Caps* bgfx_get_caps (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_decl_begin (ref VertexLayout.Data decl, RendererBackend backend); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_decl_add (ref VertexLayout.Data decl, VertexAttributeUsage attribute, byte count, VertexAttributeType type, [MarshalAs(UnmanagedType.U1)] bool normalized, [MarshalAs(UnmanagedType.U1)] bool asInt); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_decl_skip (ref VertexLayout.Data decl, byte count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_decl_end (ref VertexLayout.Data decl); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_vertex_buffer (MemoryBlock.DataPtr* memory, ref VertexLayout.Data decl, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_vertex_buffer_name(ushort handle, [MarshalAs(UnmanagedType.LPStr)] string name, int len); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_vertex_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_uniform ([MarshalAs(UnmanagedType.LPStr)] string name, UniformType type, ushort arraySize); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_get_uniform_info (ushort handle, out Uniform.Info info); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_uniform (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_texture (MemoryBlock.DataPtr* mem, TextureFlags flags, byte skip, out Texture.TextureInfo info); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_texture_2d (ushort width, ushort _height, [MarshalAs(UnmanagedType.U1)] bool hasMips, ushort numLayers, TextureFormat format, TextureFlags flags, MemoryBlock.DataPtr* mem); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_texture_2d_scaled (BackbufferRatio ratio, [MarshalAs(UnmanagedType.U1)] bool hasMips, ushort numLayers, TextureFormat format, TextureFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_texture_3d (ushort width, ushort _height, ushort _depth, [MarshalAs(UnmanagedType.U1)] bool hasMips, TextureFormat format, TextureFlags flags, MemoryBlock.DataPtr* mem); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_texture_cube (ushort size, [MarshalAs(UnmanagedType.U1)] bool hasMips, ushort numLayers, TextureFormat format, TextureFlags flags, MemoryBlock.DataPtr* mem); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_texture_name(ushort handle, [MarshalAs(UnmanagedType.LPStr)] string name, int len); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr bgfx_get_direct_access_ptr (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_texture (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_calc_texture_size (ref Texture.TextureInfo info, ushort width, ushort height, ushort depth, [MarshalAs(UnmanagedType.U1)] bool cubeMap, [MarshalAs(UnmanagedType.U1)] bool hasMips, ushort numLayers, TextureFormat format); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool bgfx_is_texture_valid (ushort depth, [MarshalAs(UnmanagedType.U1)] bool cubeMap, ushort numLayers, TextureFormat format, TextureFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_shader (MemoryBlock.DataPtr* memory); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_get_shader_uniforms (ushort handle, Uniform[] uniforms, ushort max); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_shader_name(ushort handle, [MarshalAs(UnmanagedType.LPStr)] string name, int len); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_shader (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern MemoryBlock.DataPtr* bgfx_alloc (int size); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern MemoryBlock.DataPtr* bgfx_copy (IntPtr data, int size); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern MemoryBlock.DataPtr* bgfx_make_ref_release (IntPtr data, int size, IntPtr releaseFn, IntPtr userData); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_index_buffer (MemoryBlock.DataPtr* memory, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_index_buffer_name(ushort handle, [MarshalAs(UnmanagedType.LPStr)] string name, int len); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_index_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_dynamic_index_buffer (int indexCount, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_dynamic_index_buffer_mem (MemoryBlock.DataPtr* memory, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_update_dynamic_index_buffer (ushort handle, int startIndex, MemoryBlock.DataPtr* memory); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_dynamic_index_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_dynamic_vertex_buffer (int vertexCount, ref VertexLayout.Data decl, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_dynamic_vertex_buffer_mem (MemoryBlock.DataPtr* memory, ref VertexLayout.Data decl, BufferFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_update_dynamic_vertex_buffer (ushort handle, int startVertex, MemoryBlock.DataPtr* memory); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_dynamic_vertex_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_indirect_buffer (int size); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_indirect_buffer (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_image_swizzle_bgra8 (IntPtr dst, int width, int height, int pitch, IntPtr src); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_image_rgba8_downsample_2x2 (IntPtr dst, int width, int height, int pitch, IntPtr src); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_platform_data (ref PlatformData data); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern InternalData* bgfx_get_internal_data (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern RenderFrameResult bgfx_render_frame (int timeoutMs); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr bgfx_override_internal_texture_ptr (ushort handle, IntPtr ptr); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr bgfx_override_internal_texture (ushort handle, ushort width, ushort height, byte numMips, TextureFormat format, TextureFlags flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern PerfStats.Stats* bgfx_get_stats (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern RendererBackend bgfx_get_renderer_type (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_shutdown (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_reset (int width, int height, ResetFlags flags, TextureFormat format); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_frame ([MarshalAs(UnmanagedType.U1)] bool capture); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_debug (DebugFeatures flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_marker ([MarshalAs(UnmanagedType.LPStr)] string marker); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_dbg_text_clear (byte color, [MarshalAs(UnmanagedType.U1)] bool smallText); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_set_transform (float* matrix, ushort count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_stencil (uint frontFace, uint backFace); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_touch (ushort id); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_submit (ushort id, ushort programHandle, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_submit_occlusion_query (ushort id, ushort programHandle, ushort queryHandle, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_submit_indirect (ushort id, ushort programHandle, ushort indirectHandle, ushort start, ushort num, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_discard (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_name (ushort id, [MarshalAs(UnmanagedType.LPStr)] string name); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_rect (ushort id, ushort x, ushort y, ushort width, ushort height); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_rect_auto (ushort id, ushort x, ushort y, BackbufferRatio ratio); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_scissor (ushort id, ushort x, ushort y, ushort width, ushort height); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_clear (ushort id, ClearTargets flags, int rgba, float depth, byte stencil); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_clear_mrt (ushort id, ClearTargets flags, float depth, byte stencil, byte rt0, byte rt1, byte rt2, byte rt3, byte rt4, byte rt5, byte rt6, byte rt7); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_palette_color (byte index, float* color); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_mode (ushort id, ViewMode mode); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_view_transform (ushort id, float* view, float* proj); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_request_screen_shot (ushort handle, [MarshalAs(UnmanagedType.LPStr)] string filePath); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_state (ulong state, int rgba); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_pack (float* input, [MarshalAs(UnmanagedType.U1)] bool inputNormalized, VertexAttributeUsage attribute, ref VertexLayout.Data decl, IntPtr data, int index); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_unpack (float* output, VertexAttributeUsage attribute, ref VertexLayout.Data decl, IntPtr data, int index); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_vertex_convert (ref VertexLayout.Data destDecl, IntPtr destData, ref VertexLayout.Data srcDecl, IntPtr srcData, int num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_weld_vertices (ushort* output, ref VertexLayout.Data decl, IntPtr data, ushort num, float epsilon); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern byte bgfx_get_supported_renderers (byte max, RendererBackend[] backends); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern sbyte* bgfx_get_renderer_name (RendererBackend backend); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_init_ctor (InitSettings.Native* ptr); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool bgfx_init (InitSettings.Native* ptr); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_dbg_text_printf (ushort x, ushort y, byte color, [MarshalAs(UnmanagedType.LPStr)] string format, [MarshalAs(UnmanagedType.LPStr)] string args); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_dbg_text_printf (ushort x, ushort y, byte color, byte* format, IntPtr args); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_dbg_text_image (ushort x, ushort y, ushort width, ushort height, IntPtr data, ushort pitch); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_index_buffer (ushort handle, int firstIndex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_dynamic_index_buffer (ushort handle, int firstIndex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_vertex_buffer (byte stream, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_dynamic_vertex_buffer (byte stream, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_uniform (ushort handle, void* value, ushort arraySize); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_transform_cached (int cache, ushort num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_set_scissor (ushort x, ushort y, ushort width, ushort height); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_scissor_cached (ushort cache); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_transient_vertex_buffer (byte stream, ref TransientVertexBuffer tvb, int startVertex, int numVertices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_transient_index_buffer (ref TransientIndexBuffer tib, int startIndex, int numIndices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_vertex_count (int numVertices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_instance_count (int numInstances); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_instance_data_buffer (ref InstanceDataBuffer.NativeStruct idb, uint start, uint num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_instance_data_from_vertex_buffer (ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_instance_data_from_dynamic_vertex_buffer (ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_reset_view (ushort id); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_blit (ushort id, ushort dst, byte dstMip, ushort dstX, ushort dstY, ushort dstZ, ushort src, byte srcMip, ushort srcX, ushort srcY, ushort srcZ, ushort width, ushort height, ushort depth); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern uint bgfx_read_texture (ushort handle, IntPtr data, byte mip); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_get_texture (ushort handle, byte attachment); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_create_occlusion_query (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_destroy_occlusion_query (ushort handle); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern OcclusionQueryResult bgfx_get_result (ushort handle, int* pixels); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_set_condition (ushort handle, [MarshalAs(UnmanagedType.U1)] bool visible); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_vsnprintf(sbyte* str, IntPtr count, [MarshalAs(UnmanagedType.LPStr)] string format, IntPtr argList); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr bgfx_begin (); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_end (IntPtr encoder); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_marker (IntPtr encoder, [MarshalAs(UnmanagedType.LPStr)] string marker); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_state (IntPtr encoder, ulong state, int rgba); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_condition (IntPtr encoder, ushort handle, [MarshalAs(UnmanagedType.U1)] bool visible); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_stencil(IntPtr encoder, uint frontFace, uint backFace); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ushort bgfx_encoder_set_scissor(IntPtr encoder, ushort x, ushort y, ushort width, ushort height); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_scissor_cached(IntPtr encoder, ushort cache); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_set_transform(IntPtr encoder, float* matrix, ushort count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_transform_cached(IntPtr encoder, int cache, ushort num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_uniform(IntPtr encoder, ushort handle, void* value, ushort arraySize); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_index_buffer(IntPtr encoder, ushort handle, int firstIndex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_dynamic_index_buffer(IntPtr encoder, ushort handle, int firstIndex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_vertex_buffer(IntPtr encoder, byte stream, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_dynamic_vertex_buffer(IntPtr encoder, byte stream, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_transient_vertex_buffer(IntPtr encoder, byte stream, ref TransientVertexBuffer tvb, int startVertex, int numVertices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_transient_index_buffer(IntPtr encoder, ref TransientIndexBuffer tib, int startIndex, int numIndices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_vertex_count (IntPtr encoder, int numVertices); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_instance_data_buffer(IntPtr encoder, ref InstanceDataBuffer.NativeStruct idb, uint start, uint num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_instance_data_from_vertex_buffer(IntPtr encoder, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_instance_data_from_dynamic_vertex_buffer(IntPtr encoder, ushort handle, int startVertex, int count); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_texture(IntPtr encoder, byte stage, ushort sampler, ushort texture, uint flags); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_touch(IntPtr encoder, ushort id); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_submit(IntPtr encoder, ushort id, ushort programHandle, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_submit_occlusion_query(IntPtr encoder, ushort id, ushort programHandle, ushort queryHandle, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_submit_indirect(IntPtr encoder, ushort id, ushort programHandle, ushort indirectHandle, ushort start, ushort num, int depth, [MarshalAs(UnmanagedType.U1)] bool preserveState); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_image(IntPtr encoder, byte stage, ushort texture, byte mip, TextureFormat format, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_compute_index_buffer(IntPtr encoder, byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_compute_vertex_buffer(IntPtr encoder, byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_compute_dynamic_index_buffer(IntPtr encoder, byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_compute_dynamic_vertex_buffer(IntPtr encoder, byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_set_compute_indirect_buffer(IntPtr encoder, byte stage, ushort handle, ComputeBufferAccess access); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_dispatch(IntPtr encoder, ushort id, ushort program, uint numX, uint numY, uint numZ); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int bgfx_encoder_dispatch_indirect(IntPtr encoder, ushort id, ushort program, ushort indirectHandle, ushort start, ushort num); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_discard(IntPtr encoder); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void bgfx_encoder_blit(IntPtr encoder, ushort id, ushort dst, byte dstMip, ushort dstX, ushort dstY, ushort dstZ, ushort src, byte srcMip, ushort srcX, ushort srcY, ushort srcZ, ushort width, ushort height, ushort depth); #pragma warning restore IDE1006 // Naming Styles #if DEBUG const string DllName = "bgfx_debug.dll"; #else const string DllName = "bgfx.dll"; #endif } unsafe struct CallbackShim { IntPtr vtbl; IntPtr reportError; IntPtr reportDebug; IntPtr profilerBegin; IntPtr profilerBeginLiteral; IntPtr profilerEnd; IntPtr getCachedSize; IntPtr getCacheEntry; IntPtr setCacheEntry; IntPtr saveScreenShot; IntPtr captureStarted; IntPtr captureFinished; IntPtr captureFrame; public static unsafe IntPtr CreateShim (ICallbackHandler handler) { if (handler == null) return IntPtr.Zero; if (savedDelegates != null) throw new InvalidOperationException("Callbacks should only be initialized once; bgfx can only deal with one set at a time."); var memory = Marshal.AllocHGlobal(Marshal.SizeOf()); var shim = (CallbackShim*)memory; var saver = new DelegateSaver(handler, shim); // the shim uses the unnecessary ctor slot to act as a vtbl pointer to itself, // so that the same block of memory can act as both bgfx_callback_interface_t and bgfx_callback_vtbl_t shim->vtbl = memory + IntPtr.Size; // cache the data so we can free it later shimMemory = memory; savedDelegates = saver; return memory; } public static void FreeShim () { if (savedDelegates == null) return; savedDelegates = null; Marshal.FreeHGlobal(shimMemory); } [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] delegate void ReportErrorHandler (IntPtr thisPtr, string fileName, ushort line, ErrorType errorType, string message); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] delegate void ReportDebugHandler (IntPtr thisPtr, string fileName, ushort line, string format, IntPtr args); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] delegate void ProfilerBeginHandler (IntPtr thisPtr, sbyte* name, int abgr, sbyte* filePath, ushort line); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void ProfilerEndHandler (IntPtr thisPtr); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate int GetCachedSizeHandler (IntPtr thisPtr, long id); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate bool GetCacheEntryHandler (IntPtr thisPtr, long id, IntPtr data, int size); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void SetCacheEntryHandler (IntPtr thisPtr, long id, IntPtr data, int size); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] delegate void SaveScreenShotHandler (IntPtr thisPtr, string path, int width, int height, int pitch, IntPtr data, int size, [MarshalAs(UnmanagedType.U1)] bool flipVertical); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void CaptureStartedHandler (IntPtr thisPtr, int width, int height, int pitch, TextureFormat format, [MarshalAs(UnmanagedType.U1)] bool flipVertical); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void CaptureFinishedHandler (IntPtr thisPtr); [SuppressUnmanagedCodeSecurity] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate void CaptureFrameHandler (IntPtr thisPtr, IntPtr data, int size); // We're creating delegates to a user's interface methods; we're then converting those delegates // to native pointers and passing them into native code. If we don't save the references to the // delegates in managed land somewhere, the GC will think they're unreferenced and clean them // up, leaving native holding a bag of pointers into nowhere land. class DelegateSaver { ICallbackHandler handler; ReportErrorHandler reportError; ReportDebugHandler reportDebug; ProfilerBeginHandler profilerBegin; ProfilerBeginHandler profilerBeginLiteral; ProfilerEndHandler profilerEnd; GetCachedSizeHandler getCachedSize; GetCacheEntryHandler getCacheEntry; SetCacheEntryHandler setCacheEntry; SaveScreenShotHandler saveScreenShot; CaptureStartedHandler captureStarted; CaptureFinishedHandler captureFinished; CaptureFrameHandler captureFrame; public unsafe DelegateSaver (ICallbackHandler handler, CallbackShim* shim) { this.handler = handler; reportError = ReportError; reportDebug = ReportDebug; profilerBegin = ProfilerBegin; profilerBeginLiteral = ProfilerBegin; profilerEnd = ProfilerEnd; getCachedSize = GetCachedSize; getCacheEntry = GetCacheEntry; setCacheEntry = SetCacheEntry; saveScreenShot = SaveScreenShot; captureStarted = CaptureStarted; captureFinished = CaptureFinished; captureFrame = CaptureFrame; shim->reportError = Marshal.GetFunctionPointerForDelegate(reportError); shim->reportDebug = Marshal.GetFunctionPointerForDelegate(reportDebug); shim->profilerBegin = Marshal.GetFunctionPointerForDelegate(profilerBegin); shim->profilerBeginLiteral = Marshal.GetFunctionPointerForDelegate(profilerBeginLiteral); shim->profilerEnd = Marshal.GetFunctionPointerForDelegate(profilerEnd); shim->getCachedSize = Marshal.GetFunctionPointerForDelegate(getCachedSize); shim->getCacheEntry = Marshal.GetFunctionPointerForDelegate(getCacheEntry); shim->setCacheEntry = Marshal.GetFunctionPointerForDelegate(setCacheEntry); shim->saveScreenShot = Marshal.GetFunctionPointerForDelegate(saveScreenShot); shim->captureStarted = Marshal.GetFunctionPointerForDelegate(captureStarted); shim->captureFinished = Marshal.GetFunctionPointerForDelegate(captureFinished); shim->captureFrame = Marshal.GetFunctionPointerForDelegate(captureFrame); } void ReportError (IntPtr thisPtr, string fileName, ushort line, ErrorType errorType, string message) { handler.ReportError(fileName, line, errorType, message); } void ReportDebug (IntPtr thisPtr, string fileName, ushort line, string format, IntPtr args) { handler.ReportDebug(fileName, line, format, args); } void ProfilerBegin (IntPtr thisPtr, sbyte* name, int color, sbyte* filePath, ushort line) { handler.ProfilerBegin(new string(name), color, new string(filePath), line); } void ProfilerEnd (IntPtr thisPtr) { handler.ProfilerEnd(); } int GetCachedSize (IntPtr thisPtr, long id) { return handler.GetCachedSize(id); } bool GetCacheEntry (IntPtr thisPtr, long id, IntPtr data, int size) { return handler.GetCacheEntry(id, data, size); } void SetCacheEntry (IntPtr thisPtr, long id, IntPtr data, int size) { handler.SetCacheEntry(id, data, size); } void SaveScreenShot (IntPtr thisPtr, string path, int width, int height, int pitch, IntPtr data, int size, bool flipVertical) { handler.SaveScreenShot(path, width, height, pitch, data, size, flipVertical); } void CaptureStarted (IntPtr thisPtr, int width, int height, int pitch, TextureFormat format, bool flipVertical) { handler.CaptureStarted(width, height, pitch, format, flipVertical); } void CaptureFinished (IntPtr thisPtr) { handler.CaptureFinished(); } void CaptureFrame (IntPtr thisPtr, IntPtr data, int size) { handler.CaptureFrame(data, size); } } static IntPtr shimMemory; static DelegateSaver savedDelegates; } }