/*
 * This file is part of Afterwarp Framework (https://afterwarp.io).
 * Copyright (c) 2015 - 2025 Dr. Yuriy Kotsarenko. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 */

// Afterwarp.h
#pragma once

#include "Afterwarp.Structs.h"

#ifdef __cplusplus
  extern "C" {
#endif

// The following SAL-style annotations are used by an automated header translation tool to determine proper
// conventions for languages such as C#. For C/C++ applications, these are just a syntatic sugar and should
// be ignored.
#if !defined(_MSC_VER) || !defined(_In_)
  #define _In_
  #define _Out_
  #define _Inout_
  #define _In_opt_
  #define _Out_opt_
  #define _Inout_opt_
#endif

// Library functions.

/// Returns current version of the shared library.
AFTERWARP_API LibraryBool LibraryGetVersion(int32_t* major, int32_t* minor, uint32_t* build);

/// Specifies a business serial key for the shared library.
AFTERWARP_API void LibrarySerialCode(char const* serial, int32_t length);

// SwapChain functions.

/// Creates a new rendering swap-chain associated with the given device and window handle. Once the
/// swap-chain has been created for a particular window under OpenGL-based backends, it would not be
/// possible to remove this association without re-creating the window.
AFTERWARP_API struct SwapChain_t* SwapChainCreate(struct Device_t* device, UntypedHandle windowHandle,
  Point const* size, PixelFormat format, PixelFormat depthStencil, int32_t multisamples,
  LibraryBool vsync);

/// Releases given instance of rendering swap-chain.
AFTERWARP_API void SwapChainDestroy(struct SwapChain_t* swapChain);

/// Returns device associated with the given swap-chain.
AFTERWARP_API struct Device_t* SwapChainGetDevice(struct SwapChain_t* swapChain);

/// Returns handle of the associated window.
AFTERWARP_API UntypedHandle SwapChainGetWindowHandle(struct SwapChain_t* swapChain);

/// Returns swap-chain width.
AFTERWARP_API int32_t SwapChainGetWidth(struct SwapChain_t* swapChain);

/// Returns swap-chain height.
AFTERWARP_API int32_t SwapChainGetHeight(struct SwapChain_t* swapChain);

/// Returns pixel format of swap-chain rendering surface.
AFTERWARP_API PixelFormat SwapChainGetFormat(struct SwapChain_t* swapChain);

/// Returns pixel format of swap-chain depth/stencil surface.
AFTERWARP_API PixelFormat SwapChainGetDepthStencil(struct SwapChain_t* swapChain);

/// Returns number of samples of swap-chain surfaces.
AFTERWARP_API int32_t SwapChainGetMultisamples(struct SwapChain_t* swapChain);

/// Returns whether to wait for a vertical retrace.
AFTERWARP_API LibraryBool SwapChainGetVSync(struct SwapChain_t* swapChain);

/// Resizes the swap-chain.
AFTERWARP_API LibraryBool SwapChainResize(struct SwapChain_t* swapChain, Point const* size);

/// Begins rendering on the swap-chain.
AFTERWARP_API LibraryBool SwapChainBegin(struct SwapChain_t* swapChain);

/// Finishes rendering on the swap-chain and flips the buffers.
AFTERWARP_API void SwapChainEnd(struct SwapChain_t* swapChain);

// Device functions.

/// Creates a new graphics device of the given technology and attributes.
AFTERWARP_API struct Device_t* DeviceCreate(struct Application_t* application, DeviceTechnology technology,
  DeviceAttributes attributes);

/// Creates a graphics device wrapped around an already initialized graphics context of the given technology
/// and attributes.
AFTERWARP_API struct Device_t* DeviceCreateWrapped(struct Application_t* application,
  DeviceTechnology technology, DeviceAttributes attributes, UntypedHandle platformDevice);

/// Releases given instance of device.
AFTERWARP_API void DeviceDestroy(struct Device_t* device);

/// Returns platform-specific device context.
AFTERWARP_API UntypedHandle DeviceGetPlatformDevice(struct Device_t* device);

/// Returns attributes with which the device has been created.
AFTERWARP_API DeviceAttributes DeviceGetAttributes(struct Device_t* device);

/// Returns device behavior attributes.
AFTERWARP_API DeviceBehavior DeviceGetBehavior(struct Device_t* device);

/// Returns legacy feature bits that define older hardware features.
AFTERWARP_API DeviceLegacyBits DeviceGetLegacyBits(struct Device_t* device);

/// Returns graphics technology type that is currently being used.
AFTERWARP_API DeviceTechnology DeviceGetTechnology(struct Device_t* device);

/// Returns OS platform the device application is currently running on.
AFTERWARP_API DevicePlatform DeviceGetPlatform(struct Device_t* device);

/// Returns the version of technology that is currently being used. The values are specified in
/// hexadecimal format. That is, a value of 0x100 indicates version 1.0, while a value of 0x247 would
/// indicate version 2.4.7. The value is used in combination with device technology, so if technology
/// is Direct3D, and this function returns 0xA10, it means that Direct3D 10.1 is being used.
AFTERWARP_API uint32_t DeviceGetTechVersion(struct Device_t* device);

/// Returns the feature level version of technology that is currently being used. The difference between
/// this and technology version is that the last one indicates type of technology being used (for example,
/// DirectX 3D), while this one indicates the level of features available (for example, Direct3D 9.0c).
/// The values here are specified in hexadecimal format. That is, a value of 0x213 would indicate
/// version 2.1.3.
AFTERWARP_API uint32_t DeviceGetTechFeatureVersion(struct Device_t* device);

/// Releases any cached device resources.
AFTERWARP_API void DeviceResetCache(struct Device_t* device);

/// Clears rendering surface that is currently active.
AFTERWARP_API LibraryBool DeviceClear(struct Device_t* device, uint8_t clearLayers,
  FloatColor const* clearColor, float clearDepth, uint32_t clearStencil);

/// Sets new rendering parameters and operation characteristics.
AFTERWARP_API LibraryBool DeviceSetRenderingState(struct Device_t* device, RenderingState const* state);

/// Returns current rendering states.
AFTERWARP_API void DeviceGetRenderingState(struct Device_t* device, RenderingState* state);

/// Specifies new viewport parameters.
AFTERWARP_API LibraryBool DeviceSetViewport(struct Device_t* device, Rect const* viewport);

/// Returns current viewport parameters.
AFTERWARP_API void DeviceGetViewport(struct Device_t* device, Rect* viewport);

/// Specifies new scissor parameters.
AFTERWARP_API LibraryBool DeviceSetScissor(struct Device_t* device, Rect const* scissor);

/// Returns current scissor parameters.
AFTERWARP_API void DeviceGetScissor(struct Device_t* device, Rect* scissor);

/// Issues a memory barrier according to the specified bit flags.
AFTERWARP_API void DeviceMemoryBarrier(struct Device_t* device, uint32_t barrierBits);

// Buffer functions.

/// Creates a new instance of hardware buffer associated with a particular device with the given parameters
/// and (optional) initial data.
AFTERWARP_API struct Buffer_t* BufferCreate(struct Device_t* device, BufferDataType dataType,
  BufferAccessType accessType, uint32_t size, uint32_t pitch, PixelFormat format, void const* initialData);

/// Releases given instance of hardware buffer.
AFTERWARP_API void BufferDestroy(struct Buffer_t* buffer);

/// Returns device associated with the given buffer.
AFTERWARP_API struct Device_t* BufferGetDevice(struct Buffer_t* buffer);

/// Returns platform-specific buffer handle.
AFTERWARP_API UntypedHandle BufferGetPlatformHandle(struct Buffer_t* buffer);

/// Returns the type of data that buffer contains.
AFTERWARP_API BufferDataType BufferGetDataType(struct Buffer_t* buffer);

/// Returns the access type of for buffer data.
AFTERWARP_API BufferAccessType BufferGetAccessType(struct Buffer_t* buffer);

/// Returns buffer size in bytes.
AFTERWARP_API uint32_t BufferGetSize(struct Buffer_t* buffer);

/// Returns the number of bytes for offset to move for advancing the pointer from one element to another.
AFTERWARP_API uint32_t BufferGetPitch(struct Buffer_t* buffer);

/// Returns pixel format that represents the buffer contents.
AFTERWARP_API PixelFormat BufferGetFormat(struct Buffer_t* buffer);

/// Updates the contents of the buffer with a new data. If \c size is left at zero, the remaining portion of
/// buffer starting at given byte offset will be updated. Note that if buffer has been created with an
/// access type that is non-default, then typically a whole buffer should be updated, attempting to update
/// a portion of it may be implementation-dependent.
AFTERWARP_API LibraryBool BufferUpdate(struct Buffer_t* buffer, void const* data, uint32_t offset,
  uint32_t size);

/// Retrieves the contents of the buffer. If \c size is left at zero, the remaining portion of buffer
/// starting at given byte offset will be retrieved.
AFTERWARP_API LibraryBool BufferRetrieve(struct Buffer_t* buffer, void* data, uint32_t offset,
  uint32_t size);

/// Updates the contents of the buffer with data copied from another buffer. If \c size is left at zero,
/// the remaining portion of buffer starting at given byte offset will be copied.
AFTERWARP_API LibraryBool BufferCopy(struct Buffer_t* buffer, struct Buffer_t* bufferSource,
  uint32_t offsetDest, uint32_t offsetSource, uint32_t size);

// Program types and functions.

/// Creates a new instance of shader program.
AFTERWARP_API struct Program_t* ProgramCreate(struct Device_t* device,
  _In_opt_ VertexElement const vertexElements[], int32_t vertexElementCount,
  _In_opt_ ProgramElement const programElements[], int32_t programElementCount,
  _In_opt_ ProgramVariable const programVariables[], int32_t programVariableCount,
  _In_opt_ char const* shaderVertex, int32_t shaderVertexLength,
  _In_opt_ char const* shaderHull, int32_t shaderHullLength,
  _In_opt_ char const* shaderDomain, int32_t shaderDomainLength,
  _In_opt_ char const* shaderGeometry, int32_t shaderGeometryLength,
  _In_opt_ char const* shaderPixel, int32_t shaderPixelLength);

/// Releases given instance of shader program.
AFTERWARP_API void ProgramDestroy(struct Program_t* program);

// TODO: expose getters for shaders, vertex and program elements.

/// Returns device associated with the given program.
AFTERWARP_API struct Device_t* ProgramGetDevice(struct Program_t* program);

/// Updates a portion of a specific variable that corresponds to the given index. The provided size
/// indicates how many bytes should be updated. If the provided size is left at zero, the entire contents
/// of given variable will be updated. This function should only be used inside \c ProgramBegin and \c
/// ProgramEnd call block.
AFTERWARP_API LibraryBool ProgramUpdateByIndex(struct Program_t* program, int32_t variableIndex,
  void const* variableData, uint32_t size);

/// Updates a portion of a specific variable identified by its name (case-sensitive). The provided size
/// indicates how many bytes should be updated. If the provided size is left at zero, the entire contents of
/// given variable will be updated. This function should only be used inside \c ProgramBegin and \c
/// ProgramEnd call block.
AFTERWARP_API LibraryBool ProgramUpdateByName(struct Program_t* program, char const* variableName,
  void const* variableData, uint32_t size);

/// Assigns a generic buffer (or a portion of starting from the given offset in bytes) to a particular
/// channel. Vertex and index buffers are associated with input stream channels, whereas constant buffers
/// are associated with shader program channels - each of these being unrelated and dependent on shader
/// vertex and program element declarations. The current bindings can be considered valid until
/// \c ProgramEnd, \c ProgramResetBindings or \c ProgramResetCache is called.
AFTERWARP_API LibraryBool ProgramBind(struct Program_t* program, struct Buffer_t* buffer, uint32_t channel,
  uint32_t offset);

/// Removes association that was previously made with \c ProgramBind between the buffer and the given channel.
AFTERWARP_API void ProgramUnbind(struct Program_t* program, struct Buffer_t* buffer, uint32_t channel);

/// Resets any bindings that were previously made as if \c ProgramUnbind would be called for each of them.
AFTERWARP_API void ProgramResetBindings(struct Program_t* program);

/// Resets any cache associated with vertex buffers. In case of OpenGL, this resets internal Vertex Array
/// Object (VAO) cache.
AFTERWARP_API void ProgramResetCache(struct Program_t* program);

/// Applies any binding changes to constant and/or vertex buffers, which usually occur when a draw call is
/// issued, to occur immediately.
AFTERWARP_API LibraryBool ProgramCommit(struct Program_t* program);

/// Activates the shader program and prepares for rendering.
AFTERWARP_API LibraryBool ProgramBegin(struct Program_t* program);

/// Deactivates the shader program, resets previously active input streams and bindings.
AFTERWARP_API void ProgramEnd(struct Program_t* program);

/// Renders primitives with the given number of vertices.
AFTERWARP_API LibraryBool ProgramDraw(struct Program_t* program, PrimitiveTopology topology,
  int32_t vertexCount, int32_t baseVertex);

/// Renders indexed primitives with the given number of indices.
AFTERWARP_API LibraryBool ProgramDrawIndexed(struct Program_t* program, PrimitiveTopology topology,
  int32_t indexCount, int32_t firstIndex, int32_t baseVertex);

/// Renders multiple number of instances of the given primitives.
AFTERWARP_API LibraryBool ProgramDrawInstances(struct Program_t* program, PrimitiveTopology topology,
  int32_t vertexCount, int32_t instanceCount, int32_t baseVertex);

/// Renders multiple number of instances of the given indexed primitives.
AFTERWARP_API LibraryBool ProgramDrawInstancesIndexed(struct Program_t* program, PrimitiveTopology topology,
  int32_t indexCount, int32_t instanceCount, int32_t firstIndex, int32_t baseVertex);

/// Specifies number of vertices in each patch. This only applies when rendering patch topology.
AFTERWARP_API LibraryBool ProgramSetPatchVertices(struct Program_t* program, int32_t patchVertices);

// ComputeProgram types and functions.

// TODO: expose getter for program elements.

/// Creates a new instance of compute shader program.
AFTERWARP_API struct ComputeProgram_t* ComputeProgramCreate(struct Device_t* device,
  _In_opt_ ProgramElement const programElements[], int32_t programElementCount,
  _In_opt_ char const* shader, int32_t shaderLength);

/// Releases given instance of compute shader program.
AFTERWARP_API void ComputeProgramDestroy(struct ComputeProgram_t* program);

/// Returns device associated with the given compute program.
AFTERWARP_API struct Device_t* ComputeProgramGetDevice(struct ComputeProgram_t* program);

/// Assigns a generic buffer (or a portion of starting from the given offset in bytes) to a particular
/// channel. The current bindings can be considered valid until \c ComputeProgramEnd() or
/// \c ComputeProgramResetBindings() is called.
AFTERWARP_API LibraryBool ComputeProgramBindBuffer(struct ComputeProgram_t* program,
  struct Buffer_t* buffer, uint32_t channel, uint32_t offset);

/// Removes association that was previously made with \c ComputeProgramBindBuffer() between the buffer and
/// the given channel.
AFTERWARP_API void ComputeProgramUnbindBuffer(struct ComputeProgram_t* program, struct Buffer_t* buffer,
  uint32_t channel);

/// Assigns texture to a particular channel.
AFTERWARP_API LibraryBool ComputeProgramBindTexture(struct ComputeProgram_t* program,
  struct Texture_t* texture, ComputeBindTextureFormat const* bindFormat);

/// Removes existing texture association with the particular channel.
AFTERWARP_API void ComputeProgramUnbindTexture(struct ComputeProgram_t* program, struct Texture_t* texture,
  ComputeBindTextureFormat const* bindFormat);

/// Resets any bindings that were previously made as if \c ComputeProgramUnbindXXX() would be called for
/// each of them.
AFTERWARP_API void ComputeProgramResetBindings(struct ComputeProgram_t* program);

/// Applies any binding changes to constant buffers, which usually occur when a dispatch call is issued,
/// to occur immediately.
AFTERWARP_API LibraryBool ComputeProgramCommit(struct ComputeProgram_t* program);

/// Activates the compute shader program.
AFTERWARP_API LibraryBool ComputeProgramBegin(struct ComputeProgram_t* program);

/// Deactivates the compute shader program.
AFTERWARP_API void ComputeProgramEnd(struct ComputeProgram_t* program);

/// Launches one or more compute shader work groups.
AFTERWARP_API LibraryBool ComputeProgramDispatch(struct ComputeProgram_t* program, int32_t groupsX,
  int32_t groupsY, int32_t groupsZ);

// Sampler functions.

/// Creates a new instance of sampler object.
AFTERWARP_API struct Sampler_t* SamplerCreate(struct Device_t* device, SamplerState const* samplerState);

/// Releases given instance of sampler object.
AFTERWARP_API void SamplerDestroy(struct Sampler_t* sampler);

/// Returns device associated with the given sampler.
AFTERWARP_API struct Device_t* SamplerGetDevice(struct Sampler_t* sampler);

/// Retrieves parameters associated with the sampler object.
AFTERWARP_API void SamplerGetState(struct Sampler_t* sampler, SamplerState* samplerState);

/// Updates parameters associated with the sampler object.
AFTERWARP_API LibraryBool SamplerSetState(struct Sampler_t* sampler, SamplerState const* samplerState);

/// Binds sampler object to a particular channel.
AFTERWARP_API LibraryBool SamplerBind(struct Sampler_t* sampler, uint32_t channel);

/// Unbinds sampler object from the particular channel.
AFTERWARP_API void SamplerUnbind(struct Sampler_t* sampler, uint32_t channel);

// Texture functions.

/// Creates a new instance of texture object.
AFTERWARP_API struct Texture_t* TextureCreate(struct Device_t* device, TextureParameters const* parameters);

/// Creates a new instance of texture object loading its contents from an external file. This function
/// typically supports most common file formats such as BMP, PNG, JPEG, but may also support other formats
/// like GIF and TIFF.
AFTERWARP_API struct Texture_t* TextureCreateFromFile(struct Device_t* device, char const* fileName,
  PixelFormat format, TextureAttributes attributes);

/// Creates texture containing displacement map for Parallax Mapping technique from an external file on disk.
AFTERWARP_API struct Texture_t* TextureCreateFromFileParallax(struct Device_t* device, char const* fileName,
  PixelFormat format, TextureAttributes attributes);

/// Creates texture containing normal map and occlusion map from external files on disk. Both normal and
/// occlusion map must have equal sizes.
AFTERWARP_API struct Texture_t* TextureCreateFromFileNormalsAndOcclusion(struct Device_t* device,
  char const* fileNameNormalMap, char const* fileNameOcclusionMap, TextureAttributes attributes);

/// Creates a new instance of texture object loading its contents from an image file that has been preloaded
/// into memory. The internal file format is determined by "extension" parameter, which should contain a
/// valid file extension such as \c .png (case-insensitive). This function typically supports most common
/// file formats such as \c BMP, \c PNG, \c JPEG, but may also support other formats like \c GIF and \c TIFF.
AFTERWARP_API struct Texture_t* TextureCreateFromFileInMemory(struct Device_t* device,
  void const* fileContents, uint32_t contentSize, char const* extension, PixelFormat format,
  TextureAttributes attributes);

/// Creates a new instance of texture object loading its contents from an existing surface.
AFTERWARP_API struct Texture_t* TextureCreateFromSurface(struct Device_t* device, struct Surface_t* surface,
  TextureAttributes attributes);

/// Releases given instance of texture object.
AFTERWARP_API void TextureDestroy(struct Texture_t* texture);

/// Returns device associated with the given texture.
AFTERWARP_API struct Device_t* TextureGetDevice(struct Texture_t* texture);

/// Returns platform-specific texture handle.
AFTERWARP_API UntypedHandle TextureGetPlatformHandle(struct Texture_t* texture);

/// Retrieves current texture parameters.
AFTERWARP_API void TextureGetParameters(struct Texture_t* texture, TextureParameters* parameters);

/// Copies content from user pointer to texture's owned memory at the given location. The data is assumed
/// to match texture's pixel format and destination rectangle, if specified, must be within valid bounds
/// (no clipping is performed).
AFTERWARP_API LibraryBool TextureUpdate(struct Texture_t* texture, void const* content, uint32_t pitch,
  int32_t layer, Rect const* rect, int32_t mipLevel);

/// Retrieves content from the given location of texture's owned memory to the user pointer. The data is
/// copied in its original format and source rectangle, if specified, must be within valid bounds
/// (no clipping is performed).
AFTERWARP_API LibraryBool TextureRetrieve(struct Texture_t* texture, void* content, uint32_t pitch,
  int32_t layer, Rect const* rect, int32_t mipLevel);

/// Copies a portion of source texture to the current one according to specified source rectangle and
/// destination position. If source rectangle is empty, then the entire source texture will be copied.
/// This function does the appropriate clipping and pixel format conversion (albeit at significant
/// performance cost). Note that \c premultipliedAlpha attribute of either current or source texture is
/// completely ignored.
AFTERWARP_API LibraryBool TextureCopy(struct Texture_t* texture, struct Texture_t* source,
  int32_t destLayer, Point const* destPos, int32_t srcLayer, Rect const* sourceRect, int32_t destMipLevel,
  int32_t srcMipLevel);

/// Copies a portion of source surface to the current texture according to specified source rectangle and
/// destination position. If source rectangle is empty, then the entire source surface will be copied.
/// This function does the appropriate clipping and pixel format conversion. Note that \c
/// premultipliedAlpha attribute of either current or source surface is completely ignored.
AFTERWARP_API LibraryBool TextureCopyFromSurface(struct Texture_t* texture, struct Surface_t* surface,
  int32_t layer, Point const* destPos, Rect const* sourceRect, int32_t mipLevel);

/// Copies a portion of current texture to the destination surface according to specified source rectangle
/// and destination position. If source rectangle is empty, then the entire texture surface will be copied.
/// This function does the appropriate clipping and pixel format conversion. Note that \c
/// premultipliedAlpha attribute of either current or source surface is completely ignored.
AFTERWARP_API LibraryBool TextureCopyToSurface(struct Texture_t* texture, struct Surface_t* surface,
  int32_t layer, Point const* destPos, Rect const* sourceRect, int32_t mipLevel);

/// Loads image from disk and copies it to the specified location and parameters.
AFTERWARP_API LibraryBool TextureLoadFromFile(struct Texture_t* texture, char const* fileName,
  int32_t layer, Point const* destPos, Rect const* sourceRect, int32_t mipLevel);

/// Saves the appropriate portion of texture to external file.
AFTERWARP_API LibraryBool TextureSaveToFile(struct Texture_t* texture, char const* fileName,
  int32_t quality, int32_t layer, Rect const* sourceRect, int32_t mipLevel);

/// Clears entire texture surface and fills pixels with zeros.
AFTERWARP_API LibraryBool TextureClear(struct Texture_t* texture);

/// Clears texture surface with the given color.
/// This must be called outside of device and texture \c TextureBegin() / \c TextureEnd() blocks.
AFTERWARP_API LibraryBool TextureClearWith(struct Texture_t* texture, FloatColor const* color,
  int32_t layer, int32_t mipLevel);

/// Binds texture to the specified rendering channel.
AFTERWARP_API LibraryBool TextureBind(struct Texture_t* texture, uint32_t channel);

/// Unbinds texture from the specified rendering channel.
AFTERWARP_API LibraryBool TextureUnbind(struct Texture_t* texture, uint32_t channel);

/// Attaches another drawable texture with the current texture into a common MRT rendering stack.
/// Drawable textures will be available to shaders in the same order of attachment.
AFTERWARP_API LibraryBool TextureAttach(struct Texture_t* texture, struct Texture_t* attachment,
  int32_t layer, int32_t mipLevel);

/// Removes all previous drawable texture attachments.
AFTERWARP_API void TextureDetach(struct Texture_t* texture);

/// Starts rendering on the drawable texture.
AFTERWARP_API LibraryBool TextureBegin(struct Texture_t* texture, int32_t layer, int32_t mipLevel);

/// Finishes rendering on the drawable texture.
AFTERWARP_API LibraryBool TextureEnd(struct Texture_t* texture);

/// Generates texture's mipmaps from its base (level = 0) image.
AFTERWARP_API LibraryBool TextureGenerateMipMaps(struct Texture_t* texture);

/// Resets any cache associated with the texture, which means purging any temporary resources.
/// This also removes all existing texture attachments.
AFTERWARP_API void TextureResetCache(struct Texture_t* texture);

// Surface functions.

/// Creates a new instance of raster surface.
AFTERWARP_API struct Surface_t* SurfaceCreate(int32_t width, int32_t height, PixelFormat format);

/// Creates a new instance of raster surface containing image loaded from external file. The preference for
/// premultiplied or non-premultiplied alpha-channel is merely a suggestion, which can influence how the
/// image is loaded (depending on underlying implementation). This function typically supports most common
/// file formats such as BMP, PNG, JPEG, but may also support other formats like GIF and TIFF.
AFTERWARP_API struct Surface_t* SurfaceCreateFromFile(char const* fileName,
  AlphaFormatRequest formatRequest);

/// Creates a new instance of raster surface containing image loaded from file that has been preloaded into
/// memory. The internal file format is determined by "extension" parameter, which should contain a valid
/// file extension such as \c .png (case-insensitive). The preference for premultiplied or non-premultiplied
/// alpha-channel is merely a suggestion, which can influence how the image is loaded (depending on
/// underlying implementation). This function typically supports most common file formats such as \c BMP,
/// \c PNG, \c JPEG, but may also support other formats like \c GIF and \c TIFF.
AFTERWARP_API struct Surface_t* SurfaceCreateFromFileInMemory(void const* fileContents,
  uint32_t contentSize, char const* extension, AlphaFormatRequest formatRequest);

/// Releases given instance of raster surface.
AFTERWARP_API void SurfaceDestroy(struct Surface_t* surface);

/// Returns pointer to top/left corner of pixel data contained by this surface, with horizontal rows
/// arranged linearly from top to bottom.
AFTERWARP_API void* SurfaceGetBits(struct Surface_t* surface);

/// Returns number of bytes each horizontal row of pixels occupies. This may differ from an actual
/// calculated number and may include unused or even protected memory locations, which should be
/// considered read-only and be skipped.
AFTERWARP_API uint32_t SurfaceGetPitch(struct Surface_t* surface);

/// Returns number of bytes each pixel occupies.
AFTERWARP_API int32_t SurfaceGetBytesPerPixel(struct Surface_t* surface);

/// Returns surface width in pixels.
AFTERWARP_API int32_t SurfaceGetWidth(struct Surface_t* surface);

/// Returns surface height in pixels.
AFTERWARP_API int32_t SurfaceGetHeight(struct Surface_t* surface);

/// Returns surface size in bytes.
AFTERWARP_API uint32_t SurfaceGetByteSize(struct Surface_t* surface);

/// Returns pixel format in which pixels are stored.
AFTERWARP_API PixelFormat SurfaceGetFormat(struct Surface_t* surface);

/// Indicates whether the pixels in this surface have their alpha premultiplied or not. This is just an
/// informative parameter; to actually convert pixels from one mode to another, use
/// \c SurfacePremultiplyAlpha() and \c SurfaceUnpremultiplyAlpha() methods.
AFTERWARP_API LibraryBool SurfaceGetPremultipliedAlpha(struct Surface_t* surface);

/// Changes attribute of premultiplied alpha in the surface. This is just an informative parameter;
/// to actually convert pixels from one mode to another, use  \c SurfacePremultiplyAlpha() and
/// \c SurfaceUnpremultiplyAlpha() methods.
AFTERWARP_API void SurfaceSetPremultipliedAlpha(struct Surface_t* surface, LibraryBool premultipliedAlpha);

/// Provides pointer to a first pixel at the given scanline index (that is, row number).
AFTERWARP_API void* SurfaceGetScanline(struct Surface_t* surface, int32_t index);

/// Provides pointer to the pixel data at the given coordinates.
AFTERWARP_API void* SurfaceGetPixelPtr(struct Surface_t* surface, int32_t x, int32_t y);

/// Checks whether the surface has width or height set to zero, has undefined pixel format, unknown
/// pitch, unknown bytes per pixel, or access bits set to NULL.
/// If this returns false, then the surface can be considered valid.
AFTERWARP_API LibraryBool SurfaceEmpty(struct Surface_t* surface);

/// Redefines surface size to the specified width, height and pixel format, discarding previous contents.
AFTERWARP_API LibraryBool SurfaceResize(struct Surface_t* surface, int32_t width, int32_t height,
  PixelFormat format);

/// Converts surface from its current format to another one.
AFTERWARP_API LibraryBool SurfaceConvertFormat(struct Surface_t* surface, PixelFormat format);

/// Reads a single pixel from the surface.
AFTERWARP_API Color SurfaceGetPixel(struct Surface_t* surface, int32_t x, int32_t y);

/// Writes a single pixel to the surface.
AFTERWARP_API void SurfaceSetPixel(struct Surface_t* surface, int32_t x, int32_t y, Color color);

/// Retrieves pixel from floating-point coordinates, interpolating linearly between four neighbor pixels
/// as necessary to get an accurate match. This can be used for limitless stretching, to get color values
/// that lie between individual pixels and slowly change from one pixel to another.
AFTERWARP_API Color SurfaceGetPixelBilinear(struct Surface_t* surface, float x, float y);

/// Copies a portion of source surface to the current one according to specified source rectangle and
/// destination position. If source rectangle is empty (or \c NULL), then the entire source surface will be
/// copied. This function does the appropriate clipping and pixel format conversion. It does not change
/// current surface size or pixel format. Note that "premultiplied alpha" flag of either current or source
/// surfaces is completely ignored.
AFTERWARP_API LibraryBool SurfaceCopyRect(struct Surface_t* surface, struct Surface_t* source,
  Rect const* sourceRect, Point const* destPos);

/// Copies entire contents from a source surface to the current one. If the current surface has size and/or
/// pixel format not specified, these will be copied from the source surface as well. If current surface is
/// not empty, then its pixel format will not be modified - in this case, pixel format conversion may occur.
/// This function will try to ensure that current surface size matches the source surface and if if this
/// cannot be achieved, it will fail.
AFTERWARP_API LibraryBool SurfaceCopyFrom(struct Surface_t* surface, struct Surface_t* source);

/// Clears the entire surface with zeros.
AFTERWARP_API void SurfaceClear(struct Surface_t* surface);

/// Clears the entire surface with a given color. This does pixel format conversion when appropriate.
AFTERWARP_API LibraryBool SurfaceClearWith(struct Surface_t* surface, Color color);

/// Processes surface pixels, setting alpha-channel to either fully translucent or fully opaque.
AFTERWARP_API LibraryBool SurfaceResetAlpha(struct Surface_t* surface, LibraryBool opaque);

/// Processes the whole surface to determine whether it has meaningful alpha-channel. A surface that has all
/// its pixels with alpha-channel set to fully translucent or fully opaque (but not mixed) is considered
/// lacking alpha-channel. On the other hand, a surface that has at least one pixel with alpha-channel value
/// different than any other pixel, is considered to have alpha-channel. This is useful to determine whether
/// the surface can be stored in one of pixel formats lacking alpha-channel, to avoid losing any
/// transparency information.
AFTERWARP_API LibraryBool SurfaceHasAlphaChannel(struct Surface_t* surface);

/// Processes the whole surface, premultiplying each pixel's red, green and blue values by the corresponding
/// alpha-channel value, resulting in image with premultiplied alpha. Note that this is an irreversible
/// process, during which some color information is lost permanently (smaller alpha values contribute to
/// bigger information loss). This is generally useful to prepare the image for generating mipmaps and/or
/// alpha-blending, to get more accurate visual results.
AFTERWARP_API LibraryBool SurfacePremultiplyAlpha(struct Surface_t* surface);

/// Processes the whole surface, dividing each pixel by its alpha-value, resulting in image with
/// non-premultiplied alpha. During this process, some color information may be lost due to precision
/// issues. This can be useful to obtain original pixel information from image that has been previously
/// premultiplied; however, this does not recover lost information during premultiplication process. For
/// instance, pixels that had alpha value of zero and were premultiplied, lose all information and cannot be
/// recovered; pixels with alpha value of 128 (that is, 50% opaque) lose half of their precision and after
/// "unpremultiply" process will have values multiples of 2.
AFTERWARP_API LibraryBool SurfaceUnpremultiplyAlpha(struct Surface_t* surface);

/// Mirrors the visible image on surface horizontally.
AFTERWARP_API LibraryBool SurfaceMirror(struct Surface_t* surface);

/// Flips the visible image on surface vertically.
AFTERWARP_API LibraryBool SurfaceFlip(struct Surface_t* surface);

/// Inverts colors in the surface.
AFTERWARP_API LibraryBool SurfaceInvert(struct Surface_t* surface);

/// This function works similarly to \c SurfaceCopyFrom(), except that it produces image with half of size,
/// averaging each four pixels to one. This is specifically useful to generate mipmaps.
AFTERWARP_API LibraryBool SurfaceShrinkFrom(struct Surface_t* surface, struct Surface_t* source);

/// This function works similarly to \c SurfaceCopyRect(), but provides stretching and/or shrinking.
/// That is, it copies source surface rectangle onto destination rectangle with point filtering.
/// Clipping and pixel format conversion is done as necessary.
AFTERWARP_API LibraryBool SurfaceStretchRect(struct Surface_t* surface, struct Surface_t* source,
  RectF const* destRect, RectF const* sourceRect);

/// This function works similarly to \c SurfaceCopyRect(), but provides bilinear stretching. That is, it
/// copies source surface rectangle onto destination rectangle with linear filtering. Clipping and pixel
/// format conversion is done as necessary. Note that this function is meant for stretching only; shrinking
/// although will also work, but result in inaccurate results as shrinking requires calculating average of
/// variable number of pixels depending on shrink ratio.
AFTERWARP_API LibraryBool SurfaceStretchRectBilinear(struct Surface_t* surface, struct Surface_t* source,
  RectF const* destRect, RectF const* sourceRect);

/// Calculates signed distance field from alpha values of the source.
AFTERWARP_API LibraryBool SurfaceMakeSignedDistanceField(struct Surface_t* surface,
  struct Surface_t* source, float spread, Point const* destPos, Rect const* sourceRect);

/// Saves the contents of the surface to external file. This function typically supports most common file
/// formats such as BMP, PNG, JPEG, but may also support other formats like GIF and TIFF. "Quality"
/// parameter, in case of formats such as JPEG, determines the compression ratio (between 0 and 100).
AFTERWARP_API LibraryBool SurfaceSaveToFile(struct Surface_t* surface, char const* fileName,
  int32_t quality);

/// Saves the contents of surface to a file in memory and returns the size of resulting file. This function
/// will save up to "fileContentSize" bytes to the provided pointer, even if it means that not a complete
/// file will be saved. If "fileContents" pointer is NULL, then this function will provide an estimate size
/// required to store the file in memory. This function typically supports most common file formats such
/// as BMP, PNG, JPEG, but may also support other formats like GIF and TIFF. \c quality parameter, in case
/// of formats such as JPEG, determines the compression ratio (between 0 and 100).
AFTERWARP_API uint32_t SurfaceSaveToFileInMemory(struct Surface_t* surface, void* fileContents,
  uint32_t fileContentSize, char const* extension, int32_t quality);

// TODO: expose canvas for surface.

// CanvasBuffer functions.

/// Creates a new container for vertices and indices defining one or more triangular meshes that can be
/// suitable for rendering with a 2D canvas.
AFTERWARP_API struct CanvasBuffer_t* CanvasBufferCreate(void);

/// Releases an existing instance of canvas buffer container.
AFTERWARP_API void CanvasBufferDestroy(struct CanvasBuffer_t* buffer);

/// Returns existing number of vertices.
AFTERWARP_API int32_t CanvasBufferGetVertexCount(struct CanvasBuffer_t* buffer);

/// Adjusts the existing number of vertices.
AFTERWARP_API LibraryBool CanvasBufferSetVertexCount(struct CanvasBuffer_t* buffer, int32_t vertexCount);

/// Returns existing number of indices.
AFTERWARP_API int32_t CanvasBufferGetIndexCount(struct CanvasBuffer_t* buffer);

/// Adjusts the existing number of indices.
AFTERWARP_API LibraryBool CanvasBufferSetIndexCount(struct CanvasBuffer_t* buffer, int32_t indexCount);

/// Clears all buffers.
AFTERWARP_API void CanvasBufferClear(struct CanvasBuffer_t* buffer);

/// Clears all buffers and releases their memory.
AFTERWARP_API void CanvasBufferClearAndShrink(struct CanvasBuffer_t* buffer);

/// Returns pointer to an existing array of vertices.
AFTERWARP_API PointF* CanvasBufferGetVertices(struct CanvasBuffer_t* buffer);

/// Returns pointer to an existing array of colors.
AFTERWARP_API Color* CanvasBufferGetColors(struct CanvasBuffer_t* buffer);

/// Returns pointer to an existing array of vertex indices.
AFTERWARP_API int32_t* CanvasBufferGetIndices(struct CanvasBuffer_t* buffer);

/// Calculates boundaries for the existing vertices.
AFTERWARP_API void CanvasBufferGetExtents(struct CanvasBuffer_t* buffer, RectF* extents);

// PathBroker functions.

/// Creates a new module for creating paths.
AFTERWARP_API struct PathBroker_t* PathBrokerCreate(void);

/// Releases an existing instance of path creation module.
AFTERWARP_API void PathBrokerDestroy(struct PathBroker_t* broker);

/// Pre-renders a fill for the given path. \c quality parameter determines how the resulting contours are
/// triangulated.
AFTERWARP_API LibraryBool PathBrokerFill(struct PathBroker_t* broker, struct CanvasBuffer_t* buffer,
  PathElement const path[], int32_t pathLength, ColorRect const* colors, LibraryBool quality);

/// Pre-renders a stroke for the given path.
AFTERWARP_API LibraryBool PathBrokerStroke(struct PathBroker_t* broker, struct CanvasBuffer_t* buffer,
  PathElement const path[], int32_t pathLength, float thickness, Color color, PathJoint joints,
  LineCaps caps, float miterLimit, float smoothStep);

/// Resets internal cache and releases any allocated memory.
AFTERWARP_API void PathBrokerReset(struct PathBroker_t* broker);

// Canvas functions.

/// Creates new 2D rendering canvas.
AFTERWARP_API struct Canvas_t* CanvasCreate(struct Device_t* device);

/// Releases given instance of 2D rendering canvas.
AFTERWARP_API void CanvasDestroy(struct Canvas_t* canvas);

/// Returns device associated with the given canvas.
AFTERWARP_API struct Device_t* CanvasGetDevice(struct Canvas_t* canvas);

/// Starts rendering with the canvas.
AFTERWARP_API LibraryBool CanvasBegin(struct Canvas_t* canvas);

/// Finishes rendering with the canvas.
AFTERWARP_API void CanvasEnd(struct Canvas_t* canvas);

/// Draws pixels with the given positions and colors.
AFTERWARP_API void CanvasPixels(struct Canvas_t* canvas, PointF const positions[], Color const colors[],
  int32_t elementCount, BlendingEffect effect);

/// Draws lines with the given vertices, colors and indices.
AFTERWARP_API void CanvasLines(struct Canvas_t* canvas, PointF const vertices[], Color const colors[],
  int32_t const indices[], int32_t vertexCount, int32_t primitiveCount, BlendingEffect effect);

/// Draws triangles with the given vertices, colors and indices.
AFTERWARP_API void CanvasTriangles(struct Canvas_t* canvas, PointF const vertices[], Color const colors[],
  int32_t const indices[], int32_t vertexCount, int32_t primitiveCount, BlendingEffect effect);

/// Draws triangles with the given vertices, texture coordinates, colors and indices.
AFTERWARP_API void CanvasTexturedTriangles(struct Canvas_t* canvas, struct Texture_t* texture,
  PointF const vertices[], PointF const texCoords[], Color const colors[], int32_t const indices[],
  int32_t vertexCount, int32_t primitiveCount, BlendingEffect effect);

/// Draws a pixel with the given position and color.
AFTERWARP_API void CanvasPixel(struct Canvas_t* canvas, PointF const* position, Color color,
  BlendingEffect effect);

/// Draws a line with the given positions and colors.
AFTERWARP_API void CanvasLine(struct Canvas_t* canvas, PointF const* srcPos, PointF const* destPos,
  ColorPair const* colors, BlendingEffect effect);

/// Draws a line of varying thickness with the given positions and colors.
AFTERWARP_API void CanvasThickLine(struct Canvas_t* canvas, PointF const* srcPos, PointF const* destPos,
  ColorPair const* colors, float thickness, BlendingEffect effect);

/// Draws ellipse with the given origin, radiuses, color and steps using "line" primitive.
AFTERWARP_API void CanvasLineEllipse(struct Canvas_t* canvas, PointF const* origin, PointF const* radius,
  int32_t steps, Color color, BlendingEffect effect);

/// Draws circle with the given origin, radius, color and steps using "line" primitive.
AFTERWARP_API void CanvasLineCircle(struct Canvas_t* canvas, PointF const* origin, float radius,
  int32_t steps, Color color, BlendingEffect effect);

/// Draws ellipse of varying thickness with the given origin, radiuses, color and steps.
AFTERWARP_API void CanvasThickLineEllipse(struct Canvas_t* canvas, PointF const* origin,
  PointF const* radius, int32_t steps, Color color, float thickness, BlendingEffect effect);

/// Draws circle of varying thickness with the given origin, radius, color and steps.
AFTERWARP_API void CanvasThickLineCircle(struct Canvas_t* canvas, PointF const* origin, float radius,
  int32_t steps, Color color, float thickness, BlendingEffect effect);

/// Draws lines between specified triangle vertices and colors.
AFTERWARP_API void CanvasLineTriangle(struct Canvas_t* canvas, PointF const* vertex1, PointF const* vertex2,
  PointF const* vertex3, Color color1, Color color2, Color color3, BlendingEffect effect);

/// Draws line path of varying thickness between specified triangle vertices and colors.
AFTERWARP_API void CanvasThickLineTriangle(struct Canvas_t* canvas, PointF const* vertex1,
  PointF const* vertex2, PointF const* vertex3, Color color1, Color color2, Color color3, float thickness,
  BlendingEffect effect);

/// Draws a wireframe quadrilateral with the given vertices and colors using "line" primitive.
AFTERWARP_API void CanvasLineQuad(struct Canvas_t* canvas, Quad const* vertices, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a wireframe quadrilateral of varying thickness with the given vertices and colors.
AFTERWARP_API void CanvasThickLineQuad(struct Canvas_t* canvas, Quad const* vertices,
  ColorRect const* colors, float thickness, BlendingEffect effect);

/// Draws lines between each vertex in a hexagon of unity size centered along axis origin and drawn with
/// gradient of six colors at the corresponding vertices. The bounding width of hexagon is exactly one,
/// which simplifies placement of multiple hexagons. The final size, position and rotation of hexagon can
/// be given using one or a combination of several 3x2 transformation matrices multiplied together.
/// This method uses \c line primitive.
AFTERWARP_API void CanvasLineHexagon(struct Canvas_t* canvas, Color color1, Color color2, Color color3,
  Color color4, Color color5, Color color6, BlendingEffect effect);

/// Draws lines between each vertex in a hexagon of unity size centered along axis origin and filled with
/// four-color gradient interpolated to the corresponding vertices. The bounding width of hexagon is
/// exactly one, which simplifies placement of multiple hexagons. The final size, position and rotation of
/// hexagon can be given using one or a combination of several 3x2 transformation matrices multiplied
/// together. This method uses \c line primitive.
AFTERWARP_API void CanvasLineHexagonGrad(struct Canvas_t* canvas, ColorRect const* colors,
  BlendingEffect effect);

/// Draws lines of varying thickness between each vertex in a hexagon of unity size centered along axis
/// origin and drawn with gradient of six colors at the corresponding corners. The final size, position
/// and rotation of hexagon can be given using one or a combination of several 3x2 transformation matrices
/// multiplied together.
AFTERWARP_API void CanvasThickLineHexagon(struct Canvas_t* canvas, Color color1, Color color2, Color color3,
  Color color4, Color color5, Color color6, float thickness, BlendingEffect effect);

/// Draws lines of varying thickness between each vertex in a hexagon of unity size centered along axis
/// origin and filled with four-color gradient interpolated to the corresponding vertices. The final size,
/// position and rotation of hexagon can be given using one or a combination of several 3x2 transformation
/// matrices multiplied together.
AFTERWARP_API void CanvasThickLineHexagonGrad(struct Canvas_t* canvas, ColorRect const* colors,
  float thickness, BlendingEffect effect);

// TODO: lineArc and thickLineArc

/// Draws triangle filled with color gradient specified by given positions and colors.
AFTERWARP_API void CanvasTriangle(struct Canvas_t* canvas, PointF const* vertex1, PointF const* vertex2,
  PointF const* vertex3, Color color1, Color color2, Color color3, BlendingEffect effect);

/// Draws a filled quadrilateral with the given vertices and colors.
AFTERWARP_API void CanvasQuad(struct Canvas_t* canvas, Quad const* vertices, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a filled rectangle with the given vertices and colors.
AFTERWARP_API void CanvasFillRect(struct Canvas_t* canvas, RectF const* rect, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a rectangle of varying thickness with the given vertices and colors.
AFTERWARP_API void CanvasFrameRect(struct Canvas_t* canvas, RectF const* rect, ColorRect const* colors,
  float thickness, BlendingEffect effect);

// NOTE: Other fillRect(), frameRect(), horizLine() and vertLine() overloads are not exposed.

/// Draws a filled rectangle with the given gradient and round corners.
AFTERWARP_API void CanvasFillRoundRect(struct Canvas_t* canvas, RectF const* rect, ColorRect const* colors,
  float radius, int32_t steps, BlendingEffect effect);

/// Draws a round frame for the given rectangle area with varying thickness and gradient.
AFTERWARP_API void CanvasFrameRoundRect(struct Canvas_t* canvas, RectF const* rect, ColorRect const* colors,
  float radius, float thickness, int32_t steps, BlendingEffect effect);

/// Draws a filled rectangle with the given gradient and round corners on top.
AFTERWARP_API void CanvasFillRoundRectTop(struct Canvas_t* canvas, RectF const* rect,
  ColorRect const* colors, float radius, int32_t steps, BlendingEffect effect);

/// Draws a filled rectangle with the given gradient and round corners on bottom.
AFTERWARP_API void CanvasFillRoundRectBottom(struct Canvas_t* canvas, RectF const* rect,
  ColorRect const* colors, float radius, int32_t steps, BlendingEffect effect);

/// Draws a filled rectangle with the given gradient and round corners, but top is reverted.
/// This can be used to render rounded window background behind caption.
AFTERWARP_API void CanvasFillRoundRectTopInverse(struct Canvas_t* canvas, RectF const* rect,
  ColorRect const* colors, float radius, int32_t steps, BlendingEffect effect);

/// Draws either a highlight or a shadow around the specified rectangle with the given parameters,
/// mimicking effect of gaussian highlight.
AFTERWARP_API void CanvasHighlight(struct Canvas_t* canvas, RectF const* rect, float cornerRadius,
  float luma, float distance, int32_t steps);

/// Draws hexagon of unity size centered along axis origin and filled with gradient of six colors at the
/// corresponding vertices. The bounding width of hexagon is exactly one, which simplifies placement of
/// multiple hexagons. The final size, position and rotation of hexagon can be given using one or a
/// combination of several 3x2 transformation matrices multiplied together.
AFTERWARP_API void CanvasHexagon(struct Canvas_t* canvas, Color color1, Color color2, Color color3,
  Color color4, Color color5, Color color6, BlendingEffect effect);

/// Draws hexagon of unity size centered along axis origin and filled with four-color gradient interpolated
/// to the corresponding vertices. The bounding width of hexagon is exactly one, which simplifies placement
/// of multiple hexagons. The final size, position and rotation of hexagon can be given using one or a
/// combination of several 3x2 transformation matrices multiplied together.
AFTERWARP_API void CanvasHexagonGrad(struct Canvas_t* canvas, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a filled arc with the given origin, radiuses, angles, steps and color gradient going away from
/// the center of the arc.
AFTERWARP_API void CanvasArc(struct Canvas_t* canvas, PointF const* origin, PointF const* radius,
  float initAngle, float endAngle, int32_t steps, Color colorInside, Color colorOutside,
  BlendingEffect effect);

/// Draws a filled arc with the given origin, radiuses, angles, steps and colors.
AFTERWARP_API void CanvasArcGrad(struct Canvas_t* canvas, PointF const* origin, PointF const* radius,
  float initAngle, float endAngle, int32_t steps, ColorRect const* colors, BlendingEffect effect);

/// Draws a filled ellipse with the given origin, radiuses, steps and colors.
AFTERWARP_API void CanvasEllipse(struct Canvas_t* canvas, PointF const* origin, PointF const* radius,
  int32_t steps, ColorRect const* colors, BlendingEffect effect);

/// Draws a filled ribbon between inner and outer radiuses filled with four-color gradient.
AFTERWARP_API void CanvasRibbonGrad(struct Canvas_t* canvas, PointF const* origin,
  PointF const* insideRadius, PointF const* outsideRadius, int32_t steps, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a filled ribbon between inner and outer radiuses filled with continuous three-pair gradient.
AFTERWARP_API void CanvasRibbonTri(struct Canvas_t* canvas, PointF const* origin,
  PointF const* insideRadius, PointF const* outsideRadius, int32_t steps, ColorPair const* color1,
  ColorPair const* color2, ColorPair const* color3, BlendingEffect effect);

/// Draws a filled ribbon between inner and outer radiuses filled with a single color.
AFTERWARP_API void CanvasRibbon(struct Canvas_t* canvas, PointF const* origin, PointF const* insideRadius,
  PointF const* outsideRadius, int32_t steps, Color color, BlendingEffect effect);

/// Draws a filled tape between the given radiuses and angles, filled with four-color gradient.
AFTERWARP_API void CanvasTapeGrad(struct Canvas_t* canvas, PointF const* origin, PointF const* insideRadius,
  PointF const* outsideRadius, float initAngle, float endAngle, int32_t steps, ColorRect const* colors,
  BlendingEffect effect);

/// Draws a filled tape between the given radiuses and angles, filled with continuous three-pair gradient.
AFTERWARP_API void CanvasTapeTri(struct Canvas_t* canvas, PointF const* origin, PointF const* insideRadius,
  PointF const* outsideRadius, float initAngle, float endAngle, int32_t steps, ColorPair const* color1,
  ColorPair const* color2, ColorPair const* color3, BlendingEffect effect);

/// Draws a filled tape between the given radiuses and angles, filled with a single color.
AFTERWARP_API void CanvasTape(struct Canvas_t* canvas, PointF const* origin, PointF const* insideRadius,
  PointF const* outsideRadius, float initAngle, float endAngle, int32_t steps, Color color,
  BlendingEffect effect);

/// Draws a filled rectangle with a hole inside of it, filled with the given colors.
AFTERWARP_API void CanvasRectWithHole(struct Canvas_t* canvas, RectF const* rect, PointF const* holeOrigin,
  PointF const* holeRadius, ColorPair const* colors, int32_t steps, BlendingEffect effect);

/// Draws triangles from an existing buffer.
AFTERWARP_API void CanvasDrawBuffer(struct Canvas_t* canvas, struct CanvasBuffer_t* buffer,
  BlendingEffect effect);

/// Draws a textured triangle multiplied with a color gradient specified by given positions, colors and
/// texture coordinates (in range from 0 to 1).
AFTERWARP_API void CanvasTexturedTriangle(struct Canvas_t* canvas, struct Texture_t* texture,
  PointF const* vertex1, PointF const* vertex2, PointF const* vertex3, PointF const* texCoord1,
  PointF const* texCoord2, PointF const* texCoord3, Color color1, Color color2, Color color3,
  BlendingEffect effect);

/// Draws a textured triangle multiplied with a color gradient specified by given positions, colors and
/// texture coordinates (in pixels).
AFTERWARP_API void CanvasTexturedTriangleRegion(struct Canvas_t* canvas, struct Texture_t* texture,
  PointF const* vertex1, PointF const* vertex2, PointF const* vertex3, PointF const* texCoord1,
  PointF const* texCoord2, PointF const* texCoord3, Color color1, Color color2, Color color3,
  BlendingEffect effect);

/// Draws a textured quadrilateral multiplied with a color gradient specified by the given vertices,
/// colors and texture coordinates (in range from 0 to 1).
AFTERWARP_API void CanvasTexturedQuad(struct Canvas_t* canvas, struct Texture_t* texture,
  Quad const* vertices, Quad const* texCoords, ColorRect const* colors, BlendingEffect effect);

/// Draws a textured quadrilateral multiplied with a color gradient specified by the given vertices,
/// colors and texture coordinates (in pixels).
AFTERWARP_API void CanvasTexturedQuadRegion(struct Canvas_t* canvas, struct Texture_t* texture,
  Quad const* vertices, Quad const* texCoords, ColorRect const* colors, BlendingEffect effect);

/// Draws a textured rectangle with round corners and the given gradient and texture coordinates.
AFTERWARP_API void CanvasTexturedRoundRect(struct Canvas_t* canvas, struct Texture_t* texture,
  RectF const* rect, Quad const* texCoords, ColorRect const* colors, float radius, int32_t steps,
  BlendingEffect effect);

/// Draws a textured rectangle with round corners and the given gradient and texture
/// coordinates (in pixels).
AFTERWARP_API void CanvasTexturedRoundRectRegion(struct Canvas_t* canvas, struct Texture_t* texture,
  RectF const* rect, Quad const* texCoords, ColorRect const* colors, float radius, int32_t steps,
  BlendingEffect effect);

/// Draws a textured quadrilateral from source portion of image atlas, multiplied by a color gradient.
AFTERWARP_API void CanvasQuadImage(struct Canvas_t* canvas, struct ImageAtlas_t* imageAtlas,
  Quad const* vertices, int32_t regionIndex, ColorRect const* colors, RectF const* sourceRect,
  uint32_t modifiers, BlendingEffect effect);

/// Sets new 3D world transformation matrix.
AFTERWARP_API void CanvasSetWorld(struct Canvas_t* canvas, Matrix const* world);

/// Retrieves current 3D world transformation matrix.
AFTERWARP_API void CanvasGetWorld(struct Canvas_t* canvas, Matrix* world);

/// Sets new 3D view/projection transformation matrix.
AFTERWARP_API void CanvasSetViewProjection(struct Canvas_t* canvas, Matrix const* viewProjection);

/// Retrieves current 3D view/projection transformation matrix.
AFTERWARP_API void CanvasGetViewProjection(struct Canvas_t* canvas, Matrix* viewProjection);

/// Changes 2D transformation matrix.
AFTERWARP_API void CanvasSetTransform(struct Canvas_t* canvas, Matrix3x2 const* transform);

/// Returns currently set 2D transformation matrix.
AFTERWARP_API void CanvasGetTransform(struct Canvas_t* canvas, Matrix3x2* transform);

/// Sets new Signed Distance Field (SDF) parameters. The actual SDF rendering needs to be enabled by
/// specifying one of the appropriate canvas attributes.
AFTERWARP_API void CanvasSetSignedDistanceField(struct Canvas_t* canvas,
  SignedDistanceField const* signedDistanceField);

/// Retrieves current 3D transformation (world/view/projection) matrix.
AFTERWARP_API void CanvasGetSignedDistanceField(struct Canvas_t* canvas,
  SignedDistanceField* signedDistanceField);

/// Returns currently configured canvas context state.
AFTERWARP_API CanvasContextState CanvasGetContextState(struct Canvas_t* canvas);

/// Configures device rendering state to one of pre-defined canvas states.
AFTERWARP_API LibraryBool CanvasSetContextState(struct Canvas_t* canvas,
  CanvasContextState contextState);

/// Sets new canvas sampler state.
AFTERWARP_API LibraryBool CanvasSetSamplerState(struct Canvas_t* canvas,
  CanvasSamplerState const* samplerState);

/// Retrieves current canvas sampler state (if such exists).
AFTERWARP_API LibraryBool CanvasGetSamplerState(struct Canvas_t* canvas,
  CanvasSamplerState* samplerState);

/// Resets any canvas sampler state that is currently set.
AFTERWARP_API void CanvasResetSamplerState(struct Canvas_t* canvas);

/// Sets new canvas rendering attributes.
AFTERWARP_API void CanvasSetAttributes(struct Canvas_t* canvas, uint32_t attributes);

/// Retrieves current canvas rendering attributes.
AFTERWARP_API uint32_t CanvasGetAttributes(struct Canvas_t* canvas);

/// Flushes the canvas by rendering primitives that are still in batch buffers.
AFTERWARP_API void CanvasFlush(struct Canvas_t* canvas);

/// Clears canvas internal buffers and cached resources.
AFTERWARP_API void CanvasReset(struct Canvas_t* canvas);

/// Returns number of batches that were rendered between current set of begin/end block. Drawing each
/// individual batch involves some overhead, so when this parameter happens to be considerably high at some
/// point, the rendering code should be revised for better grouping of images, shapes and blending types.
AFTERWARP_API int32_t CanvasGetBatchCount(struct Canvas_t* canvas);

/// Returns currently set clipping rectangle.
AFTERWARP_API void CanvasGetClipRect(struct Canvas_t* canvas, Rect* clipRect);

/// Sets new clipping rectangle.
AFTERWARP_API LibraryBool CanvasSetClipRect(struct Canvas_t* canvas, Rect const* rect);

// ImageAtlas functions.

/// Creates new instance of image atlas associated with a particular device.
AFTERWARP_API struct ImageAtlas_t* ImageAtlasCreate(struct Device_t* device);

/// Releases given instance of image atlas.
AFTERWARP_API void ImageAtlasDestroy(struct ImageAtlas_t* atlas);

/// Returns device associated with the given image atlas.
AFTERWARP_API struct Device_t* ImageAtlasGetDevice(struct ImageAtlas_t* atlas);

/// Returns the number of textures contained within the atlas.
AFTERWARP_API int32_t ImageAtlasTextureCount(struct ImageAtlas_t* atlas);

/// Returns texture associated with a particular index or NULL if such is not available.
AFTERWARP_API struct Texture_t* ImageAtlasTexture(struct ImageAtlas_t* atlas, int32_t textureIndex);

/// Returns the number of regions contained within the atlas.
AFTERWARP_API int32_t ImageAtlasRegionCount(struct ImageAtlas_t* atlas);

/// Returns region information for the given index.
AFTERWARP_API LibraryBool ImageAtlasRegion(struct ImageAtlas_t* atlas, int32_t regionIndex,
  ImageRegion* region);

/// Creates and adds a new region to the list.
AFTERWARP_API int32_t ImageAtlasCreateRegion(struct ImageAtlas_t* atlas, Rect const* rect,
  int32_t textureIndex);

/// Removes region with given index from the list.
AFTERWARP_API void ImageAtlasRemoveRegion(struct ImageAtlas_t* atlas, int32_t regionIndex);

/// Removes all regions.
AFTERWARP_API void ImageAtlasClearRegions(struct ImageAtlas_t* atlas);

/// Creates list of regions based on repeated rectangular pattern dimensions.
AFTERWARP_API void ImageAtlasMakeRegions(struct ImageAtlas_t* atlas, Point const* patternSize,
  Point const* visibleSize, int32_t patternCount);

/// Removes all existing textures.
AFTERWARP_API void ImageAtlasClearTextures(struct ImageAtlas_t* atlas);

/// Removes texture with the given index.
AFTERWARP_API void ImageAtlasRemoveTexture(struct ImageAtlas_t* atlas, int32_t textureIndex);

/// Attempts to create and initialize a texture with the given parameters, which is then added to the list.
/// In case of failure, -1 is returned.
AFTERWARP_API int32_t ImageAtlasCreateTexture(struct ImageAtlas_t* atlas, Point const* size,
  PixelFormat format, TextureAttributes attributes);

/// Finds a suitable location to accomodate the given rectangle in existing available space, adds the
/// appropriate region to the list and returns its index. If no space is available, -1 is returned.
AFTERWARP_API int32_t ImageAtlasPackRegion(struct ImageAtlas_t* atlas, Point const* size, int32_t padding);

/// Finds a suitable location to accomodate the given surface in existing available space, adds the
/// appropriate region to the list and copies the contents of surface to the appropriate texture,
/// returning the final region index. If no space is available or copying fails, -1 is returned.
AFTERWARP_API int32_t ImageAtlasPackSurface(struct ImageAtlas_t* atlas, struct Surface_t* surface,
  Rect const* sourceRect, int32_t padding);

// TextRenderer functions.

/// Creates new instance of text renderer.
AFTERWARP_API struct TextRenderer_t* TextRendererCreate(struct Canvas_t* canvas, Point const* textureSize,
  PixelFormat pixelFormat, LibraryBool mipMapping);

/// Releases given instance of text renderer.
AFTERWARP_API void TextRendererDestroy(struct TextRenderer_t* textRenderer);

/// Returns canvas class associated with the text renderer.
AFTERWARP_API struct Canvas_t* TextRendererGetCanvas(struct TextRenderer_t* textRenderer);

/// Specifies new font settings for the text renderer.
AFTERWARP_API LibraryBool TextRendererSetFontParameters(struct TextRenderer_t* textRenderer,
  FontParameters const* parameters);

/// Retrieves current font settings from the text renderer.
AFTERWARP_API LibraryBool TextRendererGetFontParameters(struct TextRenderer_t* textRenderer,
  FontParameters* parameters);

/// Returns the logical dimensions that the given text will occupy when rendered.
AFTERWARP_API void TextRendererExtent(struct TextRenderer_t* textRenderer, char const* text,
  PointF* dimensions, TextRenderModifiers const* modifiers);

/// Calculates the actual rectangle in pixels that the given text will occupy when rendered.
AFTERWARP_API void TextRendererExtentByPixels(struct TextRenderer_t* textRenderer, char const* text,
  RectF* rect, TextRenderModifiers const* modifiers);

/// Provides information regarding individual character position and sizes for the given text string when
/// rendered. This can be useful for components such as text edit box, for highlighting and selecting
/// different characters. The actual width and height of the text is, optionally, provided as well.
/// Returns actual number of elements returned. Calling this function with \c rects set to NULL would
/// calculate how many elements need to be allocated.
AFTERWARP_API int32_t TextRendererRects(struct TextRenderer_t* textRenderer, PointF* extent,
  _Out_opt_ TextEntryRect rects[], char const* text, TextRenderModifiers const* modifiers);

/// Draws text at the given position.
AFTERWARP_API void TextRendererDraw(struct TextRenderer_t* textRenderer, PointF const* position,
  char const* text, ColorPair const* colors, float alpha, TextRenderModifiers const* modifiers);

/// Draws text at the given position with specific alignment.
AFTERWARP_API void TextRendererDrawAligned(struct TextRenderer_t* textRenderer, PointF const* position,
  char const* text, ColorPair const* colors, TextAlignment horizAlign, TextAlignment vertAlign, float alpha,
  LibraryBool alignToPixels, TextRenderModifiers const* modifiers);

/// Draws text centered around the specified position.
AFTERWARP_API void TextRendererDrawCentered(struct TextRenderer_t* textRenderer, PointF const* position,
  char const* text, ColorPair const* colors, float alpha, LibraryBool alignToPixels,
  TextRenderModifiers const* modifiers);

/// Draws text at the given position with specific alignment by actual visible pixels.
AFTERWARP_API void TextRendererDrawAlignedByPixels(struct TextRenderer_t* textRenderer,
  PointF const* position, char const* text, ColorPair const* colors, TextAlignment horizAlign,
  TextAlignment vertAlign, float alpha, LibraryBool alignToPixels, TextRenderModifiers const* modifiers);

/// Draws text centered around the specified position by actual visible pixels.
AFTERWARP_API void TextRendererDrawCenteredByPixels(struct TextRenderer_t* textRenderer,
  PointF const* position, char const* text, ColorPair const* colors, float alpha, LibraryBool alignToPixels,
  TextRenderModifiers const* modifiers);

// TextModeller functions.

/// Creates new instance of vector-based text rendering module.
AFTERWARP_API struct TextModeller_t* TextModellerCreate(struct Device_t* device);

/// Releases an existing instance of vector-based text rendering module.
AFTERWARP_API void TextModellerDestroy(struct TextModeller_t* textModeller);

/// Returns graphics device associated with the text rendering module.
AFTERWARP_API struct Device_t* TextModellerGetDevice(struct TextModeller_t* textModeller);

/// Searches for an existing font provider with the given parameters and if such is not found, creates a
/// new one. Returns the appropriate font provider or NULL if provider could not be created.
AFTERWARP_API UntypedHandle TextModellerSetFontParameters(struct TextModeller_t* textModeller,
  FontParameters const* parameters);

/// Returns currently associated font provider.
AFTERWARP_API UntypedHandle TextModellerGetFontProvider(struct TextModeller_t* textModeller);

/// Changes currently associated font provider. The parameter must match one of the results returned
/// by \c TextModellerSetFontParameters function.
AFTERWARP_API void TextModellerSetFontProvider(struct TextModeller_t* textModeller, UntypedHandle provider);

/// Returns the logical dimensions that the given text will occupy when rendered.
AFTERWARP_API void TextModellerExtent(struct TextModeller_t* textModeller, char const* text, PointF* extent,
  TextRenderModifiers const* modifiers);

/// Calculates a physical shape area that a given text occupies when rendered at zero position.
AFTERWARP_API void TextModellerExtentByShape(struct TextModeller_t* textModeller, char const* text,
  RectF* rect, TextRenderModifiers const* modifiers);

/// Provides information regarding individual character position and sizes for the given text string when
/// rendered. This can be useful for components such as text edit box, for highlighting and selecting
/// different characters. Returns the actual width and height of the text.
AFTERWARP_API int32_t TextModellerRects(struct TextModeller_t* textModeller, PointF* extent,
  _Out_opt_ TextEntryRect rects[], char const* text, TextRenderModifiers const* modifiers);

/// Draws 2D text at the given position with specific alignment directly to canvas.
AFTERWARP_API LibraryBool TextModellerDrawToCanvas(struct TextModeller_t* textModeller,
  struct Canvas_t* canvas, PointF const* position, char const* text, ColorPair const* colors,
  TextAlignment alignHoriz, TextAlignment alignVert, LibraryBool alignByShape,
  TextRenderModifiers const* modifiers, BlendingEffect effect);

/// Draws 2D text at the given position with specific alignment to a canvas buffer.
AFTERWARP_API LibraryBool TextModellerDrawToCanvasBuffer(struct TextModeller_t* textModeller,
  struct CanvasBuffer_t* buffer, PointF const* position, char const* text, ColorPair const* colors,
  TextAlignment alignHoriz, TextAlignment alignVert, LibraryBool alignByShape,
  TextRenderModifiers const* modifiers);

/// Draws a curved 2D text at the given position with specific alignment directly to canvas.
/// Note: if angle is "NaN", then the text is centered vertically according to the curvature; that is,
/// if the radius would converge to infinity, the text would converge to look like if it wasn't curved.
AFTERWARP_API LibraryBool TextModellerDrawCurvedToCanvas(struct TextModeller_t* textModeller,
  struct Canvas_t* canvas, PointF const* position, char const* text, float radius, float angle,
  ColorPair const* colors, TextRenderModifiers const* modifiers, BlendingEffect effect);

/// Draws a curved 2D text at the given position with specific alignment to a canvas buffer.
/// Note: if angle is "NaN", then the text is centered vertically according to the curvature; that is,
/// if the radius would converge to infinity, the text would converge to look like if it wasn't curved.
AFTERWARP_API LibraryBool TextModellerDrawCurvedToCanvasBuffer(struct TextModeller_t* textModeller,
  struct CanvasBuffer_t* buffer, PointF const* position, char const* text, float radius, float angle,
  ColorPair const* colors, TextRenderModifiers const* modifiers);

/// Renders a volumetric 3D text at the given position, orientation and alignment. The text is oriented in
/// XZ plane with front side oriented towards positive Y axis.
AFTERWARP_API LibraryBool TextModellerDraw(struct TextModeller_t* textModeller, Vector const* position,
  char const* text, float depth, ColorPair const* colors, TextAlignment alignHoriz, TextAlignment alignVert,
  TextAlignment alignDepth, LibraryBool alignByShape, TextRenderModifiers const* modifiers);

/// Renders a curved volumetric 3D text at the given position, orientation and alignment. The text is
/// oriented in XZ plane with front side oriented towards positive Y axis, and the rotation is performed
/// around Y axis. Note: if angle is "NaN", then the text is centered vertically according to the curvature;
/// that is, if the radius would converge to infinity, the text would converge to look like if it wasn't
/// curved.
AFTERWARP_API LibraryBool TextModellerDrawCurved(struct TextModeller_t* textModeller,
  Vector const* position, char const* text, float radius, float angle, float depth, ColorPair const* colors,
  TextAlignment alignDepth, TextRenderModifiers const* modifiers);

/// Renders a curved volumetric 3D text at the given position, orientation and alignment. The text is
/// oriented in XZ plane with front side oriented towards positive Y axis, and the rotation is performed
/// around Z axis. Note: if angle is "NaN", then the text is centered vertically according to the curvature;
/// that is, if the radius would converge to infinity, the text would converge to look like if it wasn't
/// curved.
AFTERWARP_API LibraryBool TextModellerDrawDepthCurved(struct TextModeller_t* textModeller,
  Vector const* position, char const* text, float radius, float angle, float depth, ColorPair const* colors,
  TextRenderModifiers const* modifiers);

/// Clears GPU buffers for rendering 3D text.
AFTERWARP_API void TextModellerClear(struct TextModeller_t* textModeller);

/// Prepares and fills GPU buffers with an existing 3D text rendering data.
AFTERWARP_API LibraryBool TextModellerPrepare(struct TextModeller_t* textModeller);

/// Issues draw call with existing GPU buffers attached.
AFTERWARP_API LibraryBool TextModellerRender(struct TextModeller_t* textModeller, struct Program_t* program,
  uint32_t channel);

/// Copies the contents of existing 3D buffers into a mesh buffer.
AFTERWARP_API LibraryBool TextModellerCopyToMeshBuffer(struct TextModeller_t* textModeller,
  struct MeshBuffer_t* meshBuffer);

/// Releases existing resources, character records and buffers.
AFTERWARP_API void TextModellerReset(struct TextModeller_t* textModeller);

/// Returns current 3D transformation matrix.
AFTERWARP_API void TextModellerGetTransform(struct TextModeller_t* textModeller, Matrix* transform);

/// Changes current 3D transformation matrix.
AFTERWARP_API void TextModellerSetTransform(struct TextModeller_t* textModeller, Matrix const* transform);

// Grapher functions.

/// Creates new 3D plotting grapher.
AFTERWARP_API struct Grapher_t* GrapherCreate(struct Device_t* device);

/// Releases given instance of 3D plotting grapher.
AFTERWARP_API void GrapherDestroy(struct Grapher_t* grapher);

/// Returns device associated with the given grapher module.
AFTERWARP_API struct Device_t* GrapherGetDevice(struct Grapher_t* grapher);

/// Prepares grapher for rendering.
AFTERWARP_API LibraryBool GrapherBegin(struct Grapher_t* grapher);

/// Finishes grapher rendering.
AFTERWARP_API void GrapherEnd(struct Grapher_t* grapher);

/// Draws points at their given vertices with their respective sizes ("w" component of each vertex),
/// colors, angles and the appropriate shape in 3D space.
AFTERWARP_API void GrapherPoints(struct Grapher_t* grapher, Vector4 const vertices[], Color const colors[],
  float const angles[], int32_t elementCount, PointShape shape);

/// Draws lines at their given vertices, thicknesses ("w" component of each vertex), colors and indices.
AFTERWARP_API void GrapherLines(struct Grapher_t* grapher, Vector4 const vertices[], Color const colors[],
  int32_t const indices[], int32_t vertexCount, int32_t indexCount, LineCaps caps);

/// Draws a single point with the given parameters.
AFTERWARP_API void GrapherPoint(struct Grapher_t* grapher, Vector const* position, Color color, float size,
  PointShape shape, float angle);

/// Draws a single line with the given parameters.
AFTERWARP_API void GrapherLine(struct Grapher_t* grapher, Vector const* position1, Vector const* position2,
  Color color1, Color color2, float thickness1, float thickness2, LineCaps caps);

/// Draws an arrow from origin to destination and the given parameters.
/// \c targetSize is the rendering surface size (required for proper arrow angle calculation).
AFTERWARP_API void GrapherArrow(struct Grapher_t* grapher, PointF const* targetSize, Vector const* origin,
  Vector const* destination, Color color, float thickness, float size, LineCaps caps);

/// Draws lines around a bounding box for the given volume matrix.
AFTERWARP_API void GrapherBoundingBox(struct Grapher_t* grapher, Matrix const* volume, Color color,
  float thickness, float length, LineCaps caps);

/// Draws a line of dots with the given parameters.
AFTERWARP_API void GrapherDottedLine(struct Grapher_t* grapher, Vector const* position1,
  Vector const* position2, Color color1, Color color2, float thickness1, float thickness2, float sparsity,
  PointShape shape, float angle);

/// Flushes grapher cache and draws any pending primitives on the rendering surface. This can be useful to
/// make sure that nothing remains in graph cache before changing any device states.
AFTERWARP_API void GrapherFlush(struct Grapher_t* grapher);

/// Resets grapher internal resources and releases any non-critical memory buffers. This can reduce overall
/// memory consumption, when switching from one complex visual scene to another, to allow graph to "adapt"
/// to a new scene from a fresh start.
AFTERWARP_API void GrapherReset(struct Grapher_t* grapher);

/// Returns currently set 3D transformation (world/view/projection) matrix.
AFTERWARP_API void GrapherGetTransform(struct Grapher_t* grapher, Matrix* transform);

/// Changes 3D transformation (world/view/projection) matrix.
AFTERWARP_API void GrapherSetTransform(struct Grapher_t* grapher, Matrix const* transform);

/// Returns number of batches that were sent to rendering pipeline. Drawing each individual batch involves
/// some overhead, which is implementation-specific. If this parameter happens to be considerably high at
/// some point, the rendering code should be revised for better grouping of plotting primitives.
AFTERWARP_API int32_t GrapherGetBatchCount(struct Grapher_t* grapher);

// MeshModel functions.

/// Creates a new instance of 3D mesh model.
AFTERWARP_API struct MeshModel_t* MeshModelCreate(struct Device_t* device, int32_t vertexCount,
  uint32_t vertexElementPitch, int32_t indexCount, uint32_t channel, void const* initialVertexData,
  void const* initialIndexData);

/// Releases given instance of 3D mesh model.
AFTERWARP_API void MeshModelDestroy(struct MeshModel_t* meshModel);

/// Tests whether the model can actually be rendered. For that, it must contain at least a non-empty
/// vertex buffer. Non-renderable mesh is basically a "dummy" that serves as a placeholder.
AFTERWARP_API LibraryBool MeshModelRenderable(struct MeshModel_t* meshModel);

/// Releases vertex and/or index buffers, setting number of vertices and indices to zero.
/// This basically turns an existing model into a "dummy" or a placeholder.
AFTERWARP_API void MeshModelDismantle(struct MeshModel_t* meshModel);

/// Takes away the internal contents from another 3D mesh model container without doing any copying.
AFTERWARP_API void MeshModelTakeAway(struct MeshModel_t* meshModel, struct MeshModel_t* meshModelAnother);

/// Returns total number of vertices stored in the model.
AFTERWARP_API int32_t MeshModelGetVertexCount(struct MeshModel_t* meshModel);

/// Returns total number of indices stored in the model.
AFTERWARP_API int32_t MeshModelGetIndexCount(struct MeshModel_t* meshModel);

/// Returns channel associated with vertex buffer format.
AFTERWARP_API uint32_t MeshModelGetChannel(struct MeshModel_t* meshModel);

/// Returns pointer to integrated vertex buffer.
AFTERWARP_API struct Buffer_t* MeshModelGetVertexBuffer(struct MeshModel_t* meshModel);

/// Returns pointer to integrated index buffer.
AFTERWARP_API struct Buffer_t* MeshModelGetIndexBuffer(struct MeshModel_t* meshModel);

/// Renders the mesh model with the given program.
AFTERWARP_API LibraryBool MeshModelDraw(struct MeshModel_t* meshModel, struct Program_t* program,
  PrimitiveTopology topology, int32_t elementCount, int32_t firstIndex, int32_t baseVertex,
  LibraryBool postUnbind);

/// Renders multiple instances of the mesh model with a given program.
AFTERWARP_API LibraryBool MeshModelDrawInstances(struct MeshModel_t* meshModel, struct Program_t* program,
  int32_t instanceCount, PrimitiveTopology topology, int32_t elementCount, int32_t firstIndex,
  int32_t baseVertex, LibraryBool postUnbind);

// MeshMetaTag functions.

/// Returns mesh meta tag's parent container.
AFTERWARP_API struct MeshMetaTags_t* MeshMetaTagGetParent(struct MeshMetaTag_t* tag);

/// Returns name of the tag. The pointed value of \c nameLength defines the maximum number of
/// characters, including null-terminating character, that can be copied. The actual string length is stored
/// in \c nameLength.
AFTERWARP_API void MeshMetaTagGetName(struct MeshMetaTag_t* tag, char* name, _Inout_ int32_t* nameLength);

/// Returns type of the tag.
AFTERWARP_API uint8_t MeshMetaTagGetType(struct MeshMetaTag_t* tag);

/// Calculates and returns boundaries for all existing tag's portions, if such exist.
AFTERWARP_API void MeshMetaTagGetBounds(struct MeshMetaTag_t* tag, Vector* boundsMin, Vector* boundsMax);

/// Returns number of existing portions associated with the tag.
AFTERWARP_API int32_t MeshMetaTagGetPortionCount(struct MeshMetaTag_t* tag);

/// Returns a portion that corresponds to the tag with a given index.
AFTERWARP_API LibraryBool MeshMetaTagPortionGet(struct MeshMetaTag_t* tag, MeshMetaTagPortion* portion,
  int32_t index);

/// Adds a new portion to the tag.
AFTERWARP_API LibraryBool MeshMetaTagPortionAdd(struct MeshMetaTag_t* tag,
  MeshMetaTagPortion const* portion);

/// Erases a portion with the given index.
AFTERWARP_API void MeshMetaTagPortionErase(struct MeshMetaTag_t* tag, int32_t index);

/// Removes all existing portions.
AFTERWARP_API void MeshMetaTagPortionsClear(struct MeshMetaTag_t* tag);

/// Removes any existing portions and then copies them from an existing tag.
AFTERWARP_API LibraryBool MeshMetaTagPortionsCopy(struct MeshMetaTag_t* tag, struct MeshMetaTag_t* source);

// MeshMetaTags functions.

/// Creates a new instance of 3D mesh tag container.
AFTERWARP_API struct MeshMetaTags_t* MeshMetaTagsCreate(void);

/// Releases the given 3D mesh tag container instance.
AFTERWARP_API void MeshMetaTagsDestroy(struct MeshMetaTags_t* tags);

/// Returns number of existing tags.
AFTERWARP_API int32_t MeshMetaTagsCount(struct MeshMetaTags_t* tags);

/// Returns a particular tag with the given index.
AFTERWARP_API struct MeshMetaTag_t* MeshMetaTagsGetByIndex(struct MeshMetaTags_t* tags, int32_t index);

/// Returns a particular tag with the given name (case-sensitive) and type.
AFTERWARP_API struct MeshMetaTag_t* MeshMetaTagsGetByName(struct MeshMetaTags_t* tags, char const* name,
  uint8_t type);

/// Creates a new tag with the given name (case-sensitive) and type.
AFTERWARP_API struct MeshMetaTag_t* MeshMetaTagsAdd(struct MeshMetaTags_t* tags, char const* name,
  uint8_t type);

/// Removes an existing tag from container list.
AFTERWARP_API void MeshMetaTagsErase(struct MeshMetaTags_t* tags, int32_t index);

/// Removes all existing tags from container list.
AFTERWARP_API void MeshMetaTagsClear(struct MeshMetaTags_t* tags);

/// Copies tags from another container.
AFTERWARP_API LibraryBool MeshMetaTagsCopy(struct MeshMetaTags_t* tags, struct MeshMetaTags_t* tagsAnother);

/// Takes away the internal contents from another tags container without doing any copying.
AFTERWARP_API void MeshMetaTagsTakeAway(struct MeshMetaTags_t* tags, struct MeshMetaTags_t* tagsAnother);

// MeshBuffer functions.

/// Creates a new instance of 3D mesh buffer.
AFTERWARP_API struct MeshBuffer_t* MeshBufferCreate(void);

/// Releases given instance of 3D mesh buffer.
AFTERWARP_API void MeshBufferDestroy(struct MeshBuffer_t* meshBuffer);

/// Returns pointer to vertices stored in 3D mesh buffer.
AFTERWARP_API MeshBufferEntry* MeshBufferGetVertices(struct MeshBuffer_t* meshBuffer);

/// Returns total number of vertices in 3D mesh buffer.
AFTERWARP_API int32_t MeshBufferGetVertexCount(struct MeshBuffer_t* meshBuffer);

/// Resizes 3D mesh buffer to accomodate new number of vertices.
AFTERWARP_API LibraryBool MeshBufferSetVertexCount(struct MeshBuffer_t* meshBuffer, int32_t vertexCount);

/// Returns pointer to indices stored in the 3D mesh buffer.
AFTERWARP_API int32_t* MeshBufferGetIndices(struct MeshBuffer_t* meshBuffer);

/// Returns total number of indices in 3D mesh buffer.
AFTERWARP_API int32_t MeshBufferGetIndexCount(struct MeshBuffer_t* meshBuffer);

/// Resizes 3D mesh buffer to accomodate new number of indices.
AFTERWARP_API LibraryBool MeshBufferSetIndexCount(struct MeshBuffer_t* meshBuffer, int32_t indexCount);

/// Creates new instance of 3D mesh model with the given vertex elements and actual data from this buffer.
AFTERWARP_API struct MeshModel_t* MeshBufferCreateModel(struct MeshBuffer_t* meshBuffer,
  struct Device_t* device, VertexElement const vertexElements[], int32_t vertexElementCount,
  int32_t firstVertex, int32_t vertexCount, int32_t firstIndex, int32_t indexCount, uint32_t channel);

/// Creates a 3D superellipse with the given parameters. Longitude's initial and ending angles are specified
/// in [0, 2 * PI] ranges, whereas latitude's initial and ending angles are specified in a different range
/// of [-PI / 2, PI / 2].
AFTERWARP_API LibraryBool MeshBufferSuperEllipse(struct MeshBuffer_t* meshBuffer, int32_t longitudeSections,
  int32_t latitudeSections, Vector const* origin, Vector const* radius, float initLongitudeAngle,
  float endLongitudeAngle, float longitudeShape, float initLatitudeAngle, float endLatitudeAngle,
  float latitudeShape, PointF const* initTexCoord, PointF const* endTexCoord, FloatColor const* color,
  LibraryBool indicesClockwise);

/// Creates a 3D geosphere with the given parameters.
AFTERWARP_API LibraryBool MeshBufferGeosphere(struct MeshBuffer_t* meshBuffer, int32_t subdivisions,
  FloatColor const* color, LibraryBool flatNormals, LibraryBool indicesClockwise);

/// Creates a cylinder with the given parameters. Axis vectors define both orientation and size. Initial
/// and ending angles are specified in [0, 2 * PI] range.
AFTERWARP_API LibraryBool MeshBufferCylinder(struct MeshBuffer_t* meshBuffer, int32_t radialSections,
  int32_t heightSections, Vector const* origin, Vector const* horizAxis, Vector const* vertAxis,
  Vector const* heightAxis, float initAngle, float endAngle, float shape, PointF const* initTexCoord,
  PointF const* endTexCoord, float bendAngle, float lateralAngle, FloatColor const* color,
  LibraryBool indicesClockwise);

/// Creates a simplistic cone with the given parameters in XZ plane with its base at origin.
AFTERWARP_API LibraryBool MeshBufferConeSimple(struct MeshBuffer_t* meshBuffer, int32_t sections,
  Vector const* origin, float radius, float height, FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a disc with the given parameters. Axis vectors define both orientation and size. Initial and
/// ending angles are specified in [0, 2 * PI] range. \c initRadius defines initial radius in proportion
/// to overall disc size.
AFTERWARP_API LibraryBool MeshBufferDisc(struct MeshBuffer_t* meshBuffer, int32_t radialSections,
  int32_t innerSections, Vector const* origin, Vector const* horizAxis, Vector const* vertAxis,
  Vector const* normal, float initAngle, float endAngle, float shape, float initRadius,
  PointF const* initTexCoord, PointF const* endTexCoord, float lateralAngle, FloatColor const* color,
  LibraryBool indicesClockwise);

/// Creates a 3D plane with the given parameters. Axis vectors define both orientation and size.
AFTERWARP_API LibraryBool MeshBufferPlane(struct MeshBuffer_t* meshBuffer, int32_t horizSections,
  int32_t vertSections, Vector const* origin, Vector const* horizAxis, Vector const* vertAxis,
  Vector const* normal, PointF const* initTexCoord, PointF const* endTexCoord, FloatColor const* color,
  LibraryBool indicesClockwise);

/// Creates a 3D cube with the given parameters. Axis vectors define both orientation and size.
AFTERWARP_API LibraryBool MeshBufferCube(struct MeshBuffer_t* meshBuffer, int32_t horizSections,
  int32_t vertSections, int32_t depthSections, Vector const* origin, Vector const* horizAxis,
  Vector const* vertAxis, Vector const* depthAxis, PointF const* initTexCoord, PointF const* endTexCoord,
  FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a 3D cube with minimal number of vertices and indices. Texture coordinates, normals and tangents
/// are not generated.
AFTERWARP_API LibraryBool MeshBufferCubeMinimal(struct MeshBuffer_t* meshBuffer, Vector const* origin,
  Vector const* size, FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a 3D cube with round corners.
AFTERWARP_API LibraryBool MeshBufferCubeRound(struct MeshBuffer_t* meshBuffer, Vector const* origin,
  Vector const* size, float roundness, FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a 3D torus with the given parameters. Axis vectors define both orientation and size. Initial and
/// ending angles for both inner and outer rings are specified in [0, 2 * PI] range.
AFTERWARP_API LibraryBool MeshBufferTorus(struct MeshBuffer_t* meshBuffer, int32_t outerSections,
  int32_t innerSections, Vector const* origin, Vector const* horizAxis, Vector const* vertAxis,
  float initOuterAngle, float endOuterAngle, float outerShape, float initInnerAngle, float endInnerAngle,
  float innerShape, PointF const* innerRadius, PointF const* initTexCoord, PointF const* endTexCoord,
  float lateralAngle, FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a 3D p-q torus knot with the given parameters. Initial and ending angles for both inner and
/// outer rings are specified in [0, 2 * PI] range.
AFTERWARP_API LibraryBool MeshBufferTorusKnot(struct MeshBuffer_t* meshBuffer, int32_t outerSections,
  int32_t innerSections, Vector const* origin, int32_t p, int32_t q, float initOuterAngle,
  float endOuterAngle, float outerRadius, float initInnerAngle, float endInnerAngle, float innerShape,
  PointF const* innerRadius, PointF const* initTexCoord, PointF const* endTexCoord, float lateralAngle,
  FloatColor const* color, LibraryBool indicesClockwise);

/// Creates a 3D supertoroid located in XY plane with the given parameters. Initial and ending angles for
/// both inner and outer rings are specified in [0, 2 * PI] range.
AFTERWARP_API LibraryBool MeshBufferSupertoroid(struct MeshBuffer_t* meshBuffer, int32_t outerSections,
  int32_t innerSections, Vector const* origin, float initOuterAngle, float endOuterAngle, float outerRadius,
  float outerShape, float initInnerAngle, float endInnerAngle, float innerRadius, float innerShape,
  PointF const* initTexCoord, PointF const* endTexCoord, FloatColor const* color,
  LibraryBool indicesClockwise);

/// Creates a 3D volume of a view frustum from the given view/projection matrix.
AFTERWARP_API LibraryBool MeshBufferFrustumVolume(struct MeshBuffer_t* meshBuffer,
  Matrix const* viewProjectionInverse, LibraryBool depthClipNegative);

/// Creates an extruded mesh around the given path. The mesh is colored with a gradient of four colors.
/// That is, "colors" parameter is an array of four colors each corresponding to top/left, top/right,
/// bottom/right and bottom/left corners.
AFTERWARP_API LibraryBool MeshBufferExtrusion(struct MeshBuffer_t* meshBuffer, PathElement const path[],
  int32_t pathLength, float depth, PointF const* texCoords, FloatColor const colors[], LibraryBool quality);

/// Applies current transformation to the vertices.
AFTERWARP_API void MeshBufferTransformVertices(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount);

/// Recalculates mesh normals for the given range of indices by using normals of triangles.
/// This rebuilds vertex and index lists entirely.
AFTERWARP_API LibraryBool MeshBufferCalculateFlatNormals(struct MeshBuffer_t* meshBuffer, float epsilon);

/// Recalculates mesh normals for the given range of indices by calculating face normals first and then
/// averaging the resulting values to face vertices.
AFTERWARP_API void MeshBufferCalculateNormals(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount, int32_t firstIndex, int32_t indexCount);

/// Recalculates mesh normals for the given range of indices. Vertices that have their positions almost the
/// same (depends on "weldEpsilon") will be considered duplicated and thus will receive weighted normals
/// from neighbor faces as if it would be the same shared vertex.
AFTERWARP_API void MeshBufferCalculateNormalsWeld(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount, int32_t firstIndex, int32_t indexCount, float weldEpsilon);

/// Invert the normals for vertices in the given range. If vertex count is not specified, then remaining
/// vertices starting at the given vertex and up to the end of the list are processed.
AFTERWARP_API void MeshBufferInvertNormals(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount);

/// Inverts order of indices (e.g. from clockwise to counter-clockwise and vice-versa).
AFTERWARP_API void MeshBufferInvertIndexOrder(struct MeshBuffer_t* meshBuffer, int32_t firstIndex,
  int32_t indexCount);

/// Calculates minimum and maximum vertex coordinate boundaries in the given range of mesh.
AFTERWARP_API void MeshBufferCalculateBounds(struct MeshBuffer_t* meshBuffer, Vector* vertexMin,
  Vector* vertexMax, int32_t firstVertex, int32_t vertexCount);

/// Calculates coordinate boundaries and centralizes the vertices in the given range of mesh.
AFTERWARP_API void MeshBufferCentralize(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount);

/// Processes given range of indices, marking vertices that are used and then eliminating vertices that
/// were left unused, updating the entire array of indices.
AFTERWARP_API void MeshBufferEliminateUnusedVertices(struct MeshBuffer_t* meshBuffer, int32_t firstVertex,
  int32_t vertexCount);

/// Joins vertices that have duplicate positions, averaging their normals, tangents and colors.
/// This has complexity of O(n^2), where n is number of vertices to process.
AFTERWARP_API LibraryBool MeshBufferJoinDuplicateVertices(struct MeshBuffer_t* meshBuffer,
  int32_t firstVertex, int32_t vertexCount, float treshold);

/// Includes vertices and indices from source mesh buffer into the current one.
AFTERWARP_API LibraryBool MeshBufferCombine(struct MeshBuffer_t* meshBuffer,
  struct MeshBuffer_t* meshBufferSource, int32_t firstVertex, int32_t vertexCount, int32_t firstIndex,
  int32_t indexCount);

/// Removes all vertices and indices in the mesh buffer.
AFTERWARP_API void MeshBufferClear(struct MeshBuffer_t* meshBuffer);

/// Sets new transformation matrix that is applied to generated vertices during construction.
AFTERWARP_API void MeshBufferSetTransform(struct MeshBuffer_t* meshBuffer, Matrix const* transform);

/// Returns currently set transformation matrix.
AFTERWARP_API void MeshBufferGetTransform(struct MeshBuffer_t* meshBuffer, Matrix* transform);

/// Transfers mesh vertex elements to an interleaved system buffer with the given format at the specified
/// channel. Returns number of bytes that the resulting data occupies. If \c buffer is \c NULL, this
/// function only calculates how many bytes the data will occupy.
AFTERWARP_API uint32_t MeshBufferTransferVertexElements(struct MeshBuffer_t* meshBuffer, void* buffer,
  VertexElement const vertexElements[], int32_t vertexElementCount, int32_t firstVertex, int32_t vertexCount,
  uint32_t channel, uint32_t semanticIndex);

/// Transfers mesh indices to the specified index buffer. The buffer data type is determined by its pitch.
/// Returns number of bytes that the resulting data occupies. If \c buffer is \c NULL, this function only
/// calculates how many bytes the data will occupy.
AFTERWARP_API uint32_t MeshBufferTransferIndexElements(struct MeshBuffer_t* meshBuffer, void* buffer,
  uint32_t pitch, int32_t firstVertex, int32_t firstIndex, int32_t indexCount);

/// Transfers mesh vertex elements to an interleaved vertex buffer object with the given format at the
/// specified channel and offset.
AFTERWARP_API LibraryBool MeshBufferTransferVertices(struct MeshBuffer_t* meshBuffer,
  struct Buffer_t* buffer, VertexElement const vertexElements[], int32_t vertexElementCount,
  int32_t firstVertex, int32_t vertexCount, uint32_t channel, uint32_t offset, uint32_t semanticIndex);

/// Transfers mesh index elements to an index buffer object with the given format at the specified offset.
AFTERWARP_API LibraryBool MeshBufferTransferIndices(struct MeshBuffer_t* meshBuffer,
  struct Buffer_t* buffer, int32_t firstVertex, int32_t firstIndex, int32_t indexCount, uint32_t offset);

/// Creates and builds a 3D voxel representation for geometry in the mesh buffer. A special care must be
/// taken to define levels, as using high values may exhaust available RAM resources; typical values should
/// be between 3 and 4.
AFTERWARP_API struct MeshVoxel_t* MeshBufferVoxelize(struct MeshBuffer_t* meshBuffer, uint8_t levels,
  LibraryBool colors);

/// Loads natively Wavefront OBJ mesh file format (or a proprietary mesh binary format) from disk to the mesh
/// buffer. Optionally loads materials included with the mesh file and/or meta tags (important boundaries of
/// sub-meshes). In loading fails, optionally provides debug information.
AFTERWARP_API LibraryBool MeshBufferLoadFromFile(struct MeshBuffer_t* meshBuffer,
  char const* fileName, struct SceneMeshMaterials_t* materials, struct MeshMetaTags_t* tags,
  _Inout_ uint32_t* options, MeshLoadSaveFeedback feedback, void* feedbackUser,
  char* debug, _Inout_ int32_t* debugLength);

/// Saves mesh buffer contents to a Wavefront OBJ mesh format natively to file on disk. Materials and tags
/// are optional and will also be saved, if provided. If saving fails, optionally provides debug information.
AFTERWARP_API LibraryBool MeshBufferSaveToFile(struct MeshBuffer_t* meshBuffer,
  char const* fileName, struct SceneMeshMaterials_t* materials, struct MeshMetaTags_t* tags,
  uint32_t options, MeshLoadSaveFeedback feedback, void* feedbackUser,
  char* debug, _Inout_ int32_t* debugLength);

/// Attempts to load the mesh file from disk using Assimp DLL to mesh buffer and calculates its boundaries.
/// Optionally loads mesh meta tags (important boundaries of sub-meshes) and/or provides debug information.
/// If \c normals parameter is \c true, then normals will be optionally generated when such are not present.
AFTERWARP_API LibraryBool MeshBufferLoadFromFileEx(struct MeshBuffer_t* meshBuffer,
  struct MeshMetaTags_t* tags, char const* fileName, Vector* minBounds, Vector* maxBounds,
  LibraryBool normals, char* debug, _Inout_ int32_t* debugLength);

/// Attempts to save the mesh to file on disk using Assimp DLL from an existing mesh buffer.
/// Optionally provides debug information.
AFTERWARP_API LibraryBool MeshBufferSaveToFileEx(struct MeshBuffer_t* meshBuffer, char const* fileName,
  uint32_t const* options, char* debug, _Inout_ int32_t* debugLength);

// GaussianBlur functions.

/// Creates a new instance of gaussian blur module.
AFTERWARP_API struct GaussianBlur_t* GaussianBlurCreate(struct Device_t* device, float sigma,
  int32_t samples, LibraryBool hardwareFiltering);

/// Releases given instance of gaussian blur module.
AFTERWARP_API void GaussianBlurDestroy(struct GaussianBlur_t* gaussianBlur);

/// Returns device associated with the given gaussian blur.
AFTERWARP_API struct Device_t* GaussianBlurGetDevice(struct GaussianBlur_t* gaussianBlur);

/// Returns maximum number of samples supported by a fixed-sample blur, which enables higher performance.
AFTERWARP_API int32_t GaussianBlurGetFixedSamples(struct GaussianBlur_t* gaussianBlur);

/// Returns current number of samples in the kernel.
AFTERWARP_API int32_t GaussianBlurGetSamples(struct GaussianBlur_t* gaussianBlur);

/// Sets new number of samples in the kernel. Fixed-size sampling kernel requires this number to be odd,
/// between 5 and 17 (manual filtering), or 19 (hardware filtering). For variable-size kernel, any number
/// of samples higher than the maximum number of fixed samples would work; higher values would involve
/// additional performance cost.
AFTERWARP_API void GaussianBlurSetSamples(struct GaussianBlur_t* gaussianBlur, int32_t samples);

/// Returns current value of sigma.
AFTERWARP_API float GaussianBlurGetSigma(struct GaussianBlur_t* gaussianBlur);

/// Sets new value of sigma. The value must be equal or higher than zero.
AFTERWARP_API void GaussianBlurSetSigma(struct GaussianBlur_t* gaussianBlur, float sigma);

/// Returns chroma offset for color adjustment.
AFTERWARP_API float GaussianBlurGetChroma(struct GaussianBlur_t* gaussianBlur);

/// Changes chroma offset in range of [0, inf) for color adjustment (1 means no adjustment is needed).
AFTERWARP_API void GaussianBlurSetChroma(struct GaussianBlur_t* gaussianBlur, float chroma);

/// Indicates whether hardware filtering is used to accelerate the blur.
AFTERWARP_API LibraryBool GaussianBlurGetHardwareFiltering(struct GaussianBlur_t* gaussianBlur);

/// Adjusts whether hardware filtering should be used to accelerate the blur.
AFTERWARP_API void GaussianBlurSetHardwareFiltering(struct GaussianBlur_t* gaussianBlur,
  LibraryBool hardwareFiltering);

/// Applies blur through use of an an intermediate texture. Both destination and intermediary textures must
/// have drawable attribute. If source texture has drawable attribute, then it can be passed as destination
/// texture as well.
AFTERWARP_API LibraryBool GaussianBlurUpdate(struct GaussianBlur_t* gaussianBlur,
  struct Texture_t* destination, struct Texture_t* intermediary, struct Texture_t* source);

/// Applies a horizontal blur from source to intermediary texture, then a vertical blur from intermediary
/// to destination texture. Both destination and intermediary textures must have drawable attribute.
/// If source texture has drawable attribute, then it can be passed as destination texture as well.
/// If destination position and/or intermediate rectangle are specified, then only a portion of
/// intermediary texture will be copied to destination at the given offset.
AFTERWARP_API LibraryBool GaussianBlurUpdateAt(struct GaussianBlur_t* gaussianBlur,
  struct Texture_t* destination, struct Texture_t* intermediary, struct Texture_t* source,
  Point const* destPos, Rect const* intermRect);

// KawaseBlur functions.

/// Creates a new instance of kawase blur module.
AFTERWARP_API struct KawaseBlur_t* KawaseBlurCreate(struct Device_t* device);

/// Releases given instance of kawase blur module.
AFTERWARP_API void KawaseBlurDestroy(struct KawaseBlur_t* kawaseBlur);

/// Returns device associated with the given kawase blur.
AFTERWARP_API struct Device_t* KawaseBlurGetDevice(struct KawaseBlur_t* kawaseBlur);

/// Returns number of blur passes (each pass includes two processing steps).
AFTERWARP_API int32_t KawaseBlurGetPasses(struct KawaseBlur_t* kawaseBlur);

/// Updates number of blur passes (each pass includes two processing steps).
AFTERWARP_API void KawaseBlurSetPasses(struct KawaseBlur_t* kawaseBlur, int32_t passes);

/// Returns pixel offset for each individual step.
AFTERWARP_API void KawaseBlurGetOffset(struct KawaseBlur_t* kawaseBlur, PointF* offset);

/// Changes pixel offset for each individual step.
AFTERWARP_API void KawaseBlurSetOffset(struct KawaseBlur_t* kawaseBlur, PointF const* offset);

/// Applies an advancing blur kernel from source to intermediary texture, then from intermediary to
/// destination texture. Both destination and intermediary textures must have drawable attribute.
/// If source texture has drawable attribute, then it can be passed as destination texture as well.
AFTERWARP_API LibraryBool KawaseBlurUpdate(struct KawaseBlur_t* kawaseBlur,
  struct Texture_t* destination, struct Texture_t* intermediary, struct Texture_t* source);

/// Applies blur in a single pass with the given custom offset. This can be used simultaneously when
/// performing downsampling.
AFTERWARP_API LibraryBool KawaseBlurSinglePass(struct KawaseBlur_t* kawaseBlur,
  struct Texture_t* destination, struct Texture_t* source, PointF const* offset);

// ColorDithering functions.

/// Creates a new instance of color dithering module.
AFTERWARP_API struct ColorDithering_t* ColorDitheringCreate(struct Device_t* device);

/// Releases given instance of color dithering module.
AFTERWARP_API void ColorDitheringDestroy(struct ColorDithering_t* colorDithering);

/// Returns device associated with the given module.
AFTERWARP_API struct Device_t* ColorDitheringGetDevice(struct ColorDithering_t* colorDithering);

/// Returns target color quantization format for dithering.
AFTERWARP_API ColorDitheringFormat ColorDitheringGetFormat(struct ColorDithering_t* colorDithering);

/// Updates target color quantization format for dithering.
AFTERWARP_API void ColorDitheringSetFormat(struct ColorDithering_t* colorDithering,
  ColorDitheringFormat format);

/// Performs color dithering of the source texture rendering to destination texture.
AFTERWARP_API LibraryBool ColorDitheringExecuteTo(struct ColorDithering_t* colorDithering,
  struct Texture_t* destination, struct Texture_t* source);

/// Performs color dithering of the source texture rendering a full-screen quad.
AFTERWARP_API LibraryBool ColorDitheringExecute(struct ColorDithering_t* colorDithering,
  struct Texture_t* source);

// SelectionHighlight functions.

/// Creates a new instance of selection highlight module.
AFTERWARP_API struct SelectionHighlight_t* SelectionHighlightCreate(struct Device_t* device,
  Point const* size, PixelFormat depthStencil, int32_t samples, LibraryBool grayscale);

/// Releases given instance of selection highlight module.
AFTERWARP_API void SelectionHighlightDestroy(struct SelectionHighlight_t* selectionHighlight);

/// Returns device associated with the given module.
AFTERWARP_API struct Device_t* SelectionHighlightGetDevice(struct SelectionHighlight_t* selectionHighlight);

/// Updates size of the rendering surfaces.
AFTERWARP_API LibraryBool SelectionHighlightSetSize(struct SelectionHighlight_t* selectionHighlight,
  Point const* size);

/// Returns size of the rendering surfaces.
AFTERWARP_API void SelectionHighlightGetSize(struct SelectionHighlight_t* selectionHighlight, Point* size);

/// Returns pixel format used for depth/stencil buffer.
AFTERWARP_API PixelFormat SelectionHighlightGetDepthStencil(struct SelectionHighlight_t* selectionHighlight);

/// Returns number of samples used for multisampling.
AFTERWARP_API int32_t SelectionHighlightGetSamples(struct SelectionHighlight_t* selectionHighlight);

/// Returns whether the technique is performed in a more optimal, grayscale mode, instead of full color.
AFTERWARP_API LibraryBool SelectionHighlightGetGrayscale(struct SelectionHighlight_t* selectionHighlight);

/// Returns parameters that define the behavior and characteristics of the technique.
AFTERWARP_API void SelectionHighlightGetParameters(struct SelectionHighlight_t* selectionHighlight,
  SelectionHighlightParameters* parameters);

/// Updates parameters that define the behavior and characteristics of the technique.
AFTERWARP_API LibraryBool SelectionHighlightSetParameters(struct SelectionHighlight_t* selectionHighlight,
  SelectionHighlightParameters const* parameters);

/// Clears the primary rendering textures.
AFTERWARP_API LibraryBool SelectionHighlightClear(struct SelectionHighlight_t* selectionHighlight);

/// Begins rendering the primary textures.
AFTERWARP_API LibraryBool SelectionHighlightBegin(struct SelectionHighlight_t* selectionHighlight);

/// Ends rendering to the primary textures.
AFTERWARP_API void SelectionHighlightEnd(struct SelectionHighlight_t* selectionHighlight);

/// Indicates that the rendering is currently performed to the primary textures.
AFTERWARP_API LibraryBool SelectionHighlightRendering(struct SelectionHighlight_t* selectionHighlight);

/// Performs final post-filtering of the textures to produce the highlight selection effect.
AFTERWARP_API LibraryBool SelectionHighlightFilter(struct SelectionHighlight_t* selectionHighlight);

/// Returns texture of the given type.
AFTERWARP_API struct Texture_t* SelectionHighlightGetTexture(struct SelectionHighlight_t* selectionHighlight,
  SelectionHighlightTextureType type);

/// Returns texture coordinates that can be passed to canvas for rendering the highlight.
AFTERWARP_API void SelectionHighlightGetTextureCoordinates(struct SelectionHighlight_t* selectionHighlight,
  Quad* coords);

// SpatialFog functions.

/// Creates a new instance of spatial fog module.
AFTERWARP_API struct SpatialFog_t* SpatialFogCreate(struct Device_t* device);

/// Releases given instance of spatial fog module.
AFTERWARP_API void SpatialFogDestroy(struct SpatialFog_t* spatialFog);

/// Returns device associated with the given module.
AFTERWARP_API struct Device_t* SpatialFogGetDevice(struct SpatialFog_t* spatialFog);

/// Returns parameters that define spatial fog characteristics.
AFTERWARP_API void SpatialFogGetParameters(struct SpatialFog_t* spatialFog, FogParameters* parameters);

/// Changes parameters that define spatial fog characteristics.
AFTERWARP_API LibraryBool SpatialFogSetParameters(struct SpatialFog_t* spatialFog,
  FogParameters const* parameters);

/// Returns view transformation matrix.
AFTERWARP_API void SpatialFogGetView(struct SpatialFog_t* spatialFog, Matrix* view);

/// Updates view transformation matrix.
AFTERWARP_API LibraryBool SpatialFogSetView(struct SpatialFog_t* spatialFog, Matrix const* view);

/// Returns projection transformation matrix.
AFTERWARP_API void SpatialFogGetProjection(struct SpatialFog_t* spatialFog, Matrix* projection);

/// Updates projection transformation matrix.
AFTERWARP_API LibraryBool SpatialFogSetProjection(struct SpatialFog_t* spatialFog, Matrix const* projection);

/// Returns formula used for the fog.
AFTERWARP_API FogFormula SpatialFogGetFormula(struct SpatialFog_t* spatialFog);

/// Changes formula used for the fog.
AFTERWARP_API LibraryBool SpatialFogSetFormula(struct SpatialFog_t* spatialFog, FogFormula formula);

/// Returns distance calculation formula for the fog.
AFTERWARP_API DepthFogDistance SpatialFogGetDepthDistance(struct SpatialFog_t* spatialFog);

/// Changes distance calculation formula for the fog.
AFTERWARP_API LibraryBool SpatialFogSetDepthDistance(struct SpatialFog_t* spatialFog,
  DepthFogDistance depthDistance);

/// Computes fog and applies it to the destination high-dynamic range (HDR) color texture. The module
/// requires an existing linear depths texture (optionally multisampled) to be provided.
AFTERWARP_API LibraryBool SpatialFogExecute(struct SpatialFog_t* spatialFog,
  struct Texture_t* destination, struct Texture_t* linearDepths);

/// Computes fog and applies it to the destination "glassy" composition texture. The module
/// requires an existing linear depths texture (optionally multisampled) to be provided.
AFTERWARP_API LibraryBool SpatialFogExecuteGlassy(struct SpatialFog_t* spatialFog,
  struct Texture_t* destination, struct Texture_t* linearDepths);

// SceneLights functions.

/// Creates a new instance of 3D scene light module.
AFTERWARP_API struct SceneLights_t* SceneLightsCreate(struct Device_t* device);

/// Releases given instance of 3D scene light module.
AFTERWARP_API void SceneLightsDestroy(struct SceneLights_t* sceneLights);

/// Returns device associated with 3D scene light module.
AFTERWARP_API struct Device_t* SceneLightsGetDevice(struct SceneLights_t* sceneLights);

/// Returns total number of light sources.
AFTERWARP_API int32_t SceneLightsGetCount(struct SceneLights_t* sceneLights);

/// Returns pointer to an existing 3D scene light parameters.
AFTERWARP_API SceneLight* SceneLightsGetElement(struct SceneLights_t* sceneLights, int32_t index);

/// Adds a new light with default parameters.
AFTERWARP_API SceneLight* SceneLightsAdd(struct SceneLights_t* sceneLights);

/// Erases light with the given index.
AFTERWARP_API LibraryBool SceneLightsErase(struct SceneLights_t* sceneLights, int32_t index);

/// Removes all existing lights.
AFTERWARP_API void SceneLightsClear(struct SceneLights_t* sceneLights);

/// Returns size of the viewable area.
AFTERWARP_API void SceneLightsGetViewSize(struct SceneLights_t* sceneLights, Point* viewSize);

/// Returns size of the viewable area.
AFTERWARP_API void SceneLightsSetViewSize(struct SceneLights_t* sceneLights, Point const* viewSize);

/// Returns size of individual lighting clusters.
AFTERWARP_API int32_t SceneLightsGetClusterSize(struct SceneLights_t* sceneLights);

/// Changes size of individual lighting clusters.
AFTERWARP_API void SceneLightsSetClusterSize(struct SceneLights_t* sceneLights, int32_t clusterSize);

/// Returns number of cluster slices per viewable depth.
AFTERWARP_API int32_t SceneLightsGetDepthSlices(struct SceneLights_t* sceneLights);

/// Updates number of cluster slices per viewable depth.
AFTERWARP_API void SceneLightsSetDepthSlices(struct SceneLights_t* sceneLights, int32_t depthSlices);

/// Returns mode used for packing culled lights in clusters.
AFTERWARP_API ClustersCullingMode SceneLightsGetCullingMode(struct SceneLights_t* sceneLights);

/// Changes mode used for packing culled lights in clusters.
AFTERWARP_API void SceneLightsSetCullingMode(struct SceneLights_t* sceneLights, ClustersCullingMode mode);

/// Returns number of clusters per width and height of viewable area.
AFTERWARP_API void SceneLightsGetClusters(struct SceneLights_t* sceneLights, Point* clusters);

/// Returns light indices that have been calculated for each of the clusters.
AFTERWARP_API struct Buffer_t* SceneLightsGetIndices(struct SceneLights_t* sceneLights);

/// Calculates cluster frustums, then performs light culling for each of the clusters.
/// This populates an internal GPU buffer containing light indices for each of the clusters.
AFTERWARP_API LibraryBool SceneLightsExecute(struct SceneLights_t* sceneLights, Matrix const* view,
  Matrix const* projection);

/// Renders light culling debug information. A call to \c SceneLightsExecute() must be performed before this.
AFTERWARP_API LibraryBool SceneLightsRenderDebug(struct SceneLights_t* sceneLights, LibraryBool intensity);

// ObjectMaterials functions.

/// Creates a new instance of 3D object materials container.
AFTERWARP_API struct ObjectMaterials_t* ObjectMaterialsCreate(void);

/// Releases given instance of 3D object materials container.
AFTERWARP_API void ObjectMaterialsDestroy(struct ObjectMaterials_t* objectMaterials);

/// Returns total number of materials.
AFTERWARP_API int32_t ObjectMaterialsGetCount(struct ObjectMaterials_t* objectMaterials);

/// Returns pointer to an existing 3D object material parameters.
AFTERWARP_API ObjectMaterial* ObjectMaterialsGetElement(struct ObjectMaterials_t* objectMaterials,
  int32_t index);

/// Adds a new material with default parameters.
AFTERWARP_API ObjectMaterial* ObjectMaterialsAdd(struct ObjectMaterials_t* objectMaterials);

/// Erases material with the given index.
AFTERWARP_API LibraryBool ObjectMaterialsErase(struct ObjectMaterials_t* objectMaterials, int32_t index);

/// Removes all existing materials.
AFTERWARP_API void ObjectMaterialsClear(struct ObjectMaterials_t* objectMaterials);

// TextureCabinet functions.

/// Creates a new instance of collection of drawable textures for performing 3D scene rendering.
AFTERWARP_API struct TextureCabinet_t* TextureCabinetCreate(struct Device_t* device, Point const* size,
  TextureFidelity fidelity, int32_t samples, PixelFormat depthStencil);

/// Releases given instance of drawable textures collection.
AFTERWARP_API void TextureCabinetDestroy(struct TextureCabinet_t* textureCabinet);

/// Returns device associated with the given textures collection.
AFTERWARP_API struct Device_t* TextureCabinetGetDevice(struct TextureCabinet_t* textureCabinet);

/// Returns the size of the integrated textures.
AFTERWARP_API void TextureCabinetGetSize(struct TextureCabinet_t* textureCabinet, Point* size);

/// Updates the size of integrated textures and buffers.
AFTERWARP_API LibraryBool TextureCabinetSetSize(struct TextureCabinet_t* textureCabinet, Point const* size);

/// Returns number of samples used in the textures.
AFTERWARP_API int32_t TextureCabinetGetSamples(struct TextureCabinet_t* textureCabinet);

/// Returns format used for depth/stencil buffers.
AFTERWARP_API PixelFormat TextureCabinetGetDepthStencil(struct TextureCabinet_t* textureCabinet);

/// Returns level of fidelity used for choosing integrated pixel formats.
AFTERWARP_API TextureFidelity TextureCabinetGetFidelity(struct TextureCabinet_t* textureCabinet);

/// Returns rendering attributes of the collection.
AFTERWARP_API TextureCabinetAttributes TextureCabinetGetAttributes(struct TextureCabinet_t* textureCabinet);

// Changes rendering attributes of the collection.
AFTERWARP_API LibraryBool TextureCabinetSetAttributes(struct TextureCabinet_t* textureCabinet,
  TextureCabinetAttributes attributes);

/// Returns texture from the container of the given type.
AFTERWARP_API struct Texture_t* TextureCabinetGetTexture(struct TextureCabinet_t* textureCabinet,
  TextureCabinetType type);

/// Returns final color texture that can contains the scene.
AFTERWARP_API struct Texture_t* TextureCabinetGetFinalTexture(struct TextureCabinet_t* textureCabinet);

/// Clears the content of textures related to the given pass.
/// Note: the given color is used only in main/color pass.
AFTERWARP_API LibraryBool TextureCabinetClear(struct TextureCabinet_t* textureCabinet,
  TextureCabinetPass pass, _In_opt_ FloatColor const* color);

/// Begins rendering the given pass.
AFTERWARP_API LibraryBool TextureCabinetBegin(struct TextureCabinet_t* textureCabinet,
  TextureCabinetPass pass);

/// Ends rendering the pass that was previously started.
AFTERWARP_API void TextureCabinetEnd(struct TextureCabinet_t* textureCabinet);

/// Indicates that one of the passes is currently being rendered.
AFTERWARP_API LibraryBool TextureCabinetRendering(struct TextureCabinet_t* textureCabinet);

/// Performs processing and filtering of the textures according to the filter type. For occlusion,
/// performs depth linearization and computes ambient occlusion. For bloom, downscales the color texture,
/// applies blur to compute glare, combines the effects and then performs HDR tone-mapping.
/// For order-independent transparency (OIT or "glassy") pass, performs compositioning of the textures.
/// This step must be performed outside of \c TextureCabinetBegin() and \c TextureCabinetEnd() block after
/// finishing each corresponding rendering pass but before starting next one. For performance reasons,
/// the filtering should be performed as late as possible after finishing previous pass (e.g. after doing
/// some CPU calculations) to enable GPU to do work in parallel. Note: OIT rendering pass does not require
/// projection matrix.
AFTERWARP_API LibraryBool TextureCabinetFilter(struct TextureCabinet_t* textureCabinet,
  TextureCabinetFilterType filter, Matrix const* projection);

/// Renders a multisample HDR color texture into a final color texture.
AFTERWARP_API LibraryBool TextureCabinetResolve(struct TextureCabinet_t* textureCabinet);

/// Renders the final color texture on the current rendering surface.
AFTERWARP_API LibraryBool TextureCabinetPresent(struct TextureCabinet_t* textureCabinet);

/// Returns tone-mapping and bloom parameters.
AFTERWARP_API void TextureCabinetGetToneMappingBloom(struct TextureCabinet_t* textureCabinet,
  ToneMappingBloom* parameters);

/// Updates tone-mapping and bloom parameters.
AFTERWARP_API void TextureCabinetSetToneMappingBloom(struct TextureCabinet_t* textureCabinet,
  ToneMappingBloom const* parameters);

/// Returns ambient occlusion parameters.
AFTERWARP_API void TextureCabinetGetAmbientOcclusionParameters(struct TextureCabinet_t* textureCabinet,
  AmbientOcclusionParameters* parameters);

/// Updates ambient occlusion parameters.
AFTERWARP_API void TextureCabinetSetAmbientOcclusionParameters(struct TextureCabinet_t* textureCabinet,
  AmbientOcclusionParameters const* parameters);

/// Retrieves metrics when using glassy rendering; five values are returned: hash table size,
/// fragments drawn, fragments written, fragments read, max depth. Note: this should be called as little
/// often as possible (ideally, no more than a couple of times per second) to avoid unnecessary rendering
/// pipeline stalls as the values are read asynchronously from GPU.
AFTERWARP_API LibraryBool TextureCabinetRetrieveGlassyMetrics(struct TextureCabinet_t* textureCabinet,
  uint32_t* values);

// ShadowCaster functions.

/// Returns device associated with the given shadow shadowCaster.
AFTERWARP_API struct Device_t* ShadowCasterGetDevice(struct ShadowCaster_t* shadowCaster);

/// Returns position of the shadow map in parent atlas.
AFTERWARP_API void ShadowCasterGetPosition(struct ShadowCaster_t* shadowCaster, Point* position);

/// Returns size of the shadow map.
AFTERWARP_API void ShadowCasterGetSize(struct ShadowCaster_t* shadowCaster, Point* size);

/// Returns a combined view and projection matrices of the shadow caster.
AFTERWARP_API void ShadowCasterGetViewProjection(struct ShadowCaster_t* shadowCaster,
  Matrix* viewProjection);

/// Updates a combined view and projection matrices of the shadow caster.
AFTERWARP_API void ShadowCasterSetViewProjection(struct ShadowCaster_t* shadowCaster,
  Matrix const* viewProjection);

/// Returns pointer to an owner atlas.
AFTERWARP_API struct ShadowCastingAtlas_t* ShadowCasterGetAtlas(struct ShadowCaster_t* shadowCaster);

/// Clears the integrated textures.
AFTERWARP_API LibraryBool ShadowCasterClear(struct ShadowCaster_t* shadowCaster);

/// Starts rendering to shadow caster's texture to build a shadow map.
AFTERWARP_API LibraryBool ShadowCasterBegin(struct ShadowCaster_t* shadowCaster);

/// Finishes rendering to shadow caster's texture.
AFTERWARP_API void ShadowCasterEnd(struct ShadowCaster_t* shadowCaster);

/// Performs filtering on the shadow map and accomodates it on the atlas.
AFTERWARP_API LibraryBool ShadowCasterFilter(struct ShadowCaster_t* shadowCaster);

/// Indicates whether rendering is taking place.
AFTERWARP_API LibraryBool ShadowCasterRendering(struct ShadowCaster_t* shadowCaster);

/// Returns one of the textures currently used by the shadow caster.
AFTERWARP_API struct Texture_t* ShadowCasterGetTexture(struct ShadowCaster_t* shadowCaster, int32_t index);

// ShadowCastingAtlas functions.

/// Creates a new instance of shadow caster and map management module.
AFTERWARP_API struct ShadowCastingAtlas_t* ShadowCastingAtlasCreate(struct Device_t* device,
  Point const* size, TechniqueShadows technique, int32_t samples, int32_t padding);

/// Releases given instance of shadow caster and map management module.
AFTERWARP_API void ShadowCastingAtlasDestroy(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns device associated with the given textures collection.
AFTERWARP_API struct Device_t* ShadowCastingAtlasGetDevice(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns shadow rendering technique.
AFTERWARP_API TechniqueShadows ShadowCastingAtlasGetTechnique(
  struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns parameters that define how shadows are rendered.
AFTERWARP_API void ShadowCastingAtlasGetParameters(struct ShadowCastingAtlas_t* shadowCastingAtlas,
  ShadowParameters* parameters);

/// Updates shadow rendering parameters.
AFTERWARP_API LibraryBool ShadowCastingAtlasSetParameters(struct ShadowCastingAtlas_t* shadowCastingAtlas,
  ShadowParameters const* parameters);

/// Returns size of the shadow-casting shadowCastingAtlas.
AFTERWARP_API void ShadowCastingAtlasGetSize(struct ShadowCastingAtlas_t* shadowCastingAtlas, Point* size);

/// Returns number of samples used for shadow map multisampling.
AFTERWARP_API int32_t ShadowCastingAtlasGetSamples(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns padding used to accomodate shadow maps.
AFTERWARP_API int32_t ShadowCastingAtlasGetPadding(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns shadow mapping atlas texture containing existing shadow maps.
AFTERWARP_API struct Texture_t* ShadowCastingAtlasGetTexture(
  struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Creates a new shadow caster with the given texture size. Shared parameter determines whether the caster
/// should share its shadow map textures with others to reduce memory footprint. For "progressive"
/// rendering, where more portions are added to shadow map in next frames, the shadow caster must own its
/// shadow map.
AFTERWARP_API struct ShadowCaster_t* ShadowCastingAtlasAdd(struct ShadowCastingAtlas_t* shadowCastingAtlas,
  Point const* size, LibraryBool shared);

/// Removes an existing shadow caster.
AFTERWARP_API void ShadowCastingAtlasErase(struct ShadowCastingAtlas_t* shadowCastingAtlas,
  struct ShadowCaster_t* caster);

/// Removes all existing shadow casters.
AFTERWARP_API void ShadowCastingAtlasClear(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns number of existing shadow casters.
AFTERWARP_API int32_t ShadowCastingAtlasGetCount(struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns shadow caster for the given index.
AFTERWARP_API struct ShadowCaster_t* ShadowCastingAtlasGetCaster(
  struct ShadowCastingAtlas_t* shadowCastingAtlas, int32_t index);

/// Clears the surface of shadow mapping atlas texture using border color to avoid edge artifacts.
/// This is typically required after shadow parameters have been changed.
AFTERWARP_API LibraryBool ShadowCastingAtlasBorderFill(struct ShadowCastingAtlas_t* shadowCastingAtlas);

// Scene functions.

/// Creates a new instance of depths/normals rendering scene.
AFTERWARP_API struct Scene_t* SceneCreateDepthsNormals(struct Device_t* device);

/// Creates a new instance of 3D rendering scene.
AFTERWARP_API struct Scene_t* SceneCreateModeling(struct Device_t* device);

/// Releases an existing scene rendering instance.
AFTERWARP_API void SceneDestroy(struct Scene_t* scene);

/// Returns device associated with the given scene.
AFTERWARP_API struct Device_t* SceneGetDevice(struct Scene_t* scene);

/// Returns number of items in vertex element declaration associated with the given index.
AFTERWARP_API int32_t SceneGetVertexElementCount(struct Scene_t* scene, int32_t index);

/// Returns items in vertex element declaration associated with the given index.
AFTERWARP_API VertexElement const* SceneGetVertexElements(struct Scene_t* scene, int32_t index);

/// Changes vertex element declaration associated with the given index.
AFTERWARP_API LibraryBool SceneSetVertexElements(struct Scene_t* scene, int32_t index,
  VertexElement const vertexElements[], int32_t vertexElementCount);

/// Changes vertex element declaration to match the one of 2D and 3D text rendering module, associated with
/// the given index.
AFTERWARP_API LibraryBool SceneSetVertexElementsFromTextModeller(struct Scene_t* scene, int32_t index);

/// Returns currently active index of vertex elements declaration.
AFTERWARP_API int32_t SceneGetActiveVertexElements(struct Scene_t* scene);

/// Changes currently active index of vertex elements declaration.
AFTERWARP_API LibraryBool SceneSetActiveVertexElements(struct Scene_t* scene, int32_t index);

/// Returns attributes that define the rendering behavior of the scene.
AFTERWARP_API SceneAttributes SceneGetAttributes(struct Scene_t* scene);

/// Updates attributes that define the rendering behavior of the scene.
AFTERWARP_API LibraryBool SceneSetAttributes(struct Scene_t* scene, SceneAttributes attributes);

/// Returns object world matrix.
AFTERWARP_API void SceneGetWorld(struct Scene_t* scene, Matrix* world);

/// Updates object world matrix.
AFTERWARP_API void SceneSetWorld(struct Scene_t* scene, Matrix const* world);

/// Returns view matrix.
AFTERWARP_API void SceneGetView(struct Scene_t* scene, Matrix* view);

/// Updates view matrix.
AFTERWARP_API void SceneSetView(struct Scene_t* scene, Matrix const* view);

/// Returns projection matrix.
AFTERWARP_API void SceneGetProjection(struct Scene_t* scene, Matrix* projection);

/// Updates projection matrix.
AFTERWARP_API void SceneSetProjection(struct Scene_t* scene, Matrix const* projection);

/// Supplies instance information to the pipeline. The maximum number of elements must not exceed the value
/// returned by \c SceneGetInstancesCount() function.
AFTERWARP_API LibraryBool SceneInstances(struct Scene_t* scene, Matrix const transforms[],
  FloatColor const colors[], int32_t count);

/// Returns maximum number of supported instances.
AFTERWARP_API int32_t SceneGetInstancesCount(struct Scene_t* scene);

/// Returns currently active shader program handle.
AFTERWARP_API struct Program_t* SceneGetProgram(struct Scene_t* scene);

/// Activates the appropriate shader program and begins rendering the scene.
AFTERWARP_API LibraryBool SceneBegin(struct Scene_t* scene);

/// Finishes rendering the scene and deactivates previously activated shader program.
AFTERWARP_API void SceneEnd(struct Scene_t* scene);

/// Indicates that the rendering is currently taking place (inside \c SceneBegin() / \c SceneEnd() block).
AFTERWARP_API LibraryBool SceneRendering(struct Scene_t* scene);

/// Clears cached buffers and resources in the scene.
AFTERWARP_API void SceneResetCache(struct Scene_t* scene);

// The following functions only work with "modeling" scene.

/// Returns scene object's material properties.
AFTERWARP_API void SceneGetMaterial(struct Scene_t* scene, ObjectMaterial* material);

/// Updates scene object's material properties.
AFTERWARP_API LibraryBool SceneSetMaterial(struct Scene_t* scene, ObjectMaterial const* material);

/// Returns tone-mapping RGB luma coefficients and maximum allowed level of white.
/// These parameters are used only when "glassy" (OIT) technique is being performed.
AFTERWARP_API void SceneGetToneMappingCoefficients(struct Scene_t* scene, Vector4* coefficients);

/// Updates tone-mapping RGB luma coefficients and maximum allowed level of white.
/// These parameters are used only when "glassy" (OIT) technique is being performed.
AFTERWARP_API LibraryBool SceneSetToneMappingCoefficients(struct Scene_t* scene, Vector4 const* coefficients);

/// Returns parameters that define Parallax Mapping technique is performed.
AFTERWARP_API void SceneGetParallaxMappingParameters(struct Scene_t* scene,
  ParallaxMappingParameters* parameters);

/// Updates parameters that define Parallax Mapping technique is performed.
AFTERWARP_API LibraryBool SceneSetParallaxMappingParameters(struct Scene_t* scene,
  ParallaxMappingParameters const* parameters);

/// Returns sampler of the given type associated with the scene.
AFTERWARP_API struct Sampler_t* SceneGetSampler(struct Scene_t* scene, SceneSamplerType type);

/// Returns texture of the given type associated with the scene.
AFTERWARP_API struct Texture_t* SceneGetTexture(struct Scene_t* scene, SceneTextureType type);

/// Updates texture of the given type associated with the scene.
AFTERWARP_API LibraryBool SceneSetTexture(struct Scene_t* scene, struct Texture_t* texture,
  SceneTextureType type);

/// Returns lights container module associated with the scene.
AFTERWARP_API struct SceneLights_t* SceneGetLights(struct Scene_t* scene);

/// Changes light container module associated with the scene. Note: this must be called outside
/// of \c SceneBegin() and \c SceneEnd() block and before calling \c ScenePrepare() function.
AFTERWARP_API void SceneSetLights(struct Scene_t* scene, struct SceneLights_t* sceneLights);

/// Returns shadow casting atlas associated with the scene.
AFTERWARP_API struct ShadowCastingAtlas_t* SceneGetShadowCastingAtlas(struct Scene_t* scene);

/// Changes shadow casting atlas associated with the scene. Note: this must be called outside
/// of \c SceneBegin() and \c SceneEnd() block and before calling \c ScenePrepare() function.
AFTERWARP_API void SceneSetShadowCastingAtlas(struct Scene_t* scene,
  struct ShadowCastingAtlas_t* shadowCastingAtlas);

/// Returns an associated texture cabinet.
AFTERWARP_API struct TextureCabinet_t* SceneGetTextureCabinet(struct Scene_t* scene);

/// Updates an association with a texture cabinet. Note: this must be called outside
/// of \c SceneBegin() and \c SceneEnd() block and before calling \c ScenePrepare() function.
AFTERWARP_API void SceneSetTextureCabinet(struct Scene_t* scene,
  struct TextureCabinet_t* textureCabinet);

/// Configures rendering parameters for the scene, retrieves light indices from light container module and
/// updates internal buffers required for rendering the scene. This must be called outside of \c SceneBegin()
/// and \c SceneEnd() block, but before starting any rendering. Ambient occlusion texture, shadow casting
/// atlas, view and projection matrices have been assigned prior this call.
AFTERWARP_API LibraryBool ScenePrepare(struct Scene_t* scene);

// OceanSimulation functions.

/// Creates a new instance of module for rendering semi-infinite 3D ocean wave fields.
AFTERWARP_API struct OceanSimulation_t* OceanSimulationCreate(struct Device_t* device);

/// Releases an existing ocean rendering module.
AFTERWARP_API void OceanSimulationDestroy(struct OceanSimulation_t* oceanSimulation);

/// Returns device associated with the given module.
AFTERWARP_API struct Device_t* OceanSimulationGetDevice(struct OceanSimulation_t* oceanSimulation);

/// Returns ocean waves simulation parameters.
AFTERWARP_API void OceanSimulationGetWavesParameters(struct OceanSimulation_t* oceanSimulation,
  OceanWavesParameters* parameters);

/// Updates ocean waves simulation parameters.
AFTERWARP_API LibraryBool OceanSimulationSetWavesParameters(struct OceanSimulation_t* oceanSimulation,
  OceanWavesParameters const* parameters);

/// Returns an existing ocean waves simulation texture. This would be mostly useful for debug purposes.
AFTERWARP_API struct Texture_t* OceanSimulationGetWavesTexture(struct OceanSimulation_t* oceanSimulation,
  int32_t index);

/// Returns number of sub-divisions in screen-space.
AFTERWARP_API void OceanSimulationGetSections(struct OceanSimulation_t* oceanSimulation, Point* sections);

/// Changes number of sub-divisions in screen-space.
AFTERWARP_API LibraryBool OceanSimulationSetSections(struct OceanSimulation_t* oceanSimulation,
  Point const* sections);

/// Returns view transformation matrix.
AFTERWARP_API void OceanSimulationGetView(struct OceanSimulation_t* oceanSimulation, Matrix* view);

/// Changes view transformation matrix.
AFTERWARP_API LibraryBool OceanSimulationSetView(struct OceanSimulation_t* oceanSimulation,
  Matrix const* view);

/// Returns projection transformation matrix.
AFTERWARP_API void OceanSimulationGetProjection(struct OceanSimulation_t* oceanSimulation,
  Matrix* projection);

/// Changes projection transformation matrix.
AFTERWARP_API LibraryBool OceanSimulationSetProjection(struct OceanSimulation_t* oceanSimulation,
  Matrix const* projection);

/// Returns scale of the displacement map.
AFTERWARP_API void OceanSimulationGetScale(struct OceanSimulation_t* oceanSimulation, Vector* scale);

/// Changes scale of the displacement map.
AFTERWARP_API LibraryBool OceanSimulationSetScale(struct OceanSimulation_t* oceanSimulation,
  Vector const* scale);

/// Returns grid's plane equation.
AFTERWARP_API void OceanSimulationGetPlane(struct OceanSimulation_t* oceanSimulation, Vector4* plane);

/// Changes grid's plane equation.
AFTERWARP_API LibraryBool OceanSimulationSetPlane(struct OceanSimulation_t* oceanSimulation,
  Vector4 const* plane);

/// Returns maximum height-map viewing distance.
AFTERWARP_API float OceanSimulationGetViewDistance(struct OceanSimulation_t* oceanSimulation);

/// Changes maximum height-map viewing distance.
AFTERWARP_API LibraryBool OceanSimulationSetViewDistance(struct OceanSimulation_t* oceanSimulation,
  float viewDistance);

/// Returns currently set rendering attributes.
AFTERWARP_API SceneAttributes OceanSimulationGetAttributes(struct OceanSimulation_t* oceanSimulation);

/// Updates the rendering attributes.
/// Note that only SCENE_ATTRIBUTE_SHADOWS_CUBIC is currently recognized by the module.
AFTERWARP_API void OceanSimulationSetAttributes(struct OceanSimulation_t* oceanSimulation,
  SceneAttributes attributes);

/// Returns ocean's material.
AFTERWARP_API void OceanSimulationGetMaterial(struct OceanSimulation_t* oceanSimulation,
  OceanMaterial* material);

/// Updates ocean's material.
AFTERWARP_API LibraryBool OceanSimulationSetMaterial(struct OceanSimulation_t* oceanSimulation,
  OceanMaterial const* material);

/// Returns sampler for reading from shadow map.
AFTERWARP_API struct Sampler_t* OceanSimulationGetSamplerShadow(struct OceanSimulation_t* oceanSimulation);

/// Executes the simulation of ocean waves and updates internal textures.
AFTERWARP_API LibraryBool OceanSimulationUpdate(struct OceanSimulation_t* oceanSimulation, double latency);

/// Renders the simulation to an existing active rendering surface.
AFTERWARP_API LibraryBool OceanSimulationRender(struct OceanSimulation_t* oceanSimulation,
  struct Texture_t* linearDepths, struct SceneLights_t* sceneLights, struct ShadowCastingAtlas_t* atlas);

// ObjectModel functions.

/// Returns a container that owns the object.
AFTERWARP_API struct ObjectModels_t* ObjectModelGetOwner(struct ObjectModel_t* objectModel);

/// Returns object's unique identification number.
AFTERWARP_API ObjectModelID ObjectModelGetID(struct ObjectModel_t* objectModel);

/// Retrieves object's name.
AFTERWARP_API void ObjectModelGetName(struct ObjectModel_t* objectModel, char* modelName,
  _Inout_ int32_t* modelNameLength);

/// Returns object's payload.
AFTERWARP_API ObjectPayload ObjectModelGetPayload(struct ObjectModel_t* objectModel);

/// Changes object's name.
AFTERWARP_API LibraryBool ObjectModelSetName(struct ObjectModel_t* objectModel, char const* name);

/// Retrieves object's description text.
AFTERWARP_API void ObjectModelGetDescription(struct ObjectModel_t* objectModel, char* description,
  _Inout_ int32_t* descriptionLength);

/// Changes object's description text.
AFTERWARP_API LibraryBool ObjectModelSetDescription(struct ObjectModel_t* objectModel,
  char const* description);

/// Returns object model's voxel representation.
AFTERWARP_API struct MeshVoxel_t* ObjectModelGetVoxel(struct ObjectModel_t* objectModel);

/// Updates object model's voxel representation.
AFTERWARP_API void ObjectModelSetVoxel(struct ObjectModel_t* objectModel, struct MeshVoxel_t* meshVoxel);

/// Returns object's renderable mesh.
AFTERWARP_API struct SceneMesh_t* ObjectModelGetMesh(struct ObjectModel_t* objectModel);

/// Changes object's renderable mesh.
AFTERWARP_API LibraryBool ObjectModelSetMesh(struct ObjectModel_t* objectModel,
  struct SceneMesh_t* sceneMesh);

/// Returns name of the currently associated mesh (or NULL, if no mesh is associated).
AFTERWARP_API void ObjectModelGetMeshName(struct ObjectModel_t* objectModel, char* meshName,
  _Inout_ int32_t* meshNameLength);

/// Changes object's renderable mesh to one with the given name.
AFTERWARP_API LibraryBool ObjectModelSetMeshName(struct ObjectModel_t* objectModel, char const* meshName);

/// Returns object model's parent.
AFTERWARP_API struct ObjectModel_t* ObjectModelGetParent(struct ObjectModel_t* objectModel);

/// Changes object model's parent.
AFTERWARP_API LibraryBool ObjectModelSetParent(struct ObjectModel_t* objectModel,
  struct ObjectModel_t* parent);

/// Returns number of object model's children.
AFTERWARP_API int32_t ObjectModelGetChildCount(struct ObjectModel_t* objectModel);

/// Returns pointer to a particular object model's child.
AFTERWARP_API struct ObjectModel_t* ObjectModelGetChild(struct ObjectModel_t* objectModel, int32_t index);

/// Retrieves one of current object model's transforms.
AFTERWARP_API void ObjectModelGetTransform(struct ObjectModel_t* objectModel, ModelTransform transform,
  Matrix* matrix);

/// Updates one of current object model's transforms.
AFTERWARP_API LibraryBool ObjectModelSetTransform(struct ObjectModel_t* objectModel,
  ModelTransform transform, Matrix const* matrix);

/// Extracts and returns current object position.
AFTERWARP_API void ObjectModelGetPosition(struct ObjectModel_t* objectModel, Vector* position);

/// Returns current depth bias, which is used during object selection.
AFTERWARP_API float ObjectModelGetDepthBias(struct ObjectModel_t* objectModel);

/// Updates depth bias, which is used during object selection.
AFTERWARP_API void ObjectModelSetDepthBias(struct ObjectModel_t* objectModel, float depthBias);

/// Updates and returns axis-aligned bounding box of the object.
AFTERWARP_API void ObjectModelGetAABB(struct ObjectModel_t* objectModel, Vector* boxMin, Vector* boxMax);

/// Returns current object model's attributes.
AFTERWARP_API uint32_t ObjectModelGetAttributes(struct ObjectModel_t* objectModel);

/// Updates current object's attributes.
AFTERWARP_API void ObjectModelSetAttributes(struct ObjectModel_t* objectModel, uint32_t attributes);

/// Returns current priority order index.
AFTERWARP_API int32_t ObjectModelGetOrderIndex(struct ObjectModel_t* objectModel);

/// Updates object's priority order index.
AFTERWARP_API void ObjectModelSetOrderIndex(struct ObjectModel_t* objectModel, int32_t orderIndex);

/// Returns layers on which the object is visible.
AFTERWARP_API uint64_t ObjectModelGetLayers(struct ObjectModel_t* objectModel);

/// Specifies layers on which the object is visible.
/// Note: If no layer bits are set, then object would appear visible on all layers.
AFTERWARP_API void ObjectModelSetLayers(struct ObjectModel_t* objectModel, uint64_t layers);

/// Returns the object's size.
AFTERWARP_API void ObjectModelGetSize(struct ObjectModel_t* objectModel, Vector* size);

/// Changes the object's size.
AFTERWARP_API void ObjectModelSetSize(struct ObjectModel_t* objectModel, Vector const* size);

/// Returns mesh alignments.
AFTERWARP_API void ObjectModelGetAlignments(struct ObjectModel_t* objectModel, MeshAligns* aligns);

/// Changes mesh alignments.
AFTERWARP_API void ObjectModelSetAlignments(struct ObjectModel_t* objectModel, MeshAligns const* aligns);

/// Returns object's material.
AFTERWARP_API int32_t ObjectModelGetMaterial(struct ObjectModel_t* objectModel);

/// Updates object's material.
AFTERWARP_API void ObjectModelSetMaterial(struct ObjectModel_t* objectModel, int32_t material);

/// Returns object's color.
AFTERWARP_API void ObjectModelGetColor(struct ObjectModel_t* objectModel, FloatColor* color);

/// Updates object's color.
AFTERWARP_API void ObjectModelSetColor(struct ObjectModel_t* objectModel, FloatColor const* color);

/// Returns object's highlight color.
AFTERWARP_API void ObjectModelGetHighlight(struct ObjectModel_t* objectModel, FloatColor* highlight);

/// Updates object's highlight color.
AFTERWARP_API void ObjectModelSetHighlight(struct ObjectModel_t* objectModel, FloatColor const* highlight);

/// Connects a local bone joint with the given index to a corresponding joint of the parent.
AFTERWARP_API void ObjectModelConnectLatches(struct ObjectModel_t* objectModel, int32_t latchParent,
  int32_t latchLocal);

/// Connects a local bone joint with the given name (case-insensitive) to a corresponding joint of the parent.
AFTERWARP_API void ObjectModelConnectLatchesByName(struct ObjectModel_t* objectModel,
  _In_opt_ char const* latchParentName, _In_opt_ char const* latchLocalName);

/// Returns indexes of currently connected bone joints.
AFTERWARP_API void ObjectModelGetConnectedLatches(struct ObjectModel_t* objectModel, int32_t* latchParent,
  int32_t* latchLocal);

/// Returns calculated waypoint traveling distance for the given latch group.
AFTERWARP_API float ObjectModelGetWaypointDistance(struct ObjectModel_t* objectModel, int32_t group);

/// Calculates interpolated position and orientation based on the given distance for the given latch group.
AFTERWARP_API void ObjectModelGetLatchWaypointCouple(struct ObjectModel_t* objectModel, int32_t group,
  float distance, Vector* position, Quaternion* orientation);

/// Calculates transformation matrix with interpolated position and orientation based on the given distance
/// for the given latch group.
AFTERWARP_API void ObjectModelGetLatchWaypointCoupleMatrix(struct ObjectModel_t* objectModel, int32_t group,
  float distance, Matrix* transform);

/// Retrieves either local or global transformation matrix for a given latch index.
AFTERWARP_API void ObjectModelGetLatchTransform(struct ObjectModel_t* objectModel, Matrix* transform,
  int32_t latchIndex, LibraryBool local);

/// Retrieves either local or global transformation matrix for a latch with the given name.
AFTERWARP_API void ObjectModelGetLatchTransformByName(struct ObjectModel_t* objectModel, Matrix* transform,
  char const* name, LibraryBool local);

/// Marks local transform, volume and position as dirty, including children.
AFTERWARP_API void ObjectModelInvalidate(struct ObjectModel_t* objectModel);

/// Retrieves next object from the same collection to which the given object belongs. If the given object is
/// last object in the collection, NULL will be returned.
AFTERWARP_API struct ObjectModel_t* ObjectModelGetNext(struct ObjectModel_t* objectModel);

// ObjectModels functions.

/// Creates a new instance of the container associated with a particular list of meshes.
AFTERWARP_API struct ObjectModels_t* ObjectModelsCreate(struct SceneMeshes_t* sceneMeshes);

/// Releases current instance of the container.
AFTERWARP_API void ObjectModelsDestroy(struct ObjectModels_t* objectModels);

/// Returns the associated mesh container.
AFTERWARP_API struct SceneMeshes_t* ObjectModelsGetMeshes(struct ObjectModels_t* objectModels);

/// Returns number of existing objects.
AFTERWARP_API int32_t ObjectModelsGetObjectCount(struct ObjectModels_t* objectModels);

/// Returns a first object from the collection of existing objects.
AFTERWARP_API struct ObjectModel_t* ObjectModelsGetFirst(struct ObjectModels_t* objectModels);

/// Creates a new object with a given id, name and/or payload association. If the given ID already exists,
/// or an "unknown ID" is given, a new unique one will be assigned to the object. Unique IDs are generated
/// incrementally with roll-over when highest possible ID is reached, so eventually lower order IDs might be
/// reused; the function ensures, however, that a given ID is unique in sense that it is not assigned to
/// another other object.
AFTERWARP_API struct ObjectModel_t* ObjectModelsAddWithID(struct ObjectModels_t* objectModels,
  ObjectModelID id, _In_opt_ char const* name, ObjectPayload payload, uint32_t attributes);

/// Creates a new object with the given name and/or payload association.
AFTERWARP_API struct ObjectModel_t* ObjectModelsAdd(struct ObjectModels_t* objectModels,
  _In_opt_ char const* name, ObjectPayload payload, uint32_t attributes);

/// Removes the given object.
AFTERWARP_API void ObjectModelsErase(struct ObjectModels_t* objectModels,
  struct ObjectModel_t* objectModel);

/// Removes all objects.
AFTERWARP_API void ObjectModelsClear(struct ObjectModels_t* objectModels);

/// Returns an object with the given ID or NULL if such doesn't exist.
AFTERWARP_API struct ObjectModel_t* ObjectModelsGetObjectByID(struct ObjectModels_t* objectModels,
  ObjectModelID id);

/// Returns an object with the given name (case-insensitive) or NULL if such doesn't exist.
AFTERWARP_API struct ObjectModel_t* ObjectModelsGetObjectByName(struct ObjectModels_t* objectModels,
  char const* name);

/// Returns object that corresponds to the given payload in 3D object model container.
AFTERWARP_API struct ObjectModel_t* ObjectModelsPayload(struct ObjectModels_t* objectModels,
  ObjectPayload payload);

/// Creates a new view associated with this collection.
AFTERWARP_API struct ObjectModelView_t* ObjectModelsCreateView(struct ObjectModels_t* objectModels);

/// Erases an existing view from the collection.
AFTERWARP_API void ObjectModelsEraseView(struct ObjectModels_t* objectModels,
  struct ObjectModelView_t* objectModelView);

/// Removes all existing views from the collection.
AFTERWARP_API void ObjectModelsClearViews(struct ObjectModels_t* objectModels);

// ObjectModelView functions.

/// Returns parent of the view container.
AFTERWARP_API struct ObjectModels_t* ObjectModelViewGetOwner(struct ObjectModelView_t* objectModelView);

/// Returns "View" transformation matrix of the container.
AFTERWARP_API void ObjectModelViewGetView(struct ObjectModelView_t* objectModelView, Matrix* view);

/// Changes "View" transformation matrix of the container.
AFTERWARP_API void ObjectModelViewSetView(struct ObjectModelView_t* objectModelView, Matrix const* view);

/// Returns "Projection" transformation matrix of the view container.
AFTERWARP_API void ObjectModelViewGetProjection(struct ObjectModelView_t* objectModelView,
  Matrix* projection, LibraryBool* depthClipNegative);

/// Changes "Projection" transformation matrix of the view container.
AFTERWARP_API void ObjectModelViewSetProjection(struct ObjectModelView_t* objectModelView,
  Matrix const* projection, LibraryBool depthClipNegative);

/// Returns combined "View/Projection" matrix of the container.
AFTERWARP_API void ObjectModelViewGetViewProjection(struct ObjectModelView_t* objectModelView,
  Matrix* viewProjection);

/// Returns layers that determine object visibility in the view.
AFTERWARP_API uint64_t ObjectModelViewGetLayers(struct ObjectModelView_t* objectModelView);

/// Changes layers that determine object visibility in the view.
AFTERWARP_API void ObjectModelViewSetLayers(struct ObjectModelView_t* objectModelView, uint64_t layers);

/// Notifies the container that all visible objects must be recalculated.
AFTERWARP_API void ObjectModelViewUpdateNeeded(struct ObjectModelView_t* objectModelView);

/// Notifies the container that it needs to be repainted.
AFTERWARP_API void ObjectModelViewInvalidate(struct ObjectModelView_t* objectModelView);

/// Returns number of existing objects that are visible in the view.
AFTERWARP_API int32_t ObjectModelViewGetObjectCount(struct ObjectModelView_t* objectModelView);

/// Returns an object with the given index from the view container.
AFTERWARP_API struct ObjectModel_t* ObjectModelViewGetObject(struct ObjectModelView_t* objectModelView,
  int32_t index);

/// Creates a list of objects for selection and rendering from the view container.
/// Returns \c true if there are any objects visible in the view.
AFTERWARP_API LibraryBool ObjectModelViewUpdate(struct ObjectModelView_t* objectModelView);

/// Sorts the list of objects using a predefined comparison function.
AFTERWARP_API void ObjectModelViewSort(struct ObjectModelView_t* objectModelView,
  ObjectModelViewCompare compare);

/// Sorts the list of objects using a custom comparison function.
AFTERWARP_API void ObjectModelViewSortWith(struct ObjectModelView_t* objectModelView,
  ObjectModelCompareFunc compareFunc, void* user);

/// Performs object selection either through object's voxel hierarchy if such is present and if not,
/// through ray-volume intersection. All selectable and visible objects are tested and the object with
/// closest intersection is finally chosen.
AFTERWARP_API struct ObjectModel_t* ObjectModelViewSelect(struct ObjectModelView_t* objectModelView,
  Vector const* origin, Vector const* direction, float* distance);

/// Performs object selection either through object's voxel hierarchy if such is present and if not,
/// through ray-volume intersection. All visible objects are tested and the object with closest
/// intersection is finally chosen.
AFTERWARP_API struct ObjectModel_t* ObjectModelViewSelectAny(struct ObjectModelView_t* objectModelView,
  Vector const* origin, Vector const* direction, float* distance);

/// Returns number of objects that were not performed cull test, either because they were determined to be
/// fully visible, or because they were marked as hierarchyless.
AFTERWARP_API int32_t ObjectModelViewGetObjectsNotCulled(struct ObjectModelView_t* objectModelView);

/// Returns number of ray vs AABB intersections performed last time selection was performed.
AFTERWARP_API int32_t ObjectModelViewGetIntersectedRays(struct ObjectModelView_t* objectModelView);

/// Returns number of objects that passed intersection during last selection attempt.
AFTERWARP_API int32_t ObjectModelViewGetIntersectedObjects(struct ObjectModelView_t* objectModelView);

/// Renders objects that are visible in the view according to the provided options.
/// If \a scene is NULL, this does not perform instancing or issue actual draw calls, instead performing
/// a simple non-instancing run and counting any tentative draw calls that would be issued; this can be used
/// to determine if any objects would be rendered at all or not to decide whether to perform a certain
/// rendering pass.
AFTERWARP_API LibraryBool ObjectModelViewAutoDraw(struct ObjectModelView_t* objectModelView,
  struct Scene_t* scene, struct ObjectMaterials_t* materials, uint32_t options,
  _Inout_ int32_t* drawCalls);

// MeshVoxel functions.

/// Creates an empty 3D mesh voxel representation.
AFTERWARP_API struct MeshVoxel_t* MeshVoxelCreate(void);

/// Releases the given 3D mesh voxel representation.
AFTERWARP_API void MeshVoxelDestroy(struct MeshVoxel_t* meshVoxel);

/// Takes away the internal contents from another 3D mesh voxel representation replacing any existing
/// contents, without doing any copying.
AFTERWARP_API void MeshVoxelTakeAway(struct MeshVoxel_t* meshVoxel, struct MeshVoxel_t* meshVoxelAnother);

/// Loads an existing 3D mesh voxel representation from a file on disk.
AFTERWARP_API LibraryBool MeshVoxelLoadFromFile(struct MeshVoxel_t* meshVoxel, char const* fileName,
  int32_t dimensions[], uint8_t* levels, LibraryBool* colors);

/// Loads an existing 3D mesh voxel representation from a file in memory.
AFTERWARP_API LibraryBool MeshVoxelLoadFromFileInMemory(struct MeshVoxel_t* meshVoxel, void* buffer,
  uint32_t bufferSize, int32_t dimensions[], uint8_t* levels, LibraryBool* colors);

/// Saves 3D mesh voxel representation to a file on disk.
AFTERWARP_API LibraryBool MeshVoxelSaveToFile(struct MeshVoxel_t* meshVoxel, char const* fileName,
  int32_t const dimensions[], uint8_t levels, LibraryBool colors);

/// Returns position and size of 3D mesh voxel representation.
AFTERWARP_API void MeshVoxelExtents(struct MeshVoxel_t* meshVoxel, Vector* position, Vector* size);

/// Calculates existing voxel dimensions, levels and whether colors are present.
AFTERWARP_API void MeshVoxelComputeParameters(struct MeshVoxel_t* meshVoxel, int32_t dimensions[],
  uint8_t* levels, LibraryBool* colors);

/// Visualizes 3D mesh voxel representation by invoking callback function for each cube.
AFTERWARP_API LibraryBool MeshVoxelVisualize(struct MeshVoxel_t* meshVoxel, uint8_t levelMax,
  MeshVoxelVisualizeFunc visualizeFunc, void* user);

/// Performs intersection between voxel representation and ray.
AFTERWARP_API LibraryBool MeshVoxelIntersect(struct MeshVoxel_t* meshVoxel, Vector const* origin,
  Vector const* direction, Matrix const* world, Matrix const* view, float* distance, int32_t* testsCount);

// SceneMeshMaterial functions.

/// Returns material name. The pointed value of \c nameLength defines the maximum number of characters,
/// including null-terminating character, that can be copied. The actual string length is stored
/// in \c nameLength.
AFTERWARP_API void SceneMeshMaterialGetName(struct SceneMeshMaterial_t* material, char* name,
  _Inout_ int32_t* nameLength);

/// Returns shading parameters of the material.
AFTERWARP_API void SceneMeshMaterialGetShading(struct SceneMeshMaterial_t* material,
  SceneMeshMaterialShading* shading);

/// Updates shading parameters of the material.
AFTERWARP_API void SceneMeshMaterialSetShading(struct SceneMeshMaterial_t* material,
  SceneMeshMaterialShading const* shading);

/// Returns a texture associated with the given type or NULL if such does not exist.
AFTERWARP_API struct Texture_t* SceneMeshMaterialGetTexture(struct SceneMeshMaterial_t* material,
  uint8_t type);

/// Changes texture of the given type. Note: material will take ownership of the given texture instance
/// and reliquish ownership of instance that was previously assigned (if it is not NULL).
AFTERWARP_API LibraryBool SceneMeshMaterialSetTexture(struct SceneMeshMaterial_t* material,
  struct Texture_t* texture, uint8_t type);

/// Releases existing textures.
AFTERWARP_API void SceneMeshMaterialReleaseTextures(struct SceneMeshMaterial_t* material);

/// Returns number of existing ranges.
AFTERWARP_API int32_t SceneMeshMaterialGetRangeCount(struct SceneMeshMaterial_t* material);

/// Returns a range with the given index.
AFTERWARP_API LibraryBool SceneMeshMaterialGetRange(struct SceneMeshMaterial_t* material,
  int32_t index, _Out_ SceneMeshMaterialRange* range);

/// Updates a range with the given index.
AFTERWARP_API LibraryBool SceneMeshMaterialSetRange(struct SceneMeshMaterial_t* material,
  int32_t index, SceneMeshMaterialRange const* range);

/// Adds a given range to the list of existing ranges and returns its index.
/// In case of memory allocation failure, returns -1.
AFTERWARP_API int32_t SceneMeshMaterialAddRange(struct SceneMeshMaterial_t* material,
  SceneMeshMaterialRange const* range);

/// Removes all existing ranges.
AFTERWARP_API void SceneMeshMaterialClearRanges(struct SceneMeshMaterial_t* material);

/// Converts existing "scratch" textures into hardware-based textures.
AFTERWARP_API LibraryBool SceneMeshMaterialCommit(struct SceneMeshMaterial_t* material,
  struct Device_t* device, TextureAttributes attributes);

/// Copies contents from another material. In case of textures, creates new instances of textures and copies
/// the contents of textures from the source.
AFTERWARP_API LibraryBool SceneMeshMaterialCopy(struct SceneMeshMaterial_t* material,
  struct SceneMeshMaterial_t* source);

// SceneMeshMaterials functions.

/// Creates a new 3D scene mesh material container.
AFTERWARP_API struct SceneMeshMaterials_t* SceneMeshMaterialsCreate(void);

/// Releases an existing instance of 3D scene mesh material container.
AFTERWARP_API void SceneMeshMaterialsDestroy(struct SceneMeshMaterials_t* materials);

/// Changes the name of the library.
AFTERWARP_API LibraryBool SceneMeshMaterialsSetName(struct SceneMeshMaterials_t* materials,
  char const* name);

/// Returns name of the library.
AFTERWARP_API void SceneMeshMaterialsGetName(struct SceneMeshMaterials_t* materials,
  char* name, _Inout_ int32_t* nameLength);

/// Returns total number of existing materials.
AFTERWARP_API int32_t SceneMeshMaterialsGetCount(struct SceneMeshMaterials_t* materials);

/// Returns an existing material with the given index, if such exists.
AFTERWARP_API struct SceneMeshMaterial_t* SceneMeshMaterialsGetMaterial(
  struct SceneMeshMaterials_t* materials, int32_t index);

/// Adds a new material to the scene mesh and returns its index.
/// In case of memory allocation failure, returns -1.
AFTERWARP_API int32_t SceneMeshMaterialsAdd(struct SceneMeshMaterials_t* materials, char const* name);

/// Removes a material with the given index.
AFTERWARP_API void SceneMeshMaterialsErase(struct SceneMeshMaterials_t* materials, int32_t index);

/// Removes and releases all existing materials.
AFTERWARP_API void SceneMeshMaterialsClear(struct SceneMeshMaterials_t* materials);

/// Converts existing "scratch" textures into hardware-based textures.
AFTERWARP_API LibraryBool SceneMeshMaterialsCommit(struct SceneMeshMaterials_t* materials,
  struct Device_t* device, TextureAttributes attributes);

/// Copies materials into the collection from another container.
AFTERWARP_API LibraryBool SceneMeshMaterialsCopy(struct SceneMeshMaterials_t* materials,
  struct SceneMeshMaterials_t* materialsAnother);

/// Takes away the internal contents from another material container without doing any copying.
AFTERWARP_API void SceneMeshMaterialsTakeAway(struct SceneMeshMaterials_t* materials,
  struct SceneMeshMaterials_t* materialsAnother);

/// Reviews existing materials to determine whether any of them use texturing.
AFTERWARP_API LibraryBool SceneMeshMaterialsTexturing(struct SceneMeshMaterials_t* materials);

// SceneMeshLatches functions.

/// Creates a new 3D scene mesh latches container.
AFTERWARP_API struct SceneMeshLatches_t* SceneMeshLatchesCreate(void);

/// Releases an existing instance of 3D scene mesh latches container.
AFTERWARP_API void SceneMeshLatchesDestroy(struct SceneMeshLatches_t* latches);

/// Returns total number of existing latches.
AFTERWARP_API int32_t SceneMeshLatchesGetCount(struct SceneMeshLatches_t* latches);

/// Returns an existing latch with the given index.
AFTERWARP_API LibraryBool SceneMeshLatchesGetLatch(struct SceneMeshLatches_t* latches, int32_t index,
  SceneMeshLatch* latch);

/// Updates an existing latch with the given index.
AFTERWARP_API LibraryBool SceneMeshLatchesSetLatch(struct SceneMeshLatches_t* latches, int32_t index,
  SceneMeshLatch const* latch);

/// Returns an index of a latch with the given name (case-insensitive) index or -1 if it doesn't exist.
AFTERWARP_API int32_t SceneMeshLatchesGetLatchIndex(struct SceneMeshLatches_t* latches, char const* name);

/// Adds a new latch to the container and returns its index. In case of memory allocation failure,
/// returns -1.
AFTERWARP_API int32_t SceneMeshLatchesAdd(struct SceneMeshLatches_t* latches, _In_opt_ char const* name,
  int32_t type, int32_t group, _In_opt_ Vector const* position, _In_opt_ Quaternion const* orientation);

/// Removes an existing latch with the given index.
AFTERWARP_API void SceneMeshLatchesErase(struct SceneMeshLatches_t* latches, int32_t index);

/// Removes and releases all existing latches.
AFTERWARP_API void SceneMeshLatchesClear(struct SceneMeshLatches_t* latches);

/// Copies latches from another collection.
AFTERWARP_API LibraryBool SceneMeshLatchesCopy(struct SceneMeshLatches_t* latches,
  struct SceneMeshLatches_t* latchesAnother);

/// Takes away the internal contents from another collection without doing any copying.
AFTERWARP_API void SceneMeshLatchesTakeAway(struct SceneMeshLatches_t* latches,
  struct SceneMeshLatches_t* latchesAnother);

/// Loads a collection of latches from file on disk.
AFTERWARP_API LibraryBool SceneMeshLatchesLoadFromFile(struct SceneMeshLatches_t* latches,
  char const* fileName);

/// Loads a collection of latches from file in memory.
AFTERWARP_API LibraryBool SceneMeshLatchesLoadFromFileInMemory(struct SceneMeshLatches_t* latches,
  void* buffer, uint32_t bufferSize);

/// Saves a collection of latches to file on disk.
AFTERWARP_API LibraryBool SceneMeshLatchesSaveToFile(struct SceneMeshLatches_t* latches,
  char const* fileName);

/// Returns calculated waypoint traveling distance for the given latch group.
AFTERWARP_API float SceneMeshLatchesGetWaypointDistance(struct SceneMeshLatches_t* latches,
  int32_t group);

/// Calculates interpolated position and orientation based on the given distance for the given latch group.
AFTERWARP_API void SceneMeshLatchesGetWaypointCouple(struct SceneMeshLatches_t* latches,
  int32_t group, float distance, Vector* position, Quaternion* orientation);

/// Triggers recalculation of the interpolated waypoint positions.
/// This should be done when one or more latches have been modified.
AFTERWARP_API void SceneMeshLatchesInvalidateWaypoints(struct SceneMeshLatches_t* latches);

// SceneMesh functions.

/// Returns name of the mesh.
AFTERWARP_API void SceneMeshGetName(struct SceneMesh_t* sceneMesh, char* meshName,
  _Inout_ int32_t* meshNameLength);

/// Returns payload associated with the mesh.
AFTERWARP_API ObjectPayload SceneMeshGetPayload(struct SceneMesh_t* sceneMesh);

/// Returns a renderable mesh model.
AFTERWARP_API struct MeshModel_t* SceneMeshGetModel(struct SceneMesh_t* sceneMesh);

/// Returns voxel representation of the mesh.
AFTERWARP_API struct MeshVoxel_t* SceneMeshGetVoxel(struct SceneMesh_t* sceneMesh);

/// Returns materials associated with a 3D mesh.
AFTERWARP_API struct SceneMeshMaterials_t* SceneMeshGetMaterials(struct SceneMesh_t* sceneMesh);

/// Returns meta-tags that represent sub-meshes within a 3D mesh.
AFTERWARP_API struct MeshMetaTags_t* SceneMeshGetTags(struct SceneMesh_t* sceneMesh);

/// Returns an integrated collection of latches associated with the 3D mesh.
AFTERWARP_API struct SceneMeshLatches_t* SceneMeshGetLatches(struct SceneMesh_t* sceneMesh);

/// Returns minimum and maximum mesh boundaries.
AFTERWARP_API void SceneMeshGetBounds(struct SceneMesh_t* sceneMesh, Vector* boundsMin, Vector* boundsMax);

/// Returns scale of the mesh.
AFTERWARP_API float SceneMeshGetScale(struct SceneMesh_t* sceneMesh);

/// Returns size of the mesh.
AFTERWARP_API void SceneMeshGetSize(struct SceneMesh_t* sceneMesh, Vector* size);

/// Returns index of vertex elements that describe the format of mesh vertex buffer.
/// A value of 0xFFu means index is undefined.
AFTERWARP_API uint8_t SceneMeshGetVertexElementsIndex(struct SceneMesh_t* sceneMesh);

/// Changes index of vertex elements that describe the format of mesh vertex buffer.
/// A value of 0xFFu means index is undefined.
AFTERWARP_API void SceneMeshSetVertexElementsIndex(struct SceneMesh_t* sceneMesh,
  uint8_t vertexElementsIndex);

/// Specify the parent mesh and the tag to which this slice would refer to.
AFTERWARP_API void SceneMeshSetSlice(struct SceneMesh_t* sceneMesh, struct SceneMesh_t* parent,
  struct MeshMetaTag_t* parentTag);

/// Returns parent mesh that contains the actual 3D model to be rendered and tag that contains information
/// about what portion of parent mesh should be rendered
AFTERWARP_API void SceneMeshGetSlice(struct SceneMesh_t* sceneMesh, _Out_ struct SceneMesh_t** parent,
  _Out_ struct MeshMetaTag_t** parentTag);

/// Issues one or more draw calls for the scene mesh, assigning materials and textures accordingly.
/// If \a material is \c NULL, default material will be used. If \a instanceCount is zero, then
/// non-instancing draw calls will be issued. If \a scene is \c NULL, this does not issue any draw calls,
/// instead counting any tentative draw calls that would be issued; this can be used to determine if any
/// portions of the object would be rendered to decide whether to perform certain pass or not.
AFTERWARP_API LibraryBool SceneMeshAutoDraw(struct SceneMesh_t* sceneMesh, struct Scene_t* scene,
  ObjectMaterial const* material, FloatColor const* color, PrimitiveTopology topology, int32_t instanceCount,
  int32_t elementCount, int32_t firstIndex, int32_t baseVertex, uint32_t options,
  _Inout_ int32_t* drawCalls);

/// Issues one or more draw calls for the scene mesh, assigning materials and textures accordingly.
/// If scene mesh is a slice, then renders the portions of the slice accordingly. If \a material is \c NULL,
/// default material will be used. If \a instanceCount is zero, then non-instancing draw call is issued.
/// If \a scene is \c NULL, this does not issue any draw calls, instead counting any tentative draw calls
/// that would be issued; this can be used to determine if any portions of the object would be rendered to
/// decide whether to perform certain pass or not.
AFTERWARP_API LibraryBool SceneMeshAutoDrawSliced(struct SceneMesh_t* sceneMesh, struct Scene_t* scene,
  ObjectMaterial const* material, FloatColor const* color, PrimitiveTopology topology, int32_t instanceCount,
  uint32_t options, _Inout_ int32_t* drawCalls);

// SceneMeshes functions.

/// Creates new instance of the container associated with a particular device.
AFTERWARP_API struct SceneMeshes_t* SceneMeshesCreate(struct Device_t* device);

/// Releases the container and its owned resources.
AFTERWARP_API void SceneMeshesDestroy(struct SceneMeshes_t* sceneMeshes);

/// Creates a new mesh with the given parameters.
AFTERWARP_API struct SceneMesh_t* SceneMeshesAdd(struct SceneMeshes_t* sceneMeshes, char const* name,
  ObjectPayload payload, Vector const* boundsMin, Vector const* boundsMax, float scale);

/// Creates a new mesh, loading contents from a given mesh buffer.
AFTERWARP_API struct SceneMesh_t* SceneMeshesAddFromBuffer(struct SceneMeshes_t* sceneMeshes,
  char const* name, struct MeshBuffer_t* meshBuffer, ObjectPayload payload,
  VertexElement const vertexElements[], int32_t vertexElementCount, _In_opt_ Vector const* boundsMin,
  _In_opt_ Vector const* boundsMax, uint32_t channel, uint32_t semanticIndex, float scale);

/// Creates a new mesh, loading contents from a file on disk, which can be either a Wavefront OBJ file
/// (with ".obj" extension), or a proprietary binary file (with ".mesh" extension). If the source file is in
/// OBJ format, this function will also try to automatically load an accompanying voxel file (same file name,
/// but with ".voxel" extension) and/or latches (".latch" extension), if such is present at the same path.
AFTERWARP_API struct SceneMesh_t* SceneMeshesAddFromFile(struct SceneMeshes_t* sceneMeshes,
  char const* name, char const* fileName, ObjectPayload payload, VertexElement const vertexElements[],
  int32_t vertexElementCount, uint32_t channel, uint32_t semanticIndex, _Inout_ uint32_t* options,
  float scale, MeshLoadSaveFeedback feedback, void* feedbackUser, char* debug, _Inout_ int32_t* debugLength);

/// Splits the given parent mesh into "dummy" sub-meshes by specific meta-tag type. Each sub-mesh splitted
/// this way will refer to parent and one of its tag accordingly. This enables sharing the same 3D model
/// for rendering, while having customized voxel representation and/or latches for each splitted segment.
AFTERWARP_API LibraryBool SceneMeshesSlice(struct SceneMeshes_t* sceneMeshes, struct SceneMesh_t* parent,
  uint8_t type, char const* prefix);

/// Returns device associated with the container.
AFTERWARP_API struct Device_t* SceneMeshesGetDevice(struct SceneMeshes_t* sceneMeshes);

/// Returns number of existing meshes.
AFTERWARP_API int32_t SceneMeshesGetCount(struct SceneMeshes_t* sceneMeshes);

/// Returns mesh with the given index.
/// Note that adding or removing meshes invalidates all previous mesh indices.
AFTERWARP_API struct SceneMesh_t* SceneMeshesGetMeshByIndex(struct SceneMeshes_t* sceneMeshes, int32_t index);

/// Returns mesh with the given name (case-insensitive) or NULL if no mesh with such name exists.
AFTERWARP_API struct SceneMesh_t* SceneMeshesGetMeshByName(struct SceneMeshes_t* sceneMeshes,
  char const* name);

/// Returns a mesh that corresponds to the given payload or NULL if such doesn't exist.
AFTERWARP_API struct SceneMesh_t* SceneMeshesPayload(struct SceneMeshes_t* sceneMeshes,
  ObjectPayload payload);

/// Erases the given mesh.
AFTERWARP_API void SceneMeshesErase(struct SceneMeshes_t* sceneMeshes, struct SceneMesh_t* sceneMesh);

/// Removes all existing meshes.
AFTERWARP_API void SceneMeshesClear(struct SceneMeshes_t* sceneMeshes);

// Application functions.

/// Creates a new application instance.
AFTERWARP_API struct Application_t* ApplicationCreate(_Inout_ ApplicationConfiguration* configuration);

/// Releases the given application instance.
AFTERWARP_API void ApplicationDestroy(struct Application_t* application);

/// Sets events that will be invoked by the application. If all events are set to \c NULL, or \c events is
/// set to \c NULL, then the appropriate events will use default handlers.
AFTERWARP_API void ApplicationSetEvents(struct Application_t* application, ApplicationEvents const* events,
  void* user);

/// Retrieves the handle of main application window.
AFTERWARP_API UntypedHandle ApplicationGetWindowHandle(struct Application_t* application);

/// Sets new application title.
AFTERWARP_API LibraryBool ApplicationSetTitle(struct Application_t* application, char const* title);

/// Retrieves current application title. The pointed value of \c titleLength defines the maximum
/// number of characters, including null-terminating character, that can be copied. The actual string length
/// is stored in \c titleLength.
AFTERWARP_API void ApplicationGetTitle(struct Application_t* application, char* title,
  _Inout_ int32_t* titleLength);

/// Sets new application's icon title.
AFTERWARP_API LibraryBool ApplicationSetIconTitle(struct Application_t* application, char const* iconTitle);

/// Retrieves current application icon title. The pointed value of \c iconTitleLength defines the maximum
/// number of characters, including null-terminating character, that can be copied. The actual string length
/// is stored in \c iconTitleLength.
AFTERWARP_API void ApplicationGetIconTitle(struct Application_t* application, char* iconTitle,
  _Inout_ int32_t* iconTitleLength);

/// Retrieves current application's execution path. The pointed value of \c pathLength defines the maximum
/// number of characters, including null-terminating character, that can be copied. The actual string length
/// is stored in \c pathLength.
AFTERWARP_API void ApplicationGetExecutablePath(struct Application_t* application, char* path,
  _Inout_ int32_t* pathLength);

/// Retrieves current application's window rectangle.
AFTERWARP_API void ApplicationGetWindowRect(struct Application_t* application, Rect* rect);

/// Sets new application's window rectangle.
AFTERWARP_API void ApplicationSetWindowRect(struct Application_t* application, Rect const* rect);

/// Retrieves current application's window client rectangle.
AFTERWARP_API void ApplicationGetClientRect(struct Application_t* application, Rect* rect);

/// Sets new application's window client size.
AFTERWARP_API void ApplicationSetClientSize(struct Application_t* application, Point const* size);

/// Returns current minimal size of the window. Values of zero means that there is no limit.
AFTERWARP_API void ApplicationGetMinimalSize(struct Application_t* application, Point* size);

/// Sets a minimal size of the window. Values of zero means that there is no limit.
AFTERWARP_API void ApplicationSetMinimalSize(struct Application_t* application, Point const* size);

/// Returns the scale of application window.
AFTERWARP_API double ApplicationGetWindowScale(struct Application_t* application);

/// Requests the application window to be repainted.
AFTERWARP_API void ApplicationInvalidate(struct Application_t* application);

/// Converts virtual key code to portable key code. Returns Key::Null if no equivalent is found.
AFTERWARP_API Key ApplicationTranslateVirtualKey(struct Application_t* application, int32_t virtualKey);

/// Converts portable key code to virtual key code. Returns 0 if no equivalent is found.
AFTERWARP_API int32_t ApplicationConvertPortableKey(struct Application_t* application, Key key);

/// Executes application's main loop (or returns "false" when there were errors during application create
/// event.
AFTERWARP_API LibraryBool ApplicationExecute(struct Application_t* application);

/// Finishes execution of the application.
AFTERWARP_API void ApplicationTerminate(struct Application_t* application);

/// Returns current application's window state.
AFTERWARP_API ApplicationWindowState ApplicationGetWindowState(struct Application_t* application);

/// Changes application's window state.
AFTERWARP_API LibraryBool ApplicationSetWindowState(struct Application_t* application,
  ApplicationWindowState windowState);

/// Attempts to read text from clipboard. Writes up to \c textSize number of characters, including
/// null-terminating character to the destination string. Updates \c textSize to reflect the actual number
/// of characters written.
AFTERWARP_API LibraryBool ApplicationReadTextFromClipboard(struct Application_t* application,
  char* text, _Inout_ int32_t* textSize);

/// Attempts to write text to clipboard.
AFTERWARP_API LibraryBool ApplicationWriteTextToClipboard(struct Application_t* application,
  char const* text);

/// Returns current application cursor.
AFTERWARP_API AppCursor ApplicationGetCursor(struct Application_t* application);

/// Changes application cursor.
AFTERWARP_API LibraryBool ApplicationSetCursor(struct Application_t* application, AppCursor cursor);

/// Captures mouse input for the application window.
AFTERWARP_API LibraryBool ApplicationCaptureMouseInput(struct Application_t* application);

/// Releases mouse input for the application window.
AFTERWARP_API LibraryBool ApplicationReleaseMouseInput(struct Application_t* application);

/// Indicates whether the mouse input is currently captured.
AFTERWARP_API LibraryBool ApplicationMouseInputCaptured(struct Application_t* application);

/// Specifies one or more application icons.
/// Note: the provided array including each of the surfaces should be released by the caller.
AFTERWARP_API LibraryBool ApplicationSetIcons(struct Application_t* application,
  struct Surface_t* const* surfaces, int32_t count);

/// Changes application icons by loading them from external files.
/// Note: this method will only work while at least one device instance currently exists.
AFTERWARP_API LibraryBool ApplicationSetIconsFromFiles(struct Application_t* application,
  char const* const* fileNames, int32_t fileNameCount);

/// Shows a file chooser dialog to pick a file for loading or saving. Starting file path, as well as
/// suggested file name are taken from "filePath". "filters" is a list of one or more filter, specified by
/// its name and extension wildcard, separated by semicolon. Multiple filters are separated by '|'.
/// An example filter would be: Wavefront OBj files (*.obj);*.obj|All files (*.*);*.*
AFTERWARP_API LibraryBool ApplicationFileChooserDialog(struct Application_t* application,
  _Inout_ char* filePath, _Inout_ int32_t* filePathLength, FileChooserDialog dialog, char const* filters,
  char const* caption, char const* accept, char const* reject);

// ActorCamera functions.

/// Creates a new instance of a camera module that can represent both first-person and third-person views
/// for 3D world exploration and object manipulation.
AFTERWARP_API struct ActorCamera_t* ActorCameraCreate(Vector const* position, Vector const* rotation,
  float distance);

/// Releases given instance of camera module.
AFTERWARP_API void ActorCameraDestroy(struct ActorCamera_t* camera);

/// Returns camera's forward vector (looking direction).
AFTERWARP_API void ActorCameraGetForward(struct ActorCamera_t* camera, Vector* forward);

/// Returns camera's right vector (sideway direction).
AFTERWARP_API void ActorCameraGetRight(struct ActorCamera_t* camera, Vector* right);

/// Returns camera's ceiling vector (up direction).
AFTERWARP_API void ActorCameraGetCeiling(struct ActorCamera_t* camera, Vector* ceiling);

/// Returns camera's position.
AFTERWARP_API void ActorCameraGetPosition(struct ActorCamera_t* camera, Vector* position);

/// Updates camera's position. Returns \c true if position has actually changed.
AFTERWARP_API LibraryBool ActorCameraSetPosition(struct ActorCamera_t* camera, Vector const* position);

/// Returns current camera rotation. "w" component is a rotation for Lenticular printing.
AFTERWARP_API void ActorCameraGetRotation(struct ActorCamera_t* camera, Vector4* rotation);

/// Sets new camera rotation. "w" component is a rotation for Lenticular printing.
/// Returns \c true if rotation has actually changed.
AFTERWARP_API LibraryBool ActorCameraSetRotation(struct ActorCamera_t* camera, Vector4 const* rotation);

/// Returns the distance between camera's position and the viewer (for third-person view).
AFTERWARP_API float ActorCameraGetDistance(struct ActorCamera_t* camera);

/// Sets the distance between camera's position and the viewer (for third-person view).
AFTERWARP_API void ActorCameraSetDistance(struct ActorCamera_t* camera, float distance);

/// Returns current camera rotation as quaternion.
AFTERWARP_API void ActorCameraGetQuaternion(struct ActorCamera_t* camera, Quaternion* quaternion);

/// Changes current camera's rotation as quaternion. Returns \c true if rotation has actually changed.
AFTERWARP_API LibraryBool ActorCameraSetQuaternion(struct ActorCamera_t* camera,
  Quaternion const* quaternion);

/// Returns camera's resulting 3D view matrix.
AFTERWARP_API void ActorCameraGetView(struct ActorCamera_t* camera, Matrix* view);

/// Changes camera's zoom by adjusting its distance and position around the specified point.
AFTERWARP_API void ActorCameraZoom(struct ActorCamera_t* camera, PointF const* position,
  PointF const* size, Matrix const* projection, float delta);

/// Adjusts camera position while performing orthographic zoom.
AFTERWARP_API void ActorCameraZoomOrtho(struct ActorCamera_t* camera, PointF const* position,
  PointF const* size, float distance, float adjustedDistance, Matrix const* projection,
  Matrix const* adjustedProjection);

/// Returns current 3D camera constraints.
AFTERWARP_API void ActorCameraGetConstraints(struct ActorCamera_t* camera, CameraConstraints* constraints);

/// Sets new 3D camera constraints.
AFTERWARP_API void ActorCameraSetConstraints(struct ActorCamera_t* camera,
  CameraConstraints const* constraints);

/// Issue a camera command for rotation/movement. Returns true if camera's position or rotation has changed.
/// For movement, "sense" defines the normal of the movement plane and "position.z" its altitude.
/// For dragging and rotation, "sense" defines sensitivity for X and Y axes respectively (Z is ignored).
/// Projection matrix is only used for movement command.
AFTERWARP_API LibraryBool ActorCameraCommand(struct ActorCamera_t* camera, CameraCommand command,
  Vector const* position, PointF const* size, Vector const* sense, Matrix const* projection);

// Timer functions.

/// Creates new instance of timer that can be used in multimedia interactive applications to ensure fixed
/// processing rate and/or variable processing rate (e.g. as fast as possible) with a fixed-rate counter.
AFTERWARP_API struct Timer_t* TimerCreate(void);

/// Releases given timer instance.
AFTERWARP_API void TimerDestroy(struct Timer_t* timer);

/// Returns currently set multimedia timer speed (in terms of frames per second).
AFTERWARP_API double TimerGetSpeed(struct Timer_t* timer);

/// Sets new multimedia timer processing speed (in terms of frames per second). Default speed is 60 frames
/// per second.
AFTERWARP_API void TimerSetSpeed(struct Timer_t* timer, double speed);

/// Ensures that next processing time slice is reached. Returns whether the method was executed within the
/// correct time slice (in other words, no timer slices have been lost, which could result in stuttering).
AFTERWARP_API LibraryBool TimerNextSlice(struct Timer_t* timer);

/// Ensures that next processing time slice is reached, updates latency and calculates average frame rate.
/// Returns whether the method was executed within the correct time slice (in other words, no timer slices
/// have been lost, which could result in stuttering). Updates fixed-rate token counter.
AFTERWARP_API LibraryBool TimerUpdateNextSlice(struct Timer_t* timer);

/// Updates latency, calculates average frame rate and updates fixed-rate token counter.
AFTERWARP_API void TimerUpdate(struct Timer_t* timer);

/// Resets internal structures of the timer, restarts the timing calculations and sets current time slice
/// to zero. This can be useful when an unscheduled and/or a time-consuming task was executed.
AFTERWARP_API void TimerReset(struct Timer_t* timer);

/// Returns calculated average frame rate in frames per second. This value is updated roughly two times
/// per second and can only be used for informative purposes (e.g. displaying frame rate in the
/// application). For precise real-time indications it is recommended to use \c TimerGetLatency().
AFTERWARP_API float TimerGetFrameRate(struct Timer_t* timer);

/// Returns time (in microseconds) calculated between previous and current frames. This can be a direct
/// indication of rendering performance as it tells how much time it took to render (and possibly, process)
/// the frame.
AFTERWARP_API uint64_t TimerGetLatency(struct Timer_t* timer);

/// Returns current time slice.
AFTERWARP_API int64_t TimerGetTimeSlice(struct Timer_t* timer);

/// Returns total number of skipped time slices.
AFTERWARP_API int64_t TimerGetSkippedTimeSlices(struct Timer_t* timer);

/// Reduces number of skipped time slices by the given quantity. If the quantity is larger than the actual
/// number of skipped time slices, resets that number to zero.
AFTERWARP_API void TimerTrimSkippedTimeSlices(struct Timer_t* timer, int64_t slicesToTrim);

/// Extracts existing fixed-rate token counter from the timer.
AFTERWARP_API int32_t TimerExtractTokens(struct Timer_t* timer);

// Widget functions.

/// Creates a new widget of the given class type (case-insensitive), assigns it requested instance name
/// (case-insensitive) and optional payload. The widget is commonly accessed by its instance name, which
/// must be unique. Possible values for "className" are: Widget, Label, Button, Edit, RadioButton, CheckBox,
/// GaugeEdit, SpinEdit, Placer, Panel, TabSheets,  Window and SketchPad.
AFTERWARP_API struct Widget_t* WidgetCreate(struct Widget_t* manager, char const* className,
  char const* instanceName, ObjectPayload payload);

/// Creates a new widget manager, which facilitates working with and rendering widgets. The widget manager
/// should be the topmost parent for all other widgets. The manager itself is also considered a widget.
AFTERWARP_API struct Widget_t* WidgetManagerCreate(struct Application_t* application,
  struct TextRenderer_t* textRenderer, char const* instanceName, ObjectPayload payload, PixelFormat format,
  int32_t multisamples, uint32_t attributes);

/// Releases an existing widget instance.
AFTERWARP_API void WidgetDestroy(struct Widget_t* widget);

/// Returns manager associated with the widget.
AFTERWARP_API struct Widget_t* WidgetGetManager(struct Widget_t* widget);

/// Returns widget's payload.
AFTERWARP_API ObjectPayload WidgetGetPayload(struct Widget_t* widget);

/// Returns widget's parent.
AFTERWARP_API struct Widget_t* WidgetGetParent(struct Widget_t* widget);

/// Changes widget's parent. When widget's parent is assigned, the parent is responsible for a lifetime of
/// the widget; that is, when a widget is released, all of its child hierarchy is released as well.
AFTERWARP_API LibraryBool WidgetSetParent(struct Widget_t* widget, struct Widget_t* parent);

/// Converts local widget position to screen coordinates.
AFTERWARP_API void WidgetLocalToScreen(struct Widget_t* widget, PointF* screenPos,
  PointF const* localPos);

/// Converts screen coordinates to local widget position.
AFTERWARP_API void WidgetScreenToLocal(struct Widget_t* widget, PointF* localPos,
  PointF const* screenPos);

/// Puts the widget on front of other widgets.
AFTERWARP_API void WidgetBringToFront(struct Widget_t* widget);

/// Puts the widget behind all other widgets.
AFTERWARP_API void WidgetSendToBack(struct Widget_t* widget);

/// Schedules widget repaint during next update cycle.
AFTERWARP_API void WidgetInvalidate(struct Widget_t* widget);

/// Schedules widget repositioning during next update cycle.
AFTERWARP_API void WidgetAccomodate(struct Widget_t* widget);

/// Updates widget and its children. \c latency must be a number of milliseconds elapsed since previous
/// call to update; this is necessary to ensure proper animations in the widgets. Returns \c true if
/// the application needs to be repainted or \c false otherwise.
AFTERWARP_API LibraryBool WidgetUpdate(struct Widget_t* widget, double latency);

/// Makes the widget receive and process mouse input.
AFTERWARP_API void WidgetAcceptMouse(struct Widget_t* widget, MouseEvent event, MouseButton button,
  PointF const* position);

/// Makes the widget receive and process keyboard input.
AFTERWARP_API void WidgetAcceptKey(struct Widget_t* widget, KeyEvent event, Key key,
  UnicodeChar charCode);

/// Returns number of existing widget's children.
AFTERWARP_API int32_t WidgetGetChildCount(struct Widget_t* widget);

/// Returns an existing widget's child with the given index.
AFTERWARP_API struct Widget_t* WidgetGetChildByIndex(struct Widget_t* widget, int32_t index);

/// Attempts to find a widget among given parent's widget children and returns its index.
/// If the given child is not found among parent's widget children, returns -1.
AFTERWARP_API int32_t WidgetGetChildIndex(struct Widget_t* widget, struct Widget_t* child);

/// Searches through children hierarchy and returns widget that is pointed by the given local position.
/// If no child is found, the same widget is returned. This is particularly useful for mouse hit test.
AFTERWARP_API struct Widget_t* WidgetFindAt(struct Widget_t* widget, PointF const* position);

/// Invokes a widget's event.
AFTERWARP_API LibraryBool WidgetInvokeEvent(struct Widget_t* widget, char const* eventName);

/// Specifies a new external event callback.
AFTERWARP_API void WidgetSetExternalEvent(struct Widget_t* widget, WidgetExternalEvent event, void* user);

/// Retrieves currently set external event callback.
AFTERWARP_API void WidgetGetExternalEvent(struct Widget_t* widget, WidgetExternalEvent* event, void** user);

/// Creates a new property value or updates an existing property value. If \c value is \c NULL, an existing
/// property will be deleted.
AFTERWARP_API LibraryBool WidgetSetProperty(struct Widget_t* widget, char const* propertyName,
  WidgetPropertyType valueType, void const* value, LibraryBool invokeChanged);

/// Retrieves an existing property and performs type conversion (if possible). This function will not work
/// for string type of data, for which \c WidgetGetPropertyAsString should be used instead.
AFTERWARP_API LibraryBool WidgetGetProperty(struct Widget_t* widget, char const* propertyName,
  WidgetPropertyType valueType, void* value);

/// Returns an existing property as string. The pointed value of \c valueLength defines the maximum number of
/// characters, including null-terminating character, that can be copied. The actual string length is stored
/// in \c valueLength.
AFTERWARP_API LibraryBool WidgetGetPropertyAsString(struct Widget_t* widget, char const* propertyName,
  char* value, _Inout_ int32_t* valueLength);

/// Returns number of existing properties.
AFTERWARP_API int32_t WidgetGetPropertyCount(struct Widget_t* widget);

/// Returns name, type, behavior and possibly a value of an existing property. If property name is provided,
/// the property is looked by its name. If location is provided, information about the property at that
/// location is retrieved and location is updated to point to next entry from the list of existing
/// properties. If the property name and location are not provided, then a first property is retrieved and
/// location is updated to point to the next one. When the last property is retrieved from the list,
/// the returned location will be set to "undefined". The contents of the property are also retrieved, unless
/// it is a string that is long enough not to fit within 182 characters, in which case string length will be
/// set to 255 with remaining data bytes set to zero; in this case, the string has to be retrieved
/// using \c WidgetGetPropertyAsString function.
AFTERWARP_API LibraryBool WidgetPropertyIdentify(struct Widget_t* widget, _Inout_ WidgetProperty* property);

// Functions that can only be called on a widget manager.

/// Returns application associated with the widget manager.
AFTERWARP_API struct Application_t* WidgetManagerGetApplication(struct Widget_t* widget);

/// Returns application associated with the widget manager.
AFTERWARP_API struct TextRenderer_t* WidgetManagerGetTextRenderer(struct Widget_t* widget);

/// Returns an existing widget with the given name (case-insensitive).
AFTERWARP_API struct Widget_t* WidgetManagerGetWidgetByName(struct Widget_t* widget, char const* name);

/// Returns an existing widget with the given payload.
AFTERWARP_API struct Widget_t* WidgetManagerGetWidgetByPayload(struct Widget_t* widget, ObjectPayload payload);

/// Renders widget manager's area and all controls within.
AFTERWARP_API LibraryBool WidgetManagerPresent(struct Widget_t* widget);

/// Returns one of textures used for the composition.
AFTERWARP_API struct Texture_t* WidgetManagerGetTexture(struct Widget_t* widget,
  WidgetManagerTextureType textureType);

/// Returns total number of canvas batches during UI rendering.
AFTERWARP_API int32_t WidgetManagerBatchCount(struct Widget_t* widget);

/// Returns pixel format of composition textures.
AFTERWARP_API PixelFormat WidgetManagerGetFormat(struct Widget_t* widget);

/// Returns multisamples of rendering composition texture.
AFTERWARP_API int32_t WidgetManagerGetMultisamples(struct Widget_t* widget);

/// Returns attributes used when the manager was created.
AFTERWARP_API uint32_t WidgetManagerGetAttributes(struct Widget_t* widget);

// RandomSequence functions.

/// Initializes random number generator state using local time.
AFTERWARP_API void RandomSequenceInit(_Out_ uint64_t* state);

/// Initializes random number generator state with a given seed to generate a reproducible sequence of
/// random numbers.
AFTERWARP_API void RandomSequenceInitBySeed(_Out_ uint64_t* state, uint64_t seed);

/// Generates next random number in the sequence from the specified context.
AFTERWARP_API uint32_t RandomSequenceGenerate(_Inout_ uint64_t* state);

/// Returns 64-bit random number by generating two 32-bit numbers.
AFTERWARP_API uint64_t RandomSequenceGenerate64(_Inout_ uint64_t* state);

/// Generates a random value in range [0, 1) with 23 bits of precision, using relatively linear distribution.
AFTERWARP_API float RandomSequenceGenerateFloat(_Inout_ uint64_t* state);

/// Generates a random value in range [0, 1) with 53 bits of precision, using relatively linear distribution.
AFTERWARP_API double RandomSequenceGenerateDouble(_Inout_ uint64_t* state);

/// Generates a random value in range [0, Range) using relatively linear distribution.
AFTERWARP_API int32_t RandomSequenceGenerateRanged(_Inout_ uint64_t* state, int32_t range);

/// Generates a random value using Gaussian distribution with mean 0 and standard deviation of 1.
AFTERWARP_API float RandomSequenceGenerateGaussian(_Inout_ uint64_t* state);

// Ray functions.

/// Constructs a ray's origin and direction from the given 2D surface position, surface size, inverse of
/// the 3D view matrix and the projection matrix.
AFTERWARP_API void RayCreate(Vector* origin, Vector* direction, PointF const* position,
  PointF const* surfaceSize, Matrix const* viewInverse, Matrix const* projection);

/// Tests whether the current ray intersects with the given front or back facing triangle and if so,
/// calculates the resulting barycentric coordinates and distance from origin to triangle.
AFTERWARP_API LibraryBool RayIntersectTriangle(Vector const* origin, Vector const* direction,
  Vector const* vertex1, Vector const* vertex2, Vector const* vertex3, LibraryBool backFacing,
  PointF* intersection, float* distance);

/// Tests whether the current ray intersects with one of triangles of minimalistic cube volume, whose
/// vertices are first transformed by the given world matrix, returning distance to intersection point.
AFTERWARP_API LibraryBool RayIntersectCubeVolume(Vector const* origin, Vector const* direction,
  Matrix const* world, float* distance);

/// Tests whether the current ray intersects with a plane specified by a point on the plane and its surface
/// normal, returning the actual point of intersection and distance from ray's origin.
AFTERWARP_API LibraryBool RayIntersectPlane(Vector const* origin, Vector const* direction,
  Vector const* planePoint, Vector const* planeNormal, Vector* intersection, float* distance);

// PixelFormat functions.

/// Verifies that given pixel format is well-defined, known and valid.
AFTERWARP_API LibraryBool PixelFormatValid(PixelFormat format);

/// Returns number of bits that each pixel in current format occupies.
AFTERWARP_API uint32_t PixelFormatBits(PixelFormat format);

/// Converts a single pixel from one pixel format to another preserving as much information as possible.
AFTERWARP_API void PixelFormatConvert(void* dest, void const* source, PixelFormat destFormat,
  PixelFormat sourceFormat);

/// Converts an array of pixels from one pixel format to another preserving as much information as possible.
AFTERWARP_API void PixelFormatConvertArray(void* dest, void const* source, PixelFormat destFormat,
  PixelFormat sourceFormat, uint32_t destPitch, uint32_t sourcePitch, int32_t width, int32_t height);

// Color functions.

/// Creates 32-bit RGBA color with the specified color value, having its alpha-channel multiplied by the
/// specified coefficient and divided by 255. \c alpha must be within [0, 255] range.
AFTERWARP_API Color MakeColor(Color color, int32_t alpha);

/// Creates 32-bit RGBA color where the specified color value has its alpha-channel multiplied by the given
/// coefficient. \c alpha must be within [0, 1] range.
AFTERWARP_API Color MakeColorF(Color color, float alpha);

/// Creates 32-bit RGBA color where the original color value has its components multiplied by the given
/// grayscale value and alpha-channel multiplied by the specified coefficient, and all components divided
/// by 255. \c gray and \c alpha must be in range of [0, 255].
AFTERWARP_API Color MakeColorWithGray(Color color, int32_t gray, int32_t alpha);

/// Creates 32-bit RGBA color where the original color value has its components multiplied by the given
/// grayscale value and alpha-channel multiplied by the specified coefficient. \c gray and \c alpha must be
/// within [0, 1] range.
AFTERWARP_API Color MakeColorWithGrayF(Color color, float gray, float alpha);

/// Creates 32-bit RGBA color using specified individual integer components for red, green, blue and
/// alpha-channel. All parameters must be within [0, 255] range.
AFTERWARP_API Color MakeColorRGB(int32_t red, int32_t green, int32_t blue, int32_t alpha);

/// Creates 32-bit RGBA color using specified individual floating-point components for red, green, blue
/// and alpha-channel. All parameters must be within [0, 1] range.
AFTERWARP_API Color MakeColorRGBF(float red, float green, float blue, float alpha);

/// Creates 32-bit RGBA color using specified grayscale and alpha values. \c gray and \c alpha must be
/// within [0, 255] range.
AFTERWARP_API Color MakeColorGray(int32_t gray, int32_t alpha);

/// Creates 32-bit RGBA color using specified grayscale and alpha-channel values (both multiplied by 255).
/// \c gray and \c alpha must be within [0, 1] range.
AFTERWARP_API Color MakeColorGrayF(float gray, float alpha);

/// Creates 32-bit RGBA color with the specified alpha-channel and each of red, green and blue components
/// set to 255. \c alpha must be within [0, 255] range.
AFTERWARP_API Color MakeColorAlpha(int32_t alpha);

/// Creates 32-bit RGBA color with alpha-channel specified by the given coefficient (multiplied by 255) and
/// the rest of components set to 255. \c alpha must be within [0, 1] range.
AFTERWARP_API Color MakeColorAlphaF(float alpha);

/// Returns alpha-channel in range [0, 255] for the given 32-bit RGBA color.
AFTERWARP_API int32_t GetColorAlpha(Color color);

/// Returns alpha-channel in range [0, 1] for the given 32-bit RGBA color.
AFTERWARP_API float GetColorAlphaF(Color color);

/// Takes 32-bit RGBA color with unpremultiplied alpha and multiplies each of red, green, and blue
/// components by its alpha-channel, resulting in premultiplied alpha color.
AFTERWARP_API Color PremultiplyAlpha(Color color);

/// Takes 32-bit RGBA color with premultiplied alpha channel and divides each of its red, green, and blue
/// components by alpha, resulting in unpremultiplied alpha color.
AFTERWARP_API Color UnpremultiplyAlpha(Color color);

/// Switches red and blue channels in 32-bit RGBA color value.
AFTERWARP_API Color DisplaceRB(Color color);

/// Inverts each of the components in the color, including alpha-channel.
AFTERWARP_API Color InvertColor(Color color);

/// Adds two 32-bit RGBA color values together clamping the resulting values.
AFTERWARP_API Color AddColors(Color color1, Color color2);

/// Subtracts two 32-bit RGBA color values clamping the resulting values.
AFTERWARP_API Color SubtractColors(Color color1, Color color2);

/// Multiplies two 32-bit RGBA color values together.
AFTERWARP_API Color MultiplyColors(Color color1, Color color2);

/// Computes average of two given 32-bit RGBA color values.
AFTERWARP_API Color AverageColors(Color color1, Color color2);

/// Computes average of four given 32-bit RGBA color values.
AFTERWARP_API Color AverageFourColors(Color color1, Color color2, Color color3, Color color4);

/// Computes average of six given 32-bit RGBA color values.
AFTERWARP_API Color AverageSixColors(Color color1, Color color2, Color color3, Color color4, Color color5,
  Color color6);

/// Computes alpha-blending for a pair of 32-bit RGBA colors values.
/// \c alpha must be in [0..255] range.
AFTERWARP_API Color BlendColors(Color color1, Color color2, int32_t alpha);

/// Computes resulting alpha-blended value between four 32-bit RGBA colors using linear interpolation.
/// \c alphaX and \c alphaY must be in [0..255] range. \c horizontal determines first axis to interpolate.
AFTERWARP_API Color BlendFourColors(Color topLeft, Color topRight, Color bottomRight, Color bottomLeft,
  int32_t alphaX, int32_t alphaY, LibraryBool horizontal);

/// Composes source color onto destination color using source and destination color alphas. This essentially
/// means alpha-blending source color onto destination using source's alpha, but with appropriate alpha
/// composition.
AFTERWARP_API Color ComposeColors(Color source, Color dest);

/// Returns grayscale value in range of [0..255] from the given 32-bit RGBA color value. The resulting value
/// can be considered the color's \c Luma. The alpha-channel is ignored.
AFTERWARP_API int32_t ColorToGray(Color color);

/// Returns grayscale value in range of [0..65535] from the given 32-bit RGBA color value. The resulting
/// value can be considered the color's \c Luma. The alpha-channel is ignored.
AFTERWARP_API int32_t ColorToGray16(Color color);

/// Returns grayscale value in range of [0, 1] from the given 32-bit RGBA color value. The resulting value
/// can be considered the color's \c Luma. The alpha-channel is ignored.
AFTERWARP_API float ColorToGrayF(Color color);

// Interpolation functions.

/// Interpolates between two values linearly, where theta parameter is specified in [0, 1] range.
AFTERWARP_API float Lerp(float value1, float value2, float theta);

/// Interpolates between four values using cubic spline, where theta parameter is specified in [0, 1] range.
AFTERWARP_API float Cubic(float predValue1, float value1, float value2, float succValue2, float theta);

/// Interpolates between four values using Catmull-Rom spline, where theta parameter is specified
/// in [0, 1] range.
AFTERWARP_API float CatmullRom(float predValue1, float value1, float value2, float succValue2, float theta);

/// Interpolates between four values using Hermite spline, where theta parameter is specified in [0, 1]
/// range, tension in [-1, 1] range (from low to high) and bias in (-inf, +inf) range: negative towards the
/// second element, positive towards the first one.
AFTERWARP_API float Hermite(float predValue1, float value1, float value2, float succValue2, float theta,
  float tension, float bias);

/// Interpolates between two values using simplified Hermite curve after applying saturation, where theta
/// parameter is specified in [0, 1] range.
AFTERWARP_API float SmoothStep(float value1, float value2, float theta);

/// Interpolates between two values using Hermite curve after applying saturation, where theta parameter is
/// specified in [0, 1] range. This uses Perlin's improvement, where 1st and 2nd order derivatives at
/// positions 0 and 1 are zero.
AFTERWARP_API float SmootherStep(float value1, float value2, float theta);

/// Transforms value in range of [0, 1] by using sine wave (kind of "accelerate then decelerate").
AFTERWARP_API float SineTransform(float value);

/// Transforms value in range of [0, 1] using "accelerating" sine wave. The curve starts at zero with
/// almost no "velocity", while in the end incrementing almost linearly.
AFTERWARP_API float SineAccelerate(float value);

/// Transforms value in range of [0, 1] using "decelerating" sine wave. The curve starts at zero,
/// incrementing almost linearily, while in the end going to almost a complete stop.
AFTERWARP_API float SineDecelerate(float value);

/// Transforms value in range of [0, 1] to go through full sine curve in range [0 -> 1 -> 0].
/// Note that the curve goes from zero to one and then back to zero.
AFTERWARP_API float SineCycle(float value);

/// Transforms value in range of [0, 1] to go full cycle through sine function (0 -> 1 -> 0 -> -1 -> 0).
AFTERWARP_API float SineTwoCycle(float value);

/// Transforms value in range of [0, 1] with a power function, adding bias to either start of the curve or
/// its end. Bias value of 0.25 would be similar to SineAccelerate(), whereas value of 0.75 would be similar
/// to that of SineDecelerate().
AFTERWARP_API float BiasTransform(float value, float bias);

/// Transforms value in range of [0, 1] with a power function, adding gain at start and end of the curve,
/// similar to SineTransform(). Values of "gain" closer to zero produce stronger distortions, whereas values
/// close to zero produce almost linear curves.
AFTERWARP_API float GainTransform(float value, float gain);

// Service functions.

/// Creates a model transformation matrix that centers the mesh and places it on top of zero plane.
AFTERWARP_API void MeshBoundsToMatrixModel(Matrix* model, Vector const* minBounds, Vector const* maxBounds,
  MeshAligns const* aligns, float scale);

/// Creates a volume transformation matrix that centers the mesh and places it on top of zero plane.
AFTERWARP_API void MeshBoundsToMatrixVolume(Matrix* volume, Vector const* minBounds, Vector const* maxBounds,
  MeshAligns const* aligns, float scale);

/// Calculates an offset to displace from mesh to tag origin.
AFTERWARP_API void MeshBoundsTagOffset(Vector const* meshMinBounds, Vector const* meshMaxBounds,
  Vector const* tagMinBounds, Vector const* tagMaxBounds, Vector* offset);

/// Creates a volume transformation matrix that centers the mesh tag inside mesh volume.
AFTERWARP_API void MeshBoundsToMatrixVolumeTag(Vector const* meshMinBounds, Vector const* meshMaxBounds,
  Vector const* tagMinBounds, Vector const* tagMaxBounds, Matrix* volume, float sizeBias);

/// Calculates near and far planes for a bounding box transformed by the given world/view matrix.
AFTERWARP_API void VolumeCalculateNearFarPlanes(Matrix const* worldView, float* nearPlane, float* farPlane);

/// Calculates visible surface frame for a bounding box transformed by the given world/view/projection matrix.
AFTERWARP_API void VolumeCalculateVisibleFrame(Matrix const* worldViewProjection, PointF const* surfaceSize,
  RectF* visibleFrame);

/// Makes an estimation of pitch for the given channel based on existing element offsets.
AFTERWARP_API uint32_t VertexElementsEstimatePitch(uint32_t channel, VertexElement const vertexElements[],
  int32_t vertexElementCount);

/// Retrieves number of microseconds that passed since application startup.
AFTERWARP_API uint64_t GetSystemTicks(void);

#ifdef __cplusplus
  } // extern "C"
#endif