add toggle for postprocessing and minor cleanup work

This commit is contained in:
Nick Fisher
2023-10-03 22:04:37 +08:00
parent d49b43c191
commit c1f8eae85e
189 changed files with 568 additions and 146 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,850 @@
#ifndef __wglext_h_
#define __wglext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2017 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** https://github.com/KhronosGroup/OpenGL-Registry
*/
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#define WGL_WGLEXT_VERSION 20171125
/* Generated C header for:
* API: wgl
* Versions considered: .*
* Versions emitted: _nomatch_^
* Default extensions included: wgl
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef WGL_ARB_buffer_region
#define WGL_ARB_buffer_region 1
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#ifdef WGL_WGLEXT_PROTOTYPES
HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
#endif
#endif /* WGL_ARB_buffer_region */
#ifndef WGL_ARB_context_flush_control
#define WGL_ARB_context_flush_control 1
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#endif /* WGL_ARB_context_flush_control */
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define ERROR_INVALID_VERSION_ARB 0x2095
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#ifdef WGL_WGLEXT_PROTOTYPES
HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
#endif /* WGL_ARB_create_context */
#ifndef WGL_ARB_create_context_no_error
#define WGL_ARB_create_context_no_error 1
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
#endif /* WGL_ARB_create_context_no_error */
#ifndef WGL_ARB_create_context_profile
#define WGL_ARB_create_context_profile 1
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_PROFILE_ARB 0x2096
#endif /* WGL_ARB_create_context_profile */
#ifndef WGL_ARB_create_context_robustness
#define WGL_ARB_create_context_robustness 1
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#endif /* WGL_ARB_create_context_robustness */
#ifndef WGL_ARB_extensions_string
#define WGL_ARB_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringARB (HDC hdc);
#endif
#endif /* WGL_ARB_extensions_string */
#ifndef WGL_ARB_framebuffer_sRGB
#define WGL_ARB_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#endif /* WGL_ARB_framebuffer_sRGB */
#ifndef WGL_ARB_make_current_read
#define WGL_ARB_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCARB (void);
#endif
#endif /* WGL_ARB_make_current_read */
#ifndef WGL_ARB_multisample
#define WGL_ARB_multisample 1
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif /* WGL_ARB_multisample */
#ifndef WGL_ARB_pbuffer
#define WGL_ARB_pbuffer 1
DECLARE_HANDLE(HPBUFFERARB);
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_ARB_pbuffer */
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_ARB_pixel_format */
#ifndef WGL_ARB_pixel_format_float
#define WGL_ARB_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif /* WGL_ARB_pixel_format_float */
#ifndef WGL_ARB_render_texture
#define WGL_ARB_render_texture 1
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
#endif
#endif /* WGL_ARB_render_texture */
#ifndef WGL_ARB_robustness_application_isolation
#define WGL_ARB_robustness_application_isolation 1
#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
#endif /* WGL_ARB_robustness_application_isolation */
#ifndef WGL_ARB_robustness_share_group_isolation
#define WGL_ARB_robustness_share_group_isolation 1
#endif /* WGL_ARB_robustness_share_group_isolation */
#ifndef WGL_3DFX_multisample
#define WGL_3DFX_multisample 1
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
#define WGL_SAMPLES_3DFX 0x2061
#endif /* WGL_3DFX_multisample */
#ifndef WGL_3DL_stereo_control
#define WGL_3DL_stereo_control 1
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
#endif
#endif /* WGL_3DL_stereo_control */
#ifndef WGL_AMD_gpu_association
#define WGL_AMD_gpu_association 1
#define WGL_GPU_VENDOR_AMD 0x1F00
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
#define WGL_GPU_RAM_AMD 0x21A3
#define WGL_GPU_CLOCK_AMD 0x21A4
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
#define WGL_GPU_NUM_RB_AMD 0x21A7
#define WGL_GPU_NUM_SPI_AMD 0x21A8
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#ifdef WGL_WGLEXT_PROTOTYPES
UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
#endif
#endif /* WGL_AMD_gpu_association */
#ifndef WGL_ATI_pixel_format_float
#define WGL_ATI_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
#endif /* WGL_ATI_pixel_format_float */
#ifndef WGL_EXT_colorspace
#define WGL_EXT_colorspace 1
#define WGL_COLORSPACE_EXT 0x3087
#define WGL_COLORSPACE_SRGB_EXT 0x3089
#define WGL_COLORSPACE_LINEAR_EXT 0x308A
#endif /* WGL_EXT_colorspace */
#ifndef WGL_EXT_create_context_es2_profile
#define WGL_EXT_create_context_es2_profile 1
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es2_profile */
#ifndef WGL_EXT_create_context_es_profile
#define WGL_EXT_create_context_es_profile 1
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
#endif /* WGL_EXT_create_context_es_profile */
#ifndef WGL_EXT_depth_float
#define WGL_EXT_depth_float 1
#define WGL_DEPTH_FLOAT_EXT 0x2040
#endif /* WGL_EXT_depth_float */
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
#ifdef WGL_WGLEXT_PROTOTYPES
GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
#endif
#endif /* WGL_EXT_display_color_table */
#ifndef WGL_EXT_extensions_string
#define WGL_EXT_extensions_string 1
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
const char *WINAPI wglGetExtensionsStringEXT (void);
#endif
#endif /* WGL_EXT_extensions_string */
#ifndef WGL_EXT_framebuffer_sRGB
#define WGL_EXT_framebuffer_sRGB 1
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif /* WGL_EXT_framebuffer_sRGB */
#ifndef WGL_EXT_make_current_read
#define WGL_EXT_make_current_read 1
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
HDC WINAPI wglGetCurrentReadDCEXT (void);
#endif
#endif /* WGL_EXT_make_current_read */
#ifndef WGL_EXT_multisample
#define WGL_EXT_multisample 1
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
#define WGL_SAMPLES_EXT 0x2042
#endif /* WGL_EXT_multisample */
#ifndef WGL_EXT_pbuffer
#define WGL_EXT_pbuffer 1
DECLARE_HANDLE(HPBUFFEREXT);
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
#define WGL_PBUFFER_LARGEST_EXT 0x2033
#define WGL_PBUFFER_WIDTH_EXT 0x2034
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
#endif
#endif /* WGL_EXT_pbuffer */
#ifndef WGL_EXT_pixel_format
#define WGL_EXT_pixel_format 1
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
#define WGL_ACCELERATION_EXT 0x2003
#define WGL_NEED_PALETTE_EXT 0x2004
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
#define WGL_SWAP_METHOD_EXT 0x2007
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
#define WGL_TRANSPARENT_EXT 0x200A
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
#define WGL_SHARE_DEPTH_EXT 0x200C
#define WGL_SHARE_STENCIL_EXT 0x200D
#define WGL_SHARE_ACCUM_EXT 0x200E
#define WGL_SUPPORT_GDI_EXT 0x200F
#define WGL_SUPPORT_OPENGL_EXT 0x2010
#define WGL_DOUBLE_BUFFER_EXT 0x2011
#define WGL_STEREO_EXT 0x2012
#define WGL_PIXEL_TYPE_EXT 0x2013
#define WGL_COLOR_BITS_EXT 0x2014
#define WGL_RED_BITS_EXT 0x2015
#define WGL_RED_SHIFT_EXT 0x2016
#define WGL_GREEN_BITS_EXT 0x2017
#define WGL_GREEN_SHIFT_EXT 0x2018
#define WGL_BLUE_BITS_EXT 0x2019
#define WGL_BLUE_SHIFT_EXT 0x201A
#define WGL_ALPHA_BITS_EXT 0x201B
#define WGL_ALPHA_SHIFT_EXT 0x201C
#define WGL_ACCUM_BITS_EXT 0x201D
#define WGL_ACCUM_RED_BITS_EXT 0x201E
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
#define WGL_DEPTH_BITS_EXT 0x2022
#define WGL_STENCIL_BITS_EXT 0x2023
#define WGL_AUX_BUFFERS_EXT 0x2024
#define WGL_NO_ACCELERATION_EXT 0x2025
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
#define WGL_FULL_ACCELERATION_EXT 0x2027
#define WGL_SWAP_EXCHANGE_EXT 0x2028
#define WGL_SWAP_COPY_EXT 0x2029
#define WGL_SWAP_UNDEFINED_EXT 0x202A
#define WGL_TYPE_RGBA_EXT 0x202B
#define WGL_TYPE_COLORINDEX_EXT 0x202C
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
#endif
#endif /* WGL_EXT_pixel_format */
#ifndef WGL_EXT_pixel_format_packed_float
#define WGL_EXT_pixel_format_packed_float 1
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
#endif /* WGL_EXT_pixel_format_packed_float */
#ifndef WGL_EXT_swap_control
#define WGL_EXT_swap_control 1
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglSwapIntervalEXT (int interval);
int WINAPI wglGetSwapIntervalEXT (void);
#endif
#endif /* WGL_EXT_swap_control */
#ifndef WGL_EXT_swap_control_tear
#define WGL_EXT_swap_control_tear 1
#endif /* WGL_EXT_swap_control_tear */
#ifndef WGL_I3D_digital_video_control
#define WGL_I3D_digital_video_control 1
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
#endif
#endif /* WGL_I3D_digital_video_control */
#ifndef WGL_I3D_gamma
#define WGL_I3D_gamma 1
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
#endif
#endif /* WGL_I3D_gamma */
#ifndef WGL_I3D_genlock
#define WGL_I3D_genlock 1
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
#endif
#endif /* WGL_I3D_genlock */
#ifndef WGL_I3D_image_buffer
#define WGL_I3D_image_buffer 1
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
#ifdef WGL_WGLEXT_PROTOTYPES
LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
#endif
#endif /* WGL_I3D_image_buffer */
#ifndef WGL_I3D_swap_frame_lock
#define WGL_I3D_swap_frame_lock 1
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnableFrameLockI3D (void);
BOOL WINAPI wglDisableFrameLockI3D (void);
BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
#endif
#endif /* WGL_I3D_swap_frame_lock */
#ifndef WGL_I3D_swap_frame_usage
#define WGL_I3D_swap_frame_usage 1
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
BOOL WINAPI wglBeginFrameTrackingI3D (void);
BOOL WINAPI wglEndFrameTrackingI3D (void);
BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
#endif
#endif /* WGL_I3D_swap_frame_usage */
#ifndef WGL_NV_DX_interop
#define WGL_NV_DX_interop 1
#define WGL_ACCESS_READ_ONLY_NV 0x00000000
#define WGL_ACCESS_READ_WRITE_NV 0x00000001
#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
#endif
#endif /* WGL_NV_DX_interop */
#ifndef WGL_NV_DX_interop2
#define WGL_NV_DX_interop2 1
#endif /* WGL_NV_DX_interop2 */
#ifndef WGL_NV_copy_image
#define WGL_NV_copy_image 1
typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
#endif
#endif /* WGL_NV_copy_image */
#ifndef WGL_NV_delay_before_swap
#define WGL_NV_delay_before_swap 1
typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds);
#endif
#endif /* WGL_NV_delay_before_swap */
#ifndef WGL_NV_float_buffer
#define WGL_NV_float_buffer 1
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
#endif /* WGL_NV_float_buffer */
#ifndef WGL_NV_gpu_affinity
#define WGL_NV_gpu_affinity 1
DECLARE_HANDLE(HGPUNV);
struct _GPU_DEVICE {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD Flags;
RECT rcVirtualScreen;
};
typedef struct _GPU_DEVICE *PGPU_DEVICE;
#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
BOOL WINAPI wglDeleteDCNV (HDC hdc);
#endif
#endif /* WGL_NV_gpu_affinity */
#ifndef WGL_NV_multisample_coverage
#define WGL_NV_multisample_coverage 1
#define WGL_COVERAGE_SAMPLES_NV 0x2042
#define WGL_COLOR_SAMPLES_NV 0x20B9
#endif /* WGL_NV_multisample_coverage */
#ifndef WGL_NV_present_video
#define WGL_NV_present_video 1
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
#ifdef WGL_WGLEXT_PROTOTYPES
int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
#endif
#endif /* WGL_NV_present_video */
#ifndef WGL_NV_render_depth_texture
#define WGL_NV_render_depth_texture 1
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
#define WGL_DEPTH_COMPONENT_NV 0x20A7
#endif /* WGL_NV_render_depth_texture */
#ifndef WGL_NV_render_texture_rectangle
#define WGL_NV_render_texture_rectangle 1
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
#endif /* WGL_NV_render_texture_rectangle */
#ifndef WGL_NV_swap_group
#define WGL_NV_swap_group 1
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
BOOL WINAPI wglResetFrameCountNV (HDC hDC);
#endif
#endif /* WGL_NV_swap_group */
#ifndef WGL_NV_vertex_array_range
#define WGL_NV_vertex_array_range 1
typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
#ifdef WGL_WGLEXT_PROTOTYPES
void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
void WINAPI wglFreeMemoryNV (void *pointer);
#endif
#endif /* WGL_NV_vertex_array_range */
#ifndef WGL_NV_video_capture
#define WGL_NV_video_capture 1
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
#define WGL_UNIQUE_ID_NV 0x20CE
#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
#endif
#endif /* WGL_NV_video_capture */
#ifndef WGL_NV_video_output
#define WGL_NV_video_output 1
DECLARE_HANDLE(HPVIDEODEV);
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
#define WGL_VIDEO_OUT_FRAME 0x20C8
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
#endif
#endif /* WGL_NV_video_output */
#ifndef WGL_OML_sync_control
#define WGL_OML_sync_control 1
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#ifdef WGL_WGLEXT_PROTOTYPES
BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
#endif
#endif /* WGL_OML_sync_control */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,2 @@
DisableFormat: true
SortIncludes: false

View File

@@ -0,0 +1,290 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_ACQUIREDIMAGE_H
#define TNT_FILAMENT_BACKEND_PRIVATE_ACQUIREDIMAGE_H
#include <backend/DriverEnums.h>
namespace filament::backend {
class CallbackHandler;
// This lightweight POD allows us to bundle the state required to process an ACQUIRED stream.
// Since these types of external images need to be moved around and queued up, an encapsulation is
// very useful.
struct AcquiredImage {
void* image = nullptr;
backend::StreamCallback callback = nullptr;
void* userData = nullptr;
CallbackHandler* handler = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_ACQUIREDIMAGE_H

View File

@@ -0,0 +1,223 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
#define TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
#include <utils/compiler.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class CallbackHandler;
/**
* A CPU memory-buffer descriptor, typically used to transfer data from the CPU to the GPU.
*
* A BufferDescriptor owns the memory buffer it references, therefore BufferDescriptor cannot
* be copied, but can be moved.
*
* BufferDescriptor releases ownership of the memory-buffer when it's destroyed.
*/
class UTILS_PUBLIC BufferDescriptor {
public:
/**
* Callback used to destroy the buffer data.
* Guarantees:
* Called on the main filament thread.
*
* Limitations:
* Must be lightweight.
* Must not call filament APIs.
*/
using Callback = void(*)(void* buffer, size_t size, void* user);
//! creates an empty descriptor
BufferDescriptor() noexcept = default;
//! calls the callback to advertise BufferDescriptor no-longer owns the buffer
~BufferDescriptor() noexcept {
if (mCallback) {
mCallback(buffer, size, mUser);
}
}
BufferDescriptor(const BufferDescriptor& rhs) = delete;
BufferDescriptor& operator=(const BufferDescriptor& rhs) = delete;
BufferDescriptor(BufferDescriptor&& rhs) noexcept
: buffer(rhs.buffer), size(rhs.size),
mCallback(rhs.mCallback), mUser(rhs.mUser), mHandler(rhs.mHandler) {
rhs.buffer = nullptr;
rhs.mCallback = nullptr;
}
BufferDescriptor& operator=(BufferDescriptor&& rhs) noexcept {
if (this != &rhs) {
buffer = rhs.buffer;
size = rhs.size;
mCallback = rhs.mCallback;
mUser = rhs.mUser;
mHandler = rhs.mHandler;
rhs.buffer = nullptr;
rhs.mCallback = nullptr;
}
return *this;
}
/**
* Creates a BufferDescriptor that references a CPU memory-buffer
* @param buffer Memory address of the CPU buffer to reference
* @param size Size of the CPU buffer in bytes
* @param callback A callback used to release the CPU buffer from this BufferDescriptor
* @param user An opaque user pointer passed to the callback function when it's called
*/
BufferDescriptor(void const* buffer, size_t size,
Callback callback = nullptr, void* user = nullptr) noexcept
: buffer(const_cast<void*>(buffer)), size(size), mCallback(callback), mUser(user) {
}
/**
* Creates a BufferDescriptor that references a CPU memory-buffer
* @param buffer Memory address of the CPU buffer to reference
* @param size Size of the CPU buffer in bytes
* @param callback A callback used to release the CPU buffer from this BufferDescriptor
* @param user An opaque user pointer passed to the callback function when it's called
*/
BufferDescriptor(void const* buffer, size_t size,
CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept
: buffer(const_cast<void*>(buffer)), size(size),
mCallback(callback), mUser(user), mHandler(handler) {
}
// --------------------------------------------------------------------------------------------
/**
* Helper to create a BufferDescriptor that uses a KNOWN method pointer w/ object passed
* by pointer as the callback. e.g.:
* auto bd = BufferDescriptor::make(buffer, size, &Foo::method, foo);
*
* @param buffer Memory address of the CPU buffer to reference
* @param size Size of the CPU buffer in bytes
* @param handler Handler to use to dispatch the callback, or nullptr for the default handler
* @return a new BufferDescriptor
*/
template<typename T, void(T::*method)(void const*, size_t)>
static BufferDescriptor make(
void const* buffer, size_t size, T* data, CallbackHandler* handler = nullptr) noexcept {
return {
buffer, size,
handler, [](void* b, size_t s, void* u) {
(*static_cast<T**>(u)->*method)(b, s);
}, data
};
}
/**
* Helper to create a BufferDescriptor that uses a functor as the callback.
*
* Caveats:
* - DO NOT CALL setCallback() when using this helper.
* - This make a heap allocation
*
* @param buffer Memory address of the CPU buffer to reference
* @param size Size of the CPU buffer in bytes
* @param functor functor of type f(void const* buffer, size_t size)
* @param handler Handler to use to dispatch the callback, or nullptr for the default handler
* @return a new BufferDescriptor
*/
template<typename T>
static BufferDescriptor make(
void const* buffer, size_t size, T&& functor, CallbackHandler* handler = nullptr) noexcept {
return {
buffer, size,
handler, [](void* b, size_t s, void* u) {
T& that = *static_cast<T*>(u);
that(b, s);
delete &that;
},
new T(std::forward<T>(functor))
};
}
// --------------------------------------------------------------------------------------------
/**
* Set or replace the release callback function
* @param callback The new callback function
* @param user An opaque user pointer passed to the callbeck function when it's called
*/
void setCallback(Callback callback, void* user = nullptr) noexcept {
this->mCallback = callback;
this->mUser = user;
this->mHandler = nullptr;
}
/**
* Set or replace the release callback function
* @param handler The Handler to use to dispatch the callback
* @param callback The new callback function
* @param user An opaque user pointer passed to the callbeck function when it's called
*/
void setCallback(CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept {
mCallback = callback;
mUser = user;
mHandler = handler;
}
//! Returns whether a release callback is set
bool hasCallback() const noexcept { return mCallback != nullptr; }
//! Returns the currently set release callback function
Callback getCallback() const noexcept {
return mCallback;
}
//! Returns the handler for this callback or nullptr if the default handler is to be used.
CallbackHandler* getHandler() const noexcept {
return mHandler;
}
//! Returns the user opaque pointer associated to this BufferDescriptor
void* getUser() const noexcept {
return mUser;
}
//! CPU mempry-buffer virtual address
void* buffer = nullptr;
//! CPU memory-buffer size in bytes
size_t size = 0;
private:
// callback when the buffer is consumed.
Callback mCallback = nullptr;
void* mUser = nullptr;
CallbackHandler* mHandler = nullptr;
};
} // namespace filament::backend
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::BufferDescriptor& b);
#endif
#endif // TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#define TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#include <utils/compiler.h>
namespace filament::backend {
/**
* A generic interface to dispatch callbacks.
*
* All APIs that take a callback as argument also take a
* CallbackHandler* which is used to dispatch the
* callback: CallbackHandler::post() method is called from a service thread as soon
* as possible (this will NEVER be the main thread), CallbackHandler::post()
* is responsible for scheduling the callback onto the thread the
* user desires.
*
* This is intended to make callbacks interoperate with
* the platform/OS's own messaging system.
*
* CallbackHandler* can always be nullptr in which case the default handler is used. The
* default handler always dispatches callbacks on filament's main thread opportunistically.
*
* Life time:
* ---------
*
* Filament make no attempts to manage the life time of the CallbackHandler* and never takes
* ownership.
* In particular, this means that the CallbackHandler instance must stay valid until all
* pending callbacks are been dispatched.
*
* Similarly, when shutting down filament, care must be taken to ensure that all pending callbacks
* that might access filament's state have been dispatched. Filament can no longer ensure this
* because callback execution is the responsibility of the CallbackHandler, which is external to
* filament.
* Typically, the concrete CallbackHandler would have a mechanism to drain and/or wait for all
* callbacks to be processed.
*
*/
class CallbackHandler {
public:
using Callback = void(*)(void* user);
/**
* Schedules the callback to be called onto the appropriate thread.
* Typically this will be the application's main thead.
*
* Must be thread-safe.
*/
virtual void post(void* user, Callback callback) = 0;
protected:
virtual ~CallbackHandler() = default;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
namespace filament::backend {
class CommandStream;
using DriverApi = CommandStream;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
#define TNT_FILAMENT_BACKEND_HANDLE_H
#include <utils/compiler.h>
#if !defined(NDEBUG)
#include <utils/Log.h>
#endif
#include <utils/debug.h>
#include <stdint.h>
#include <limits>
#include <type_traits>
namespace filament::backend {
struct HwBufferObject;
struct HwFence;
struct HwIndexBuffer;
struct HwProgram;
struct HwRenderPrimitive;
struct HwRenderTarget;
struct HwSamplerGroup;
struct HwStream;
struct HwSwapChain;
struct HwTexture;
struct HwTimerQuery;
struct HwVertexBuffer;
/*
* A handle to a backend resource. HandleBase is for internal use only.
* HandleBase *must* be a trivial for the purposes of calls, that is, it cannot have user-defined
* copy or move constructors.
*/
//! \privatesection
class HandleBase {
public:
using HandleId = uint32_t;
static constexpr const HandleId nullid = HandleId{ std::numeric_limits<HandleId>::max() };
constexpr HandleBase() noexcept: object(nullid) {}
// whether this Handle is initialized
explicit operator bool() const noexcept { return object != nullid; }
// clear the handle, this doesn't free associated resources
void clear() noexcept { object = nullid; }
// compare handles
bool operator==(const HandleBase& rhs) const noexcept { return object == rhs.object; }
bool operator!=(const HandleBase& rhs) const noexcept { return object != rhs.object; }
bool operator<(const HandleBase& rhs) const noexcept { return object < rhs.object; }
bool operator<=(const HandleBase& rhs) const noexcept { return object <= rhs.object; }
bool operator>(const HandleBase& rhs) const noexcept { return object > rhs.object; }
bool operator>=(const HandleBase& rhs) const noexcept { return object >= rhs.object; }
// get this handle's handleId
HandleId getId() const noexcept { return object; }
// initialize a handle, for internal use only.
explicit HandleBase(HandleId id) noexcept : object(id) {
assert_invariant(object != nullid); // usually means an uninitialized handle is used
}
protected:
HandleBase(HandleBase const& rhs) noexcept = default;
HandleBase& operator=(HandleBase const& rhs) noexcept = default;
private:
HandleId object;
};
/**
* Type-safe handle to backend resources
* @tparam T Type of the resource
*/
template<typename T>
struct Handle : public HandleBase {
Handle() noexcept = default;
Handle(Handle const& rhs) noexcept = default;
Handle& operator=(Handle const& rhs) noexcept = default;
explicit Handle(HandleId id) noexcept : HandleBase(id) { }
// type-safe Handle cast
template<typename B, typename = std::enable_if_t<std::is_base_of<T, B>::value> >
Handle(Handle<B> const& base) noexcept : HandleBase(base) { } // NOLINT(hicpp-explicit-conversions,google-explicit-constructor)
private:
#if !defined(NDEBUG)
template <typename U>
friend utils::io::ostream& operator<<(utils::io::ostream& out, const Handle<U>& h) noexcept;
#endif
};
// Types used by the command stream
// (we use this renaming because the macro-system doesn't deal well with "<" and ">")
using BufferObjectHandle = Handle<HwBufferObject>;
using FenceHandle = Handle<HwFence>;
using IndexBufferHandle = Handle<HwIndexBuffer>;
using ProgramHandle = Handle<HwProgram>;
using RenderPrimitiveHandle = Handle<HwRenderPrimitive>;
using RenderTargetHandle = Handle<HwRenderTarget>;
using SamplerGroupHandle = Handle<HwSamplerGroup>;
using StreamHandle = Handle<HwStream>;
using SwapChainHandle = Handle<HwSwapChain>;
using TextureHandle = Handle<HwTexture>;
using TimerQueryHandle = Handle<HwTimerQuery>;
using VertexBufferHandle = Handle<HwVertexBuffer>;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_HANDLE_H

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PIPELINESTATE_H
#define TNT_FILAMENT_BACKEND_PIPELINESTATE_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <limits>
#include <stdint.h>
namespace filament::backend {
//! \privatesection
struct PipelineState {
Handle<HwProgram> program;
RasterState rasterState;
StencilState stencilState;
PolygonOffset polygonOffset;
Viewport scissor{ 0, 0,
(uint32_t)std::numeric_limits<int32_t>::max(),
(uint32_t)std::numeric_limits<int32_t>::max()
};
};
} // namespace filament::backend
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PipelineState& ps);
#endif
#endif //TNT_FILAMENT_BACKEND_PIPELINESTATE_H

View File

@@ -0,0 +1,317 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H
#define TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/**
* A descriptor to an image in main memory, typically used to transfer image data from the CPU
* to the GPU.
*
* A PixelBufferDescriptor owns the memory buffer it references, therefore PixelBufferDescriptor
* cannot be copied, but can be moved.
*
* PixelBufferDescriptor releases ownership of the memory-buffer when it's destroyed.
*/
class UTILS_PUBLIC PixelBufferDescriptor : public BufferDescriptor {
public:
using PixelDataFormat = backend::PixelDataFormat;
using PixelDataType = backend::PixelDataType;
PixelBufferDescriptor() = default;
/**
* Creates a new PixelBufferDescriptor referencing an image in main memory
*
* @param buffer Virtual address of the buffer containing the image
* @param size Size in bytes of the buffer containing the image
* @param format Format of the image pixels
* @param type Type of the image pixels
* @param alignment Alignment in bytes of pixel rows
* @param left Left coordinate in pixels
* @param top Top coordinate in pixels
* @param stride Stride of a row in pixels
* @param handler Handler to dispatch the callback or nullptr for the default handler
* @param callback A callback used to release the CPU buffer
* @param user An opaque user pointer passed to the callback function when it's called
*/
PixelBufferDescriptor(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, uint8_t alignment,
uint32_t left, uint32_t top, uint32_t stride,
CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, handler, callback, user),
left(left), top(top), stride(stride),
format(format), type(type), alignment(alignment) {
}
PixelBufferDescriptor(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, uint8_t alignment = 1,
uint32_t left = 0, uint32_t top = 0, uint32_t stride = 0,
Callback callback = nullptr, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, callback, user),
left(left), top(top), stride(stride),
format(format), type(type), alignment(alignment) {
}
/**
* Creates a new PixelBufferDescriptor referencing an image in main memory
*
* @param buffer Virtual address of the buffer containing the image
* @param size Size in bytes of the buffer containing the image
* @param format Format of the image pixels
* @param type Type of the image pixels
* @param handler Handler to dispatch the callback or nullptr for the default handler
* @param callback A callback used to release the CPU buffer
* @param user An opaque user pointer passed to the callback function when it's called
*/
PixelBufferDescriptor(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type,
CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, handler, callback, user),
stride(0), format(format), type(type), alignment(1) {
}
PixelBufferDescriptor(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type,
Callback callback, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, callback, user),
stride(0), format(format), type(type), alignment(1) {
}
/**
* Creates a new PixelBufferDescriptor referencing a compressed image in main memory
*
* @param buffer Virtual address of the buffer containing the image
* @param size Size in bytes of the buffer containing the image
* @param format Compressed format of the image
* @param imageSize Compressed size of the image
* @param handler Handler to dispatch the callback or nullptr for the default handler
* @param callback A callback used to release the CPU buffer
* @param user An opaque user pointer passed to the callback function when it's called
*/
PixelBufferDescriptor(void const* buffer, size_t size,
backend::CompressedPixelDataType format, uint32_t imageSize,
CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, handler, callback, user),
imageSize(imageSize), compressedFormat(format), type(PixelDataType::COMPRESSED),
alignment(1) {
}
PixelBufferDescriptor(void const* buffer, size_t size,
backend::CompressedPixelDataType format, uint32_t imageSize,
Callback callback, void* user = nullptr) noexcept
: BufferDescriptor(buffer, size, callback, user),
imageSize(imageSize), compressedFormat(format), type(PixelDataType::COMPRESSED),
alignment(1) {
}
// --------------------------------------------------------------------------------------------
template<typename T, void(T::*method)(void const*, size_t)>
static PixelBufferDescriptor make(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, uint8_t alignment,
uint32_t left, uint32_t top, uint32_t stride, T* data,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, type, alignment, left, top, stride,
handler, [](void* b, size_t s, void* u) {
(*static_cast<T**>(u)->*method)(b, s); }, data };
}
template<typename T, void(T::*method)(void const*, size_t)>
static PixelBufferDescriptor make(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, T* data,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, type, handler, [](void* b, size_t s, void* u) {
(*static_cast<T**>(u)->*method)(b, s); }, data };
}
template<typename T, void(T::*method)(void const*, size_t)>
static PixelBufferDescriptor make(void const* buffer, size_t size,
backend::CompressedPixelDataType format, uint32_t imageSize, T* data,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, imageSize, handler, [](void* b, size_t s, void* u) {
(*static_cast<T**>(u)->*method)(b, s); }, data
};
}
template<typename T>
static PixelBufferDescriptor make(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, uint8_t alignment,
uint32_t left, uint32_t top, uint32_t stride, T&& functor,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, type, alignment, left, top, stride,
handler, [](void* b, size_t s, void* u) {
T& that = *static_cast<T*>(u);
that(b, s);
delete &that;
}, new T(std::forward<T>(functor))
};
}
template<typename T>
static PixelBufferDescriptor make(void const* buffer, size_t size,
PixelDataFormat format, PixelDataType type, T&& functor,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, type,
handler, [](void* b, size_t s, void* u) {
T& that = *static_cast<T*>(u);
that(b, s);
delete &that;
}, new T(std::forward<T>(functor))
};
}
template<typename T>
static PixelBufferDescriptor make(void const* buffer, size_t size,
backend::CompressedPixelDataType format, uint32_t imageSize, T&& functor,
CallbackHandler* handler = nullptr) noexcept {
return { buffer, size, format, imageSize,
handler, [](void* b, size_t s, void* u) {
T& that = *static_cast<T*>(u);
that(b, s);
delete &that;
}, new T(std::forward<T>(functor))
};
}
// --------------------------------------------------------------------------------------------
/**
* Computes the size in bytes needed to fit an image of given dimensions and format
*
* @param format Format of the image pixels
* @param type Type of the image pixels
* @param stride Stride of a row in pixels
* @param height Height of the image in rows
* @param alignment Alignment in bytes of pixel rows
* @return The buffer size needed to fit this image in bytes
*/
static constexpr size_t computeDataSize(PixelDataFormat format, PixelDataType type,
size_t stride, size_t height, size_t alignment) noexcept {
assert_invariant(alignment);
if (type == PixelDataType::COMPRESSED) {
return 0;
}
size_t n = 0;
switch (format) {
case PixelDataFormat::R:
case PixelDataFormat::R_INTEGER:
case PixelDataFormat::DEPTH_COMPONENT:
case PixelDataFormat::ALPHA:
n = 1;
break;
case PixelDataFormat::RG:
case PixelDataFormat::RG_INTEGER:
case PixelDataFormat::DEPTH_STENCIL:
n = 2;
break;
case PixelDataFormat::RGB:
case PixelDataFormat::RGB_INTEGER:
n = 3;
break;
case PixelDataFormat::UNUSED: // shouldn't happen (used to be rgbm)
case PixelDataFormat::RGBA:
case PixelDataFormat::RGBA_INTEGER:
n = 4;
break;
}
size_t bpp = n;
switch (type) {
case PixelDataType::COMPRESSED: // Impossible -- to squash the IDE warnings
case PixelDataType::UBYTE:
case PixelDataType::BYTE:
// nothing to do
break;
case PixelDataType::USHORT:
case PixelDataType::SHORT:
case PixelDataType::HALF:
bpp *= 2;
break;
case PixelDataType::UINT:
case PixelDataType::INT:
case PixelDataType::FLOAT:
bpp *= 4;
break;
case PixelDataType::UINT_10F_11F_11F_REV:
// Special case, format must be RGB and uses 4 bytes
assert_invariant(format == PixelDataFormat::RGB);
bpp = 4;
break;
case PixelDataType::UINT_2_10_10_10_REV:
// Special case, format must be RGBA and uses 4 bytes
assert_invariant(format == PixelDataFormat::RGBA);
bpp = 4;
break;
case PixelDataType::USHORT_565:
// Special case, format must be RGB and uses 2 bytes
assert_invariant(format == PixelDataFormat::RGB);
bpp = 2;
break;
}
size_t const bpr = bpp * stride;
size_t const bprAligned = (bpr + (alignment - 1)) & (~alignment + 1);
return bprAligned * height;
}
//! left coordinate in pixels
uint32_t left = 0;
//! top coordinate in pixels
uint32_t top = 0;
union {
struct {
//! stride in pixels
uint32_t stride;
//! Pixel data format
PixelDataFormat format;
};
struct {
//! compressed image size
uint32_t imageSize;
//! compressed image format
backend::CompressedPixelDataType compressedFormat;
};
};
//! pixel data type
PixelDataType type : 4;
//! row alignment in bytes
uint8_t alignment : 4;
};
} // namespace backend::filament
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PixelBufferDescriptor& b);
#endif
#endif // TNT_FILAMENT_BACKEND_PIXELBUFFERDESCRIPTOR_H

View File

@@ -0,0 +1,168 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORM_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
namespace filament::backend {
class Driver;
/**
* Platform is an interface that abstracts how the backend (also referred to as Driver) is
* created. The backend provides several common Platform concrete implementations, which are
* selected automatically. It is possible however to provide a custom Platform when creating
* the filament Engine.
*/
class UTILS_PUBLIC Platform {
public:
struct SwapChain {};
struct Fence {};
struct Stream {};
struct DriverConfig {
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
};
Platform() noexcept;
virtual ~Platform() noexcept;
/**
* Queries the underlying OS version.
* @return The OS version.
*/
virtual int getOSVersion() const noexcept = 0;
/**
* Creates and initializes the low-level API (e.g. an OpenGL context or Vulkan instance),
* then creates the concrete Driver.
* The caller takes ownership of the returned Driver* and must destroy it with delete.
*
* @param sharedContext an optional shared context. This is not meaningful with all graphic
* APIs and platforms.
* For EGL platforms, this is an EGLContext.
*
* @param driverConfig specifies driver initialization parameters
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual backend::Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.
*
* Internally, Filament might need to call this when waiting on a fence. It is only implemented
* on platforms that need it, such as macOS + OpenGL. Returns false if this is not the main
* thread, or if the platform does not need to perform any special processing.
*/
virtual bool pumpEvents() noexcept;
/**
* InsertBlobFunc is an Invocable to an application-provided function that a
* backend implementation may use to insert a key/value pair into the
* cache.
*/
using InsertBlobFunc = utils::Invocable<
void(const void* key, size_t keySize, const void* value, size_t valueSize)>;
/*
* RetrieveBlobFunc is an Invocable to an application-provided function that a
* backend implementation may use to retrieve a cached value from the
* cache.
*/
using RetrieveBlobFunc = utils::Invocable<
size_t(const void* key, size_t keySize, void* value, size_t valueSize)>;
/**
* Sets the callback functions that the backend can use to interact with caching functionality
* provided by the application.
*
* Cache functions may only be specified once during the lifetime of a
* Platform. The <insert> and <retrieve> Invocables may be called at any time and
* from any thread from the time at which setBlobFunc is called until the time that Platform
* is destroyed. Concurrent calls to these functions from different threads is also allowed.
*
* @param insertBlob an Invocable that inserts a new value into the cache and associates
* it with the given key
* @param retrieveBlob an Invocable that retrieves from the cache the value associated with a
* given key
*/
void setBlobFunc(InsertBlobFunc&& insertBlob, RetrieveBlobFunc&& retrieveBlob) noexcept;
/**
* @return true if setBlobFunc was called.
*/
bool hasBlobFunc() const noexcept;
/**
* To insert a new binary value into the cache and associate it with a given
* key, the backend implementation can call the application-provided callback
* function insertBlob.
*
* No guarantees are made as to whether a given key/value pair is present in
* the cache after the set call. If a different value has been associated
* with the given key in the past then it is undefined which value, if any, is
* associated with the key after the set call. Note that while there are no
* guarantees, the cache implementation should attempt to cache the most
* recently set value for a given key.
*
* @param key pointer to the beginning of the key data that is to be inserted
* @param keySize specifies the size in byte of the data pointed to by <key>
* @param value pointer to the beginning of the value data that is to be inserted
* @param valueSize specifies the size in byte of the data pointed to by <value>
*/
void insertBlob(const void* key, size_t keySize, const void* value, size_t valueSize);
/**
* To retrieve the binary value associated with a given key from the cache, a
* the backend implementation can call the application-provided callback
* function retrieveBlob.
*
* If the cache contains a value for the given key and its size in bytes is
* less than or equal to <valueSize> then the value is written to the memory
* pointed to by <value>. Otherwise nothing is written to the memory pointed
* to by <value>.
*
* @param key pointer to the beginning of the key
* @param keySize specifies the size in bytes of the binary key pointed to by <key>
* @param value pointer to a buffer to receive the cached binary data, if it exists
* @param valueSize specifies the size in bytes of the memory pointed to by <value>
* @return If the cache contains a value associated with the given key then the
* size of that binary value in bytes is returned. Otherwise 0 is returned.
*/
size_t retrieveBlob(const void* key, size_t keySize, void* value, size_t valueSize);
private:
InsertBlobFunc mInsertBlob;
RetrieveBlobFunc mRetrieveBlob;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_PRESENTCALLABLE
#define TNT_FILAMENT_BACKEND_PRESENTCALLABLE
#include <utils/compiler.h>
namespace filament {
namespace backend {
/**
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
* a SwapChain.
*
* Typically, Filament's backend is responsible scheduling a frame's presentation. However, there
* are certain cases where the application might want to control when a frame is scheduled for
* presentation.
*
* For example, on iOS, UIKit elements can be synchronized to 3D content by scheduling a present
* within a CATransation:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* void myFrameScheduledCallback(PresentCallable presentCallable, void* user) {
* [CATransaction begin];
* // Update other UI elements...
* presentCallable();
* [CATransaction commit];
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To obtain a PresentCallable, set a SwapChain::FrameScheduledCallback on a SwapChain with the
* SwapChain::setFrameScheduledCallback method. The callback is called with a PresentCallable object
* and optional user data:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* swapChain->setFrameScheduledCallback(myFrameScheduledCallback, nullptr);
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other
* backends ignore the callback (which will never be called) and proceed normally.
*
* @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread.
*
* Applications *must* call each PresentCallable they receive. Each PresentCallable represents a
* frame that is waiting to be presented. If an application fails to call a PresentCallable, a
* memory leak could occur. To "cancel" the presentation of a frame, pass false to the
* PresentCallable, which will cancel the presentation of the frame and release associated memory.
*
* @see Renderer, SwapChain::setFrameScheduledCallback
*/
class UTILS_PUBLIC PresentCallable {
public:
using PresentFn = void(*)(bool presentFrame, void* user);
PresentCallable(PresentFn fn, void* user) noexcept;
~PresentCallable() noexcept = default;
PresentCallable(const PresentCallable& rhs) = default;
PresentCallable& operator=(const PresentCallable& rhs) = default;
/**
* Call this PresentCallable, scheduling the associated frame for presentation. Pass false for
* presentFrame to effectively "cancel" the presentation of the frame.
*
* @param presentFrame if false, will not present the frame but releases associated memory
*/
void operator()(bool presentFrame = true) noexcept;
private:
PresentFn mPresentFn;
void* mUser = nullptr;
};
/**
* @deprecated, FrameFinishedCallback has been renamed to SwapChain::FrameScheduledCallback.
*/
using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable, void* user);
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRESENTCALLABLE

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <backend/DriverEnums.h>
#include <array>
#include <variant>
namespace filament::backend {
class Program {
public:
static constexpr size_t SHADER_TYPE_COUNT = 3;
static constexpr size_t UNIFORM_BINDING_COUNT = CONFIG_UNIFORM_BINDING_COUNT;
static constexpr size_t SAMPLER_BINDING_COUNT = CONFIG_SAMPLER_BINDING_COUNT;
struct Sampler {
utils::CString name = {}; // name of the sampler in the shader
uint32_t binding = 0; // binding point of the sampler in the shader
};
struct SamplerGroupData {
utils::FixedCapacityVector<Sampler> samplers;
ShaderStageFlags stageFlags = ShaderStageFlags::ALL_SHADER_STAGE_FLAGS;
};
struct Uniform {
utils::CString name; // full qualified name of the uniform field
uint16_t offset; // offset in 'uint32_t' into the uniform buffer
uint8_t size; // >1 for arrays
UniformType type; // uniform type
};
using UniformBlockInfo = std::array<utils::CString, UNIFORM_BINDING_COUNT>;
using UniformInfo = utils::FixedCapacityVector<Uniform>;
using SamplerGroupInfo = std::array<SamplerGroupData, SAMPLER_BINDING_COUNT>;
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
Program() noexcept;
Program(const Program& rhs) = delete;
Program& operator=(const Program& rhs) = delete;
Program(Program&& rhs) noexcept;
Program& operator=(Program&& rhs) noexcept = delete;
~Program() noexcept;
Program& priorityQueue(CompilerPriorityQueue priorityQueue) noexcept;
// sets the material name and variant for diagnostic purposes only
Program& diagnostics(utils::CString const& name,
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)>&& logger);
// sets one of the program's shader (e.g. vertex, fragment)
// string-based shaders are null terminated, consequently the size parameter must include the
// null terminating character.
Program& shader(ShaderStage shader, void const* data, size_t size);
// Note: This is only needed for GLES3.0 backends, because the layout(binding=) syntax is
// not permitted in glsl. The backend needs a way to associate a uniform block
// to a binding point.
Program& uniformBlockBindings(
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> const& uniformBlockBindings) noexcept;
// Note: This is only needed for GLES2.0, this is used to emulate UBO. This function tells
// the program everything it needs to know about the uniforms at a given binding
Program& uniforms(uint32_t index, UniformInfo const& uniforms) noexcept;
// Note: This is only needed for GLES2.0.
Program& attributes(
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> attributes) noexcept;
// sets the 'bindingPoint' sampler group descriptor for this program.
// 'samplers' can be destroyed after this call.
// This effectively associates a set of (BindingPoints, index) to a texture unit in the shader.
// Or more precisely, what layout(binding=) is set to in GLSL.
Program& setSamplerGroup(size_t bindingPoint, ShaderStageFlags stageFlags,
Sampler const* samplers, size_t count) noexcept;
struct SpecializationConstant {
using Type = std::variant<int32_t, float, bool>;
uint32_t id; // id set in glsl
Type value; // value and type
};
Program& specializationConstants(
utils::FixedCapacityVector<SpecializationConstant> specConstants) noexcept;
Program& cacheId(uint64_t cacheId) noexcept;
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
UniformBlockInfo const& getUniformBlockBindings() const noexcept { return mUniformBlocks; }
UniformBlockInfo& getUniformBlockBindings() noexcept { return mUniformBlocks; }
SamplerGroupInfo const& getSamplerGroupInfo() const { return mSamplerGroups; }
SamplerGroupInfo& getSamplerGroupInfo() { return mSamplerGroups; }
auto const& getBindingUniformInfo() const { return mBindingUniformInfo; }
auto& getBindingUniformInfo() { return mBindingUniformInfo; }
auto const& getAttributes() const { return mAttributes; }
auto& getAttributes() { return mAttributes; }
utils::CString const& getName() const noexcept { return mName; }
utils::CString& getName() noexcept { return mName; }
utils::FixedCapacityVector<SpecializationConstant> const& getSpecializationConstants() const noexcept {
return mSpecializationConstants;
}
utils::FixedCapacityVector<SpecializationConstant>& getSpecializationConstants() noexcept {
return mSpecializationConstants;
}
uint64_t getCacheId() const noexcept { return mCacheId; }
CompilerPriorityQueue getPriorityQueue() const noexcept { return mPriorityQueue; }
private:
friend utils::io::ostream& operator<<(utils::io::ostream& out, const Program& builder);
UniformBlockInfo mUniformBlocks = {};
SamplerGroupInfo mSamplerGroups = {};
ShaderSource mShadersSource;
utils::CString mName;
uint64_t mCacheId{};
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
utils::FixedCapacityVector<SpecializationConstant> mSpecializationConstants;
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> mAttributes;
std::array<UniformInfo, Program::UNIFORM_BINDING_COUNT> mBindingUniformInfo;
CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H

View File

@@ -0,0 +1,4 @@
# include/backend Headers
Headers in `include/backend/` are fully public, in particular they can be included in filament's
public headers.

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H
#define TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
struct UTILS_PUBLIC SamplerDescriptor {
Handle<HwTexture> t;
SamplerParams s{};
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#define TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <stdint.h>
namespace filament::backend {
//! \privatesection
struct TargetBufferInfo {
// texture to be used as render target
Handle<HwTexture> handle;
// level to be used
uint8_t level = 0;
// for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping
uint16_t layer = 0;
};
class MRT {
public:
static constexpr uint8_t MIN_SUPPORTED_RENDER_TARGET_COUNT = 4u;
// When updating this, make sure to also take care of RenderTarget.java
static constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
private:
TargetBufferInfo mInfos[MAX_SUPPORTED_RENDER_TARGET_COUNT];
public:
TargetBufferInfo const& operator[](size_t i) const noexcept {
return mInfos[i];
}
TargetBufferInfo& operator[](size_t i) noexcept {
return mInfos[i];
}
MRT() noexcept = default;
MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions)
: mInfos{ color } {
}
MRT(TargetBufferInfo const& color0, TargetBufferInfo const& color1) noexcept
: mInfos{ color0, color1 } {
}
MRT(TargetBufferInfo const& color0, TargetBufferInfo const& color1,
TargetBufferInfo const& color2) noexcept
: mInfos{ color0, color1, color2 } {
}
MRT(TargetBufferInfo const& color0, TargetBufferInfo const& color1,
TargetBufferInfo const& color2, TargetBufferInfo const& color3) noexcept
: mInfos{ color0, color1, color2, color3 } {
}
// this is here for backward compatibility
MRT(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
: mInfos{{ handle, level, layer }} {
}
};
} // namespace filament::backend
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::TargetBufferInfo& tbi);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::MRT& mrt);
#endif
#endif //TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H

View File

@@ -0,0 +1,301 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
namespace filament::backend {
class Driver;
/**
* A Platform interface that creates an OpenGL backend.
*
* WARNING: None of the methods below are allowed to change the GL state and must restore it
* upon return.
*
*/
class OpenGLPlatform : public Platform {
protected:
/*
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const DriverConfig& driverConfig);
~OpenGLPlatform() noexcept override;
public:
struct ExternalTexture {
unsigned int target; // GLenum target
unsigned int id; // GLuint id
};
/**
* Called by the driver to destroy the OpenGL context. This should clean up any windows
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
* called.
*/
virtual void terminate() noexcept = 0;
/**
* Called by the driver to create a SwapChain for this driver.
*
* @param nativeWindow a token representing the native window. See concrete implementation
* for details.
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
*/
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept = 0;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
/**
* Called by the driver create a headless SwapChain.
*
* @param width width of the buffer
* @param height height of the buffer
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
* TODO: we need a more generic way of passing construction parameters
* A void* might be enough.
*/
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
/**
* Called by the driver to destroys the SwapChain
* @param swapChain SwapChain to be destroyed.
*/
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
/**
* Returns the set of buffers that must be preserved up to the call to commit().
* The default value is TargetBufferFlags::NONE.
* The color buffer is always preserved, however ancillary buffers, such as the depth buffer
* are generally discarded. The preserve flags can be used to make sure those ancillary
* buffers are preserved until the call to commit.
*
* @param swapChain
* @return buffer that must be preserved
* @see commit()
*/
virtual TargetBufferFlags getPreservedFlags(SwapChain* swapChain) noexcept;
/**
* Called by the driver to establish the default FBO. The default implementation returns 0.
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
*/
virtual uint32_t createDefaultRenderTarget() noexcept;
/**
* Called by the driver to make the OpenGL context active on the calling thread and bind
* the drawSwapChain to the default render target (FBO) created with createDefaultRenderTarget.
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
*/
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
/**
* Called by the driver once the current frame finishes drawing. Typically, this should present
* the drawSwapChain. This is for example where `eglMakeCurrent()` would be called.
* @param swapChain the SwapChain to present.
*/
virtual void commit(SwapChain* swapChain) noexcept = 0;
/**
* Set the time the next committed buffer should be presented to the user at.
*
* @param presentationTimeInNanosecond time in the future in nanosecond. The clock used depends
* on the concrete platform implementation.
*/
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept;
// --------------------------------------------------------------------------------------------
// Fence support
/**
* Can this implementation create a Fence.
* @return true if supported, false otherwise. The default implementation returns false.
*/
virtual bool canCreateFence() noexcept;
/**
* Creates a Fence (e.g. eglCreateSyncKHR). This must be implemented if `canCreateFence`
* returns true. Fences are used for frame pacing.
*
* @return A Fence object. The default implementation returns nullptr.
*/
virtual Fence* createFence() noexcept;
/**
* Destroys a Fence object. The default implementation does nothing.
*
* @param fence Fence to destroy.
*/
virtual void destroyFence(Fence* fence) noexcept;
/**
* Waits on a Fence.
*
* @param fence Fence to wait on.
* @param timeout Timeout.
* @return Whether the fence signaled or timed out. See backend::FenceStatus.
* The default implementation always return backend::FenceStatus::ERROR.
*/
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept;
// --------------------------------------------------------------------------------------------
// Streaming support
/**
* Creates a Stream from a native Stream.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param nativeStream The native stream, this parameter depends on the concrete implementation.
* @return A new Stream object.
*/
virtual Stream* createStream(void* nativeStream) noexcept;
/**
* Destroys a Stream.
* @param stream Stream to destroy.
*/
virtual void destroyStream(Stream* stream) noexcept;
/**
* The specified stream takes ownership of the texture (tname) object
* Once attached, the texture is automatically updated with the Stream's content, which
* could be a video stream for instance.
*
* @param stream Stream to take ownership of the texture
* @param tname GL texture id to "bind" to the Stream.
*/
virtual void attach(Stream* stream, intptr_t tname) noexcept;
/**
* Destroys the texture associated to the stream
* @param stream Stream to detach from its texture
*/
virtual void detach(Stream* stream) noexcept;
/**
* Updates the content of the texture attached to the stream.
* @param stream Stream to update
* @param timestamp Output parameter: Timestamp of the image bound to the texture.
*/
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept;
// --------------------------------------------------------------------------------------------
// External Image support
/**
* Creates an external texture handle. External textures don't have any parameters because
* these are undefined until setExternalImage() is called.
* @return a pointer to an ExternalTexture structure filled with valid token. However, the
* implementation could just return { 0, GL_TEXTURE_2D } at this point. The actual
* values can be delayed until setExternalImage.
*/
virtual ExternalTexture *createExternalImageTexture() noexcept;
/**
* Destroys an external texture handle and associated data.
* @param texture a pointer to the handle to destroy.
*/
virtual void destroyExternalImage(ExternalTexture* texture) noexcept;
// called on the application thread to allow Filament to take ownership of the image
/**
* Takes ownership of the externalImage. The externalImage parameter depends on the Platform's
* concrete implementation. Ownership is released when destroyExternalImage() is called.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param externalImage A token representing the platform's external image.
* @see destroyExternalImage
*/
virtual void retainExternalImage(void* externalImage) noexcept;
/**
* Called to bind the platform-specific externalImage to an ExternalTexture.
* ExternalTexture::id is guaranteed to be bound when this method is called and ExternalTexture
* is updated with new values for id/target if necessary.
*
* WARNING: this method is not allowed to change the bound texture, or must restore the previous
* binding upon return. This is to avoid problem with a backend doing state caching.
*
* @param externalImage The platform-specific external image.
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
* @return true on success, false on error.
*/
virtual bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept;
/**
* The method allows platforms to convert a user-supplied external image object into a new type
* (e.g. HardwareBuffer => EGLImage). The default implementation returns source.
* @param source Image to transform.
* @return Transformed image.
*/
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept;
// --------------------------------------------------------------------------------------------
/**
* Returns true if additional OpenGL contexts can be created. Default: false.
* @return true if additional OpenGL contexts can be created.
* @see createContext
*/
virtual bool isExtraContextSupported() const noexcept;
/**
* Creates an OpenGL context with the same configuration than the main context and makes it
* current to the current thread. Must not be called from the main driver thread.
* createContext() is only supported if isExtraContextSupported() returns true.
* These additional contexts will be automatically terminated in terminate.
*
* @param shared whether the new context is shared with the main context.
* @see isExtraContextSupported()
* @see terminate()
*/
virtual void createContext(bool shared);
/**
* Detach and destroy the current context if any and releases all resources associated to
* this thread.
*/
virtual void releaseContext() noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaGLImpl;
/**
* A concrete implementation of OpenGLPlatform that supports macOS's Cocoa.
*/
class PlatformCocoaGL : public OpenGLPlatform {
public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// Currently returns 0
int getOSVersion() const noexcept override;
bool pumpEvents() noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaGLImpl* pImpl = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
uint32_t createDefaultRenderTarget() noexcept override;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
};
using ContextManager = PlatformCocoaTouchGL;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#include <stdint.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <utility>
#include <vector>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports EGL.
*/
class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
void releaseContext() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Helper for EGL configs and attributes parameters
class Config {
public:
Config();
Config(std::initializer_list<std::pair<EGLint, EGLint>> list);
EGLint& operator[](EGLint name);
EGLint operator[](EGLint name) const;
void erase(EGLint name) noexcept;
EGLint const* data() const noexcept {
return reinterpret_cast<EGLint const*>(mConfig.data());
}
size_t size() const noexcept {
return mConfig.size();
}
private:
std::vector<std::pair<EGLint, EGLint>> mConfig = {{ EGL_NONE, EGL_NONE }};
};
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
/**
* This returns zero. This method can be overridden to return something more useful.
* @return zero
*/
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
bool isSRGBSwapChainSupported() const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
bool canCreateFence() noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
/**
* Logs glGetError() to slog.e
* @param name a string giving some context on the error. Typically __func__.
*/
static void logEglError(const char* name) noexcept;
static void logEglError(const char* name, EGLint error) noexcept;
static const char* getEglErrorName(EGLint error) noexcept;
/**
* Calls glGetError() to clear the current error flags. logs a warning to log.w if
* an error was pending.
*/
static void clearGlError() noexcept;
/**
* Always use this instead of eglMakeCurrent().
*/
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept;
// TODO: this should probably use getters instead.
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLSurface mEGLDummySurface = EGL_NO_SURFACE;
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
Config mContextAttribs;
std::vector<EGLContext> mAdditionalContexts;
// supported extensions detected at runtime
struct {
struct {
bool OES_EGL_image_external_essl3 = false;
} gl;
struct {
bool ANDROID_recordable = false;
bool KHR_create_context = false;
bool KHR_gl_colorspace = false;
bool KHR_no_config_context = false;
bool KHR_surfaceless_context = false;
} egl;
} ext;
void initializeGlExtensions() noexcept;
private:
EGLConfig findSwapChainConfig(uint64_t flags) const;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/platforms/PlatformEGL.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
/**
* A concrete implementation of OpenGLPlatform and subclass of PlatformEGL that supports
* EGL on Android. It adds Android streaming functionality to PlatformEGL.
*/
class PlatformEGLAndroid : public PlatformEGL {
public:
PlatformEGLAndroid() noexcept;
~PlatformEGLAndroid() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Returns the Android SDK version.
* @return Android SDK version.
*/
int getOSVersion() const noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
/**
* Set the presentation time using `eglPresentationTimeANDROID`
* @param presentationTimeInNanosecond
*/
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
Stream* createStream(void* nativeStream) noexcept override;
void destroyStream(Stream* stream) noexcept override;
void attach(Stream* stream, intptr_t tname) noexcept override;
void detach(Stream* stream) noexcept override;
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
/**
* Converts a AHardwareBuffer to EGLImage
* @param source source.image is a AHardwareBuffer
* @return source.image contains an EGLImage
*/
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
private:
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_HEADLESS_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_HEADLESS_H
#include "PlatformEGL.h"
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports EGL with only headless swapchains.
*/
class PlatformEGLHeadless : public PlatformEGL {
public:
PlatformEGLHeadless() noexcept;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
};
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_HEADLESS_H

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H
#include <stdint.h>
#include "bluegl/BlueGL.h"
#include <GL/glx.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <vector>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports GLX.
*/
class PlatformGLX : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
private:
Display *mGLXDisplay;
GLXContext mGLXContext;
GLXFBConfig* mGLXConfig;
GLXPbuffer mDummySurface;
std::vector<GLXPbuffer> mPBuffers;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WGL_H
#include <stdint.h>
#include <windows.h>
#include "utils/unwindows.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <vector>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports WGL.
*/
class PlatformWGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
protected:
HGLRC mContext = NULL;
HWND mHWnd = NULL;
HDC mWhdc = NULL;
PIXELFORMATDESCRIPTOR mPfd = {};
std::vector<HGLRC> mAdditionalContexts;
std::vector<int> mAttribs;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports WebGL.
*/
class PlatformWebGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H

View File

@@ -0,0 +1,238 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#include <backend/Platform.h>
#include <bluevk/BlueVK.h>
#include <utils/FixedCapacityVector.h>
#include <utils/PrivateImplementation.h>
#include <tuple>
#include <unordered_set>
namespace filament::backend {
using SwapChain = Platform::SwapChain;
/**
* Private implementation details for the provided vulkan platform.
*/
struct VulkanPlatformPrivate;
/**
* A Platform interface that creates a Vulkan backend.
*/
class VulkanPlatform : public Platform, utils::PrivateImplementation<VulkanPlatformPrivate> {
public:
/**
* A collection of handles to objects and metadata that comprises a Vulkan context. The client
* can instantiate this struct and pass to Engine::Builder::sharedContext if they wishes to
* share their vulkan context. This is specifically necessary if the client wishes to override
* the swapchain API.
*/
struct VulkanSharedContext {
VkInstance instance = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice logicalDevice = VK_NULL_HANDLE;
uint32_t graphicsQueueFamilyIndex = 0xFFFFFFFF;
// In the usual case, the client needs to allocate at least one more graphics queue
// for Filament, and this index is the param to pass into vkGetDeviceQueue. In the case
// where the gpu only has one graphics queue. Then the client needs to ensure that no
// concurrent access can occur.
uint32_t graphicsQueueIndex = 0xFFFFFFFF;
};
/**
* Shorthand for the pointer to the Platform SwapChain struct, we use it also as a handle (i.e.
* identifier for the swapchain).
*/
using SwapChainPtr = Platform::SwapChain*;
/**
* Collection of images, formats, and extent (width/height) that defines the swapchain.
*/
struct SwapChainBundle {
utils::FixedCapacityVector<VkImage> colors;
VkImage depth = VK_NULL_HANDLE;
VkFormat colorFormat = VK_FORMAT_UNDEFINED;
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
VkExtent2D extent = {0, 0};
};
VulkanPlatform();
~VulkanPlatform() override;
Driver* createDriver(void* sharedContext,
Platform::DriverConfig const& driverConfig) noexcept override;
int getOSVersion() const noexcept override {
return 0;
}
// ----------------------------------------------------
// ---------- Platform Customization options ----------
/**
* The client preference can be stored within the struct. We allow for two specification of
* preference:
* 1) A substring to match against `VkPhysicalDeviceProperties.deviceName`.
* 2) Index of the device in the list as returned by vkEnumeratePhysicalDevices.
*/
struct GPUPreference {
std::string deviceName;
int8_t index = -1;
};
/**
* Client can provide a preference over the GPU to use in the vulkan instance
* @return `GPUPreference` struct that indicates the client's preference
*/
virtual GPUPreference getPreferredGPU() noexcept {
return {};
}
// -------- End platform customization options --------
// ----------------------------------------------------
/**
* Returns whether the platform supports sRGB swapchain. This is true by default, and the client
* needs to override this method to specify otherwise.
* @return Whether the platform supports sRGB swapchain.
*/
virtual bool isSRGBSwapChainSupported() const {
return true;
}
/**
* Get the images handles and format of the memory backing the swapchain. This should be called
* after createSwapChain() or after recreateIfResized().
* @param swapchain The handle returned by createSwapChain()
* @return An array of VkImages
*/
virtual SwapChainBundle getSwapChainBundle(SwapChainPtr handle);
/**
* Acquire the next image for rendering. The `index` will be written with an non-negative
* integer that the backend can use to index into the `SwapChainBundle.colors` array. The
* corresponding VkImage will be used as the output color attachment. The client should signal
* the `clientSignal` semaphore when the image is ready to be used by the backend.
* @param handle The handle returned by createSwapChain()
* @param clientSignal The semaphore that the client will signal to indicate that the backend
* may render into the image.
* @param index Pointer to memory that will be filled with the index that corresponding
* to an image in the `SwapChainBundle.colors` array.
* @return Result of acquire
*/
virtual VkResult acquire(SwapChainPtr handle, VkSemaphore clientSignal, uint32_t* index);
/**
* Present the image corresponding to `index` to the display. The client should wait on
* `finishedDrawing` before presenting.
* @param handle The handle returned by createSwapChain()
* @param index Index that corresponding to an image in the
* `SwapChainBundle.colors` array.
* @param finishedDrawing Backend passes in a semaphore that the client will signal to
* indicate that the client may render into the image.
* @return Result of present
*/
virtual VkResult present(SwapChainPtr handle, uint32_t index, VkSemaphore finishedDrawing);
/**
* Check if the surface size has changed.
* @param handle The handle returned by createSwapChain()
* @return Whether the swapchain has been resized
*/
virtual bool hasResized(SwapChainPtr handle);
/**
* Carry out a recreation of the swapchain.
* @param handle The handle returned by createSwapChain()
* @return Result of the recreation
*/
virtual VkResult recreate(SwapChainPtr handle);
/**
* Create a swapchain given a platform window, or if given a null `nativeWindow`, then we
* try to create a headless swapchain with the given `extent`.
* @param flags Optional parameters passed to the client as defined in
* Filament::SwapChain.h.
* @param extent Optional width and height that indicates the size of the headless swapchain.
* @return Result of the operation
*/
virtual SwapChainPtr createSwapChain(void* nativeWindow, uint64_t flags = 0,
VkExtent2D extent = {0, 0});
/**
* Destroy the swapchain.
* @param handle The handle returned by createSwapChain()
*/
virtual void destroy(SwapChainPtr handle);
/**
* Clean up any resources owned by the Platform. For example, if the Vulkan instance handle was
* generated by the platform, we need to clean it up in this method.
*/
virtual void terminate();
/**
* @return The instance (VkInstance) for the Vulkan backend.
*/
VkInstance getInstance() const noexcept;
/**
* @return The logical device (VkDevice) that was selected as the backend device.
*/
VkDevice getDevice() const noexcept;
/**
* @return The physical device (i.e gpu) that was selected as the backend physical device.
*/
VkPhysicalDevice getPhysicalDevice() const noexcept;
/**
* @return The family index of the graphics queue selected for the Vulkan backend.
*/
uint32_t getGraphicsQueueFamilyIndex() const noexcept;
/**
* @return The index of the graphics queue (if there are multiple graphics queues)
* selected for the Vulkan backend.
*/
uint32_t getGraphicsQueueIndex() const noexcept;
/**
* @return The queue that was selected for the Vulkan backend.
*/
VkQueue getGraphicsQueue() const noexcept;
private:
// Platform dependent helper methods
using ExtensionSet = std::unordered_set<std::string_view>;
static ExtensionSet getRequiredInstanceExtensions();
using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>;
static SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
uint64_t flags) noexcept;
friend struct VulkanPlatformPrivate;
};
}// namespace filament::backend
#endif// TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*/
/**********************************************************************************************
* Generated by bluegl/bluegl-gen.py
* DO NOT EDIT
**********************************************************************************************/
#ifndef TNT_FILAMENT_BLUEGL__H
#define TNT_FILAMENT_BLUEGL__H
// MSVC includes .../Windows Kits\10\Include\10.0.17763.0\um\GL/gl.h, with gl APIs conflicting with
// bluegl\include\GL/glcorearb.h, causing errors for OpenGL APIs such as:
// error C2375: 'glBindTexture': redefinition; different linkage
#ifndef FILAMENT_PLATFORM_WGL
#define GL_GLEXT_PROTOTYPES 1
#endif
#include <GL/glcorearb.h>
#include <GL/glext.h>
#if defined(WIN32)
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#ifdef far
#undef far
#endif
#ifdef near
#undef near
#endif
#ifdef ERROR
#undef ERROR
#endif
#ifdef OPAQUE
#undef OPAQUE
#endif
#ifdef TRANSPARENT
#undef TRANSPARENT
#endif
#ifdef PURE
#undef PURE
#endif
#endif
namespace bluegl {
/**
* Looks up and binds all available OpenGL Core functions.
* Every call to this function will increase an internal reference
* counter that can be decreased by calling unbind().
*
* @return 0 on success or -1 if an error occurred.
*/
int bind();
/**
* Unbinds all available OpenGL Core functions.
* Every call to this function will decrease an internal reference
* counter and unbind all OpenGL functions when the counter reaches 0.
* As such you should assume that no OpenGL calls can be made after
* calling this function.
*/
void unbind();
} // namespace bluegl
#endif // TNT_FILAMENT_BLUEGL__H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
#ifndef CAMUTILS_BOOKMARK_H
#define CAMUTILS_BOOKMARK_H
#include <camutils/compiler.h>
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament {
namespace camutils {
template <typename FLOAT> class FreeFlightManipulator;
template <typename FLOAT> class OrbitManipulator;
template <typename FLOAT> class MapManipulator;
template <typename FLOAT> class Manipulator;
enum class Mode { ORBIT, MAP, FREE_FLIGHT };
/**
* Opaque memento to a viewing position and orientation (e.g. the "home" camera position).
*
* This little struct is meant to be passed around by value and can be used to track camera
* animation between waypoints. In map mode this implements Van Wijk interpolation.
*
* @see Manipulator::getCurrentBookmark, Manipulator::jumpToBookmark
*/
template <typename FLOAT>
struct CAMUTILS_PUBLIC Bookmark {
/**
* Interpolates between two bookmarks. The t argument must be between 0 and 1 (inclusive), and
* the two endpoints must have the same mode (ORBIT or MAP).
*/
static Bookmark<FLOAT> interpolate(Bookmark<FLOAT> a, Bookmark<FLOAT> b, double t);
/**
* Recommends a duration for animation between two MAP endpoints. The return value is a unitless
* multiplier.
*/
static double duration(Bookmark<FLOAT> a, Bookmark<FLOAT> b);
private:
struct MapParams {
FLOAT extent;
filament::math::vec2<FLOAT> center;
};
struct OrbitParams {
FLOAT phi;
FLOAT theta;
FLOAT distance;
filament::math::vec3<FLOAT> pivot;
};
struct FlightParams {
FLOAT pitch;
FLOAT yaw;
filament::math::vec3<FLOAT> position;
};
Mode mode;
MapParams map;
OrbitParams orbit;
FlightParams flight;
friend class FreeFlightManipulator<FLOAT>;
friend class OrbitManipulator<FLOAT>;
friend class MapManipulator<FLOAT>;
};
} // namespace camutils
} // namespace filament
#endif // CAMUTILS_BOOKMARK_H

View File

@@ -0,0 +1,298 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
#ifndef CAMUTILS_MANIPULATOR_H
#define CAMUTILS_MANIPULATOR_H
#include <camutils/Bookmark.h>
#include <camutils/compiler.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <cstdint>
namespace filament {
namespace camutils {
enum class Fov { VERTICAL, HORIZONTAL };
/**
* Helper that enables camera interaction similar to sketchfab or Google Maps.
*
* Clients notify the camera manipulator of various mouse or touch events, then periodically call
* its getLookAt() method so that they can adjust their camera(s). Three modes are supported: ORBIT,
* MAP, and FREE_FLIGHT. To construct a manipulator instance, the desired mode is passed into the
* create method.
*
* Usage example:
*
* using CameraManipulator = camutils::Manipulator<float>;
* CameraManipulator* manip;
*
* void init() {
* manip = CameraManipulator::Builder()
* .viewport(1024, 768)
* .build(camutils::Mode::ORBIT);
* }
*
* void onMouseDown(int x, int y) {
* manip->grabBegin(x, y, false);
* }
*
* void onMouseMove(int x, int y) {
* manip->grabUpdate(x, y);
* }
*
* void onMouseUp(int x, int y) {
* manip->grabEnd();
* }
*
* void gameLoop() {
* while (true) {
* filament::math::float3 eye, center, up;
* manip->getLookAt(&eye, &center, &up);
* camera->lookAt(eye, center, up);
* render();
* }
* }
*
* @see Bookmark
*/
template <typename FLOAT>
class CAMUTILS_PUBLIC Manipulator {
public:
using vec2 = filament::math::vec2<FLOAT>;
using vec3 = filament::math::vec3<FLOAT>;
using vec4 = filament::math::vec4<FLOAT>;
/** Opaque handle to a viewing position and orientation to facilitate camera animation. */
using Bookmark = filament::camutils::Bookmark<FLOAT>;
/** Optional raycasting function to enable perspective-correct panning. */
typedef bool (*RayCallback)(const vec3& origin, const vec3& dir, FLOAT* t, void* userdata);
/** Builder state, direct access is allowed but Builder methods are preferred. **/
struct Config {
int viewport[2];
vec3 targetPosition;
vec3 upVector;
FLOAT zoomSpeed;
vec3 orbitHomePosition;
vec2 orbitSpeed;
Fov fovDirection;
FLOAT fovDegrees;
FLOAT farPlane;
vec2 mapExtent;
FLOAT mapMinDistance;
vec3 flightStartPosition;
FLOAT flightStartPitch;
FLOAT flightStartYaw;
FLOAT flightMaxSpeed;
FLOAT flightSpeedSteps;
vec2 flightPanSpeed;
FLOAT flightMoveDamping;
vec4 groundPlane;
RayCallback raycastCallback;
void* raycastUserdata;
};
struct Builder {
// Common properties
Builder& viewport(int width, int height); //! Width and height of the viewing area
Builder& targetPosition(FLOAT x, FLOAT y, FLOAT z); //! World-space position of interest, defaults to (0,0,0)
Builder& upVector(FLOAT x, FLOAT y, FLOAT z); //! Orientation for the home position, defaults to (0,1,0)
Builder& zoomSpeed(FLOAT val); //! Multiplied with scroll delta, defaults to 0.01
// Orbit mode properties
Builder& orbitHomePosition(FLOAT x, FLOAT y, FLOAT z); //! Initial eye position in world space, defaults to (0,0,1)
Builder& orbitSpeed(FLOAT x, FLOAT y); //! Multiplied with viewport delta, defaults to 0.01
// Map mode properties
Builder& fovDirection(Fov fov); //! The axis that's held constant when viewport changes
Builder& fovDegrees(FLOAT degrees); //! The full FOV (not the half-angle)
Builder& farPlane(FLOAT distance); //! The distance to the far plane
Builder& mapExtent(FLOAT worldWidth, FLOAT worldHeight); //! The ground size for computing home position
Builder& mapMinDistance(FLOAT mindist); //! Constrains the zoom-in level
// Free flight properties
Builder& flightStartPosition(FLOAT x, FLOAT y, FLOAT z); //! Initial eye position in world space, defaults to (0,0,0)
Builder& flightStartOrientation(FLOAT pitch, FLOAT yaw); //! Initial orientation in pitch and yaw, defaults to (0,0)
Builder& flightMaxMoveSpeed(FLOAT maxSpeed); //! The maximum camera speed in world units per second, defaults to 10
Builder& flightSpeedSteps(int steps); //! The number of speed steps adjustable with scroll wheel, defaults to 80
Builder& flightPanSpeed(FLOAT x, FLOAT y); //! Multiplied with viewport delta, defaults to 0.01,0.01
Builder& flightMoveDamping(FLOAT damping); //! Applies a deceleration to camera movement, defaults to 0 (no damping)
//! Lower values give slower damping times, a good default is 15
//! Too high a value may lead to instability
// Raycast properties
Builder& groundPlane(FLOAT a, FLOAT b, FLOAT c, FLOAT d); //! Plane equation used as a raycast fallback
Builder& raycastCallback(RayCallback cb, void* userdata); //! Raycast function for accurate grab-and-pan
/**
* Creates a new camera manipulator, either ORBIT, MAP, or FREE_FLIGHT.
*
* Clients can simply use "delete" to destroy the manipulator.
*/
Manipulator* build(Mode mode);
Config details = {};
};
virtual ~Manipulator() = default;
/**
* Gets the immutable mode of the manipulator.
*/
Mode getMode() const { return mMode; }
/**
* Sets the viewport dimensions. The manipulator uses this to process grab events and raycasts.
*/
void setViewport(int width, int height);
/**
* Gets the current orthonormal basis; this is usually called once per frame.
*/
void getLookAt(vec3* eyePosition, vec3* targetPosition, vec3* upward) const;
/**
* Given a viewport coordinate, picks a point in the ground plane, or in the actual scene if the
* raycast callback was provided.
*/
bool raycast(int x, int y, vec3* result) const;
/**
* Given a viewport coordinate, computes a picking ray (origin + direction).
*/
void getRay(int x, int y, vec3* origin, vec3* dir) const;
/**
* Starts a grabbing session (i.e. the user is dragging around in the viewport).
*
* In MAP mode, this starts a panning session.
* In ORBIT mode, this starts either rotating or strafing.
* In FREE_FLIGHT mode, this starts a nodal panning session.
*
* @param x X-coordinate for point of interest in viewport space
* @param y Y-coordinate for point of interest in viewport space
* @param strafe ORBIT mode only; if true, starts a translation rather than a rotation
*/
virtual void grabBegin(int x, int y, bool strafe) = 0;
/**
* Updates a grabbing session.
*
* This must be called at least once between grabBegin / grabEnd to dirty the camera.
*/
virtual void grabUpdate(int x, int y) = 0;
/**
* Ends a grabbing session.
*/
virtual void grabEnd() = 0;
/**
* Keys used to translate the camera in FREE_FLIGHT mode.
* FORWARD and BACKWARD dolly the camera forwards and backwards.
* LEFT and RIGHT strafe the camera left and right.
* UP and DOWN boom the camera upwards and downwards.
*/
enum class Key {
FORWARD,
LEFT,
BACKWARD,
RIGHT,
UP,
DOWN,
COUNT
};
/**
* Signals that a key is now in the down state.
*
* In FREE_FLIGHT mode, the camera is translated forward and backward and strafed left and right
* depending on the depressed keys. This allows WASD-style movement.
*/
virtual void keyDown(Key key);
/**
* Signals that a key is now in the up state.
*
* @see keyDown
*/
virtual void keyUp(Key key);
/**
* In MAP and ORBIT modes, dollys the camera along the viewing direction.
* In FREE_FLIGHT mode, adjusts the move speed of the camera.
*
* @param x X-coordinate for point of interest in viewport space, ignored in FREE_FLIGHT mode
* @param y Y-coordinate for point of interest in viewport space, ignored in FREE_FLIGHT mode
* @param scrolldelta In MAP and ORBIT modes, negative means "zoom in", positive means "zoom out"
* In FREE_FLIGHT mode, negative means "slower", positive means "faster"
*/
virtual void scroll(int x, int y, FLOAT scrolldelta) = 0;
/**
* Processes input and updates internal state.
*
* This must be called once every frame before getLookAt is valid.
*
* @param deltaTime The amount of time, in seconds, passed since the previous call to update.
*/
virtual void update(FLOAT deltaTime);
/**
* Gets a handle that can be used to reset the manipulator back to its current position.
*
* @see jumpToBookmark
*/
virtual Bookmark getCurrentBookmark() const = 0;
/**
* Gets a handle that can be used to reset the manipulator back to its home position.
*
* @see jumpToBookmark
*/
virtual Bookmark getHomeBookmark() const = 0;
/**
* Sets the manipulator position and orientation back to a stashed state.
*
* @see getCurrentBookmark, getHomeBookmark
*/
virtual void jumpToBookmark(const Bookmark& bookmark) = 0;
protected:
Manipulator(Mode mode, const Config& props);
virtual void setProperties(const Config& props);
vec3 raycastFarPlane(int x, int y) const;
const Mode mMode;
Config mProps;
vec3 mEye;
vec3 mTarget;
};
} // namespace camutils
} // namespace filament
#endif /* CAMUTILS_MANIPULATOR_H */

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* 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.
*/
#ifndef CAMUTILS_COMPILER_H
#define CAMUTILS_COMPILER_H
#if __has_attribute(visibility)
# define CAMUTILS_PUBLIC __attribute__((visibility("default")))
#else
# define CAMUTILS_PUBLIC
#endif
#endif // CAMUTILS_COMPILER_H

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_ENUMMANAGER_H
#define TNT_ENUMMANAGER_H
#include <algorithm>
#include <string>
#include <unordered_map>
#include <filamat/MaterialBuilder.h>
namespace filamat {
using Property = MaterialBuilder::Property;
using UniformType = MaterialBuilder::UniformType;
using SamplerType = MaterialBuilder::SamplerType;
using SubpassType = MaterialBuilder::SubpassType;
using SamplerFormat = MaterialBuilder::SamplerFormat;
using ParameterPrecision = MaterialBuilder::ParameterPrecision;
using OutputTarget = MaterialBuilder::OutputTarget;
using OutputQualifier = MaterialBuilder::VariableQualifier;
using OutputType = MaterialBuilder::OutputType;
using ConstantType = MaterialBuilder::ConstantType;
// Convenience methods to convert std::string to Enum and also iterate over Enum values.
class Enums {
public:
// Returns true if string "s" is a valid string representation of an element of enum T.
template<typename T>
static bool isValid(const std::string& s) noexcept {
std::unordered_map<std::string, T>& map = getMap<T>();
return map.find(s) != map.end();
}
// Return enum matching its string representation. Returns undefined if s is not a valid enum T
// value. You should always call isValid() first to validate a string before calling toEnum().
template<typename T>
static T toEnum(const std::string& s) noexcept {
std::unordered_map<std::string, T>& map = getMap<T>();
return map.at(s);
}
template<typename T>
static std::string toString(T t) noexcept;
// Return a map of all values in an enum with their string representation.
template<typename T>
static std::unordered_map<std::string, T>& map() noexcept {
std::unordered_map<std::string, T>& map = getMap<T>();
return map;
};
private:
template<typename T>
static std::unordered_map<std::string, T>& getMap() noexcept;
static std::unordered_map<std::string, Property> mStringToProperty;
static std::unordered_map<std::string, UniformType> mStringToUniformType;
static std::unordered_map<std::string, SamplerType> mStringToSamplerType;
static std::unordered_map<std::string, SubpassType> mStringToSubpassType;
static std::unordered_map<std::string, SamplerFormat> mStringToSamplerFormat;
static std::unordered_map<std::string, ParameterPrecision> mStringToSamplerPrecision;
static std::unordered_map<std::string, OutputTarget> mStringToOutputTarget;
static std::unordered_map<std::string, OutputQualifier> mStringToOutputQualifier;
static std::unordered_map<std::string, OutputType> mStringToOutputType;
static std::unordered_map<std::string, ConstantType> mStringToConstantType;
};
template<typename T>
std::string Enums::toString(T t) noexcept {
std::unordered_map<std::string, T>& map = getMap<T>();
auto result = std::find_if(map.begin(), map.end(), [t](auto& pair) {
return pair.second == t;
});
if (result != map.end()) {
return result->first;
}
return "";
}
} // namespace filamat
#endif //TNT_ENUMMANAGER_H

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMAT_INCLUDER_H
#define TNT_FILAMAT_INCLUDER_H
#include <utils/CString.h>
#include <functional>
namespace filamat {
struct IncludeResult {
// The include name of the root file, as if it were being included.
// I.e., 'foobar.h' in the case of #include "foobar.h"
const utils::CString includeName;
// The following fields should be filled out by the IncludeCallback when processing an include,
// or when calling resolveIncludes for the root file.
// The full contents of the include file. This may contain additional, recursive include
// directives.
utils::CString text;
// The line number for the first line of text (first line is 0).
size_t lineNumberOffset = 0;
// The name of the include file. This gets passed as "includerName" for any includes inside of
// source. This field isn't used by the include system; it's up to the callback to give meaning
// to this value and interpret it accordingly. In the case of DirIncluder, this is an empty
// string to represent the root include file, and a canonical path for subsequent included
// files.
utils::CString name;
};
/**
* A callback invoked by the include system when an #include "file.h" directive is found.
*
* For example, if a file main.h includes file.h on line 10, then IncludeCallback would be called
* with the following:
* includeCallback("main.h", {.includeName = "file.h" })
* It's then up to the IncludeCallback to fill out the .text, .name, and (optionally)
* lineNumberOffset fields.
*
* @param includedBy is the value that was given to IncludeResult.name for this source file, or
* the empty string for the root source file.
* @param result is the IncludeResult that the callback should fill out.
* @return true, if the include was resolved successfully, false otherwise.
*
* For an example of implementing this callback, see tools/matc/src/matc/DirIncluder.h.
*/
using IncludeCallback = std::function<bool(
const utils::CString& includedBy,
IncludeResult& result)>;
} // namespace filamat
#endif

View File

@@ -0,0 +1,886 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
//! \file
#ifndef TNT_FILAMAT_MATERIAL_PACKAGE_BUILDER_H
#define TNT_FILAMAT_MATERIAL_PACKAGE_BUILDER_H
#include <filament/MaterialEnums.h>
#include <filamat/IncludeCallback.h>
#include <filamat/Package.h>
#include <backend/DriverEnums.h>
#include <backend/TargetBufferInfo.h>
#include <utils/BitmaskEnum.h>
#include <utils/bitset.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <math/vec3.h>
#include <atomic>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <variant>
#include <stddef.h>
#include <stdint.h>
namespace utils {
class JobSystem;
}
namespace filament {
class BufferInterfaceBlock;
}
namespace filamat {
struct MaterialInfo;
struct Variant;
class ChunkContainer;
class UTILS_PUBLIC MaterialBuilderBase {
public:
/**
* High-level hint that works in concert with TargetApi to determine the shader models (used to
* generate GLSL) and final output representations (spirv and/or text).
* When generating the GLSL this is used to differentiate OpenGL from OpenGLES, it is also
* used to make some performance adjustments.
*/
enum class Platform {
DESKTOP,
MOBILE,
ALL
};
/**
* TargetApi defines which language after transpilation will be used, it is used to
* account for some differences between these languages when generating the GLSL.
*/
enum class TargetApi : uint8_t {
OPENGL = 0x01u,
VULKAN = 0x02u,
METAL = 0x04u,
ALL = OPENGL | VULKAN | METAL
};
/*
* Generally we generate GLSL that will be converted to SPIRV, optimized and then
* transpiled to the backend's language such as MSL, ESSL300, GLSL410 or SPIRV, in this
* case the generated GLSL uses ESSL310 or GLSL450 and has Vulkan semantics and
* TargetLanguage::SPIRV must be used.
*
* However, in some cases (e.g. when no optimization is asked) we generate the *final* GLSL
* directly, this GLSL must be ESSL300 or GLSL410 and cannot use any Vulkan syntax, for this
* situation we use TargetLanguage::GLSL. In this case TargetApi is guaranteed to be OPENGL.
*
* Note that TargetLanguage::GLSL is not the common case, as it is generally not used in
* release builds.
*
* Also note that glslang performs semantics analysis on whichever GLSL ends up being generated.
*/
enum class TargetLanguage {
GLSL, // GLSL with OpenGL 4.1 / OpenGL ES 3.0 semantics
SPIRV // GLSL with Vulkan semantics
};
enum class Optimization {
NONE,
PREPROCESSOR,
SIZE,
PERFORMANCE
};
/**
* Initialize MaterialBuilder.
*
* init must be called first before building any materials.
*/
static void init();
/**
* Release internal MaterialBuilder resources.
*
* Call shutdown when finished building materials to release all internal resources. After
* calling shutdown, another call to MaterialBuilder::init must precede another material build.
*/
static void shutdown();
protected:
// Looks at platform and target API, then decides on shader models and output formats.
void prepare(bool vulkanSemantics);
using ShaderModel = filament::backend::ShaderModel;
Platform mPlatform = Platform::DESKTOP;
TargetApi mTargetApi = (TargetApi) 0;
Optimization mOptimization = Optimization::PERFORMANCE;
bool mPrintShaders = false;
bool mGenerateDebugInfo = false;
utils::bitset32 mShaderModels;
struct CodeGenParams {
ShaderModel shaderModel;
TargetApi targetApi;
TargetLanguage targetLanguage;
};
std::vector<CodeGenParams> mCodeGenPermutations;
// Keeps track of how many times MaterialBuilder::init() has been called without a call to
// MaterialBuilder::shutdown(). Internally, glslang does something similar. We keep track for
// ourselves, so we can inform the user if MaterialBuilder::init() hasn't been called before
// attempting to build a material.
static std::atomic<int> materialBuilderClients;
};
// Utility function that looks at an Engine backend to determine TargetApi
inline constexpr MaterialBuilderBase::TargetApi targetApiFromBackend(
filament::backend::Backend backend) noexcept {
using filament::backend::Backend;
using TargetApi = MaterialBuilderBase::TargetApi;
switch (backend) {
case Backend::DEFAULT: return TargetApi::ALL;
case Backend::OPENGL: return TargetApi::OPENGL;
case Backend::VULKAN: return TargetApi::VULKAN;
case Backend::METAL: return TargetApi::METAL;
case Backend::NOOP: return TargetApi::OPENGL;
}
}
/**
* MaterialBuilder builds Filament materials from shader code.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filamat/MaterialBuilder.h>
* using namespace filamat;
*
* // Must be called before any materials can be built.
* MaterialBuilder::init();
* MaterialBuilder builder;
* builder
* .name("My material")
* .material("void material (inout MaterialInputs material) {"
* " prepareMaterial(material);"
* " material.baseColor.rgb = float3(1.0, 0.0, 0.0);"
* "}")
* .shading(MaterialBuilder::Shading::LIT)
* .targetApi(MaterialBuilder::TargetApi::ALL)
* .platform(MaterialBuilder::Platform::ALL);
* Package package = builder.build();
* if (package.isValid()) {
* // success!
* }
* // Call when finished building all materials to release internal
* // MaterialBuilder resources.
* MaterialBuilder::shutdown();
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @see filament::Material
*/
class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase {
public:
MaterialBuilder();
~MaterialBuilder();
MaterialBuilder(const MaterialBuilder& rhs) = delete;
MaterialBuilder& operator=(const MaterialBuilder& rhs) = delete;
MaterialBuilder(MaterialBuilder&& rhs) noexcept = default;
MaterialBuilder& operator=(MaterialBuilder&& rhs) noexcept = default;
static constexpr size_t MATERIAL_VARIABLES_COUNT = 4;
enum class Variable : uint8_t {
CUSTOM0,
CUSTOM1,
CUSTOM2,
CUSTOM3
// when adding more variables, make sure to update MATERIAL_VARIABLES_COUNT
};
using MaterialDomain = filament::MaterialDomain;
using RefractionMode = filament::RefractionMode;
using RefractionType = filament::RefractionType;
using ReflectionMode = filament::ReflectionMode;
using VertexAttribute = filament::VertexAttribute;
using ShaderQuality = filament::ShaderQuality;
using BlendingMode = filament::BlendingMode;
using Shading = filament::Shading;
using Interpolation = filament::Interpolation;
using VertexDomain = filament::VertexDomain;
using TransparencyMode = filament::TransparencyMode;
using SpecularAmbientOcclusion = filament::SpecularAmbientOcclusion;
using AttributeType = filament::backend::UniformType;
using UniformType = filament::backend::UniformType;
using ConstantType = filament::backend::ConstantType;
using SamplerType = filament::backend::SamplerType;
using SubpassType = filament::backend::SubpassType;
using SamplerFormat = filament::backend::SamplerFormat;
using ParameterPrecision = filament::backend::Precision;
using Precision = filament::backend::Precision;
using CullingMode = filament::backend::CullingMode;
using FeatureLevel = filament::backend::FeatureLevel;
enum class VariableQualifier : uint8_t {
OUT
};
enum class OutputTarget : uint8_t {
COLOR,
DEPTH
};
enum class OutputType : uint8_t {
FLOAT,
FLOAT2,
FLOAT3,
FLOAT4
};
struct PreprocessorDefine {
std::string name;
std::string value;
PreprocessorDefine(std::string name, std::string value) :
name(std::move(name)), value(std::move(value)) {}
};
using PreprocessorDefineList = std::vector<PreprocessorDefine>;
MaterialBuilder& noSamplerValidation(bool enabled) noexcept;
//! Set the name of this material.
MaterialBuilder& name(const char* name) noexcept;
//! Set the file name of this material file. Used in error reporting.
MaterialBuilder& fileName(const char* name) noexcept;
//! Set the shading model.
MaterialBuilder& shading(Shading shading) noexcept;
//! Set the interpolation mode.
MaterialBuilder& interpolation(Interpolation interpolation) noexcept;
//! Add a parameter (i.e., a uniform) to this material.
MaterialBuilder& parameter(const char* name, UniformType type,
ParameterPrecision precision = ParameterPrecision::DEFAULT) noexcept;
//! Add a parameter array to this material.
MaterialBuilder& parameter(const char* name, size_t size, UniformType type,
ParameterPrecision precision = ParameterPrecision::DEFAULT) noexcept;
//! Add a constant parameter to this material.
template<typename T>
using is_supported_constant_parameter_t = typename std::enable_if<
std::is_same<int32_t, T>::value ||
std::is_same<float, T>::value ||
std::is_same<bool, T>::value>::type;
template<typename T, typename = is_supported_constant_parameter_t<T>>
MaterialBuilder& constant(const char *name, ConstantType type, T defaultValue = 0);
/**
* Add a sampler parameter to this material.
*
* When SamplerType::SAMPLER_EXTERNAL is specified, format and precision are ignored.
*/
MaterialBuilder& parameter(const char* name, SamplerType samplerType,
SamplerFormat format = SamplerFormat::FLOAT,
ParameterPrecision precision = ParameterPrecision::DEFAULT) noexcept;
/// @copydoc parameter(SamplerType, SamplerFormat, ParameterPrecision, const char*)
MaterialBuilder& parameter(const char* name, SamplerType samplerType,
ParameterPrecision precision) noexcept;
MaterialBuilder& buffer(filament::BufferInterfaceBlock bib) noexcept;
//! Custom variables (all float4).
MaterialBuilder& variable(Variable v, const char* name) noexcept;
/**
* Require a specified attribute.
*
* position is always required and normal depends on the shading model.
*/
MaterialBuilder& require(VertexAttribute attribute) noexcept;
//! Specify the domain that this material will operate in.
MaterialBuilder& materialDomain(MaterialBuilder::MaterialDomain materialDomain) noexcept;
/**
* Set the code content of this material.
*
* Surface Domain
* --------------
*
* Materials in the SURFACE domain must declare a function:
* ~~~~~
* void material(inout MaterialInputs material) {
* prepareMaterial(material);
* material.baseColor.rgb = float3(1.0, 0.0, 0.0);
* }
* ~~~~~
* this function *must* call `prepareMaterial(material)` before it returns.
*
* Post-process Domain
* -------------------
*
* Materials in the POST_PROCESS domain must declare a function:
* ~~~~~
* void postProcess(inout PostProcessInputs postProcess) {
* postProcess.color = float4(1.0);
* }
* ~~~~~
*
* @param code The source code of the material.
* @param line The line number offset of the material, where 0 is the first line. Used for error
* reporting
*/
MaterialBuilder& material(const char* code, size_t line = 0) noexcept;
/**
* Set the callback used for resolving include directives.
* The default is no callback, which disallows all includes.
*/
MaterialBuilder& includeCallback(IncludeCallback callback) noexcept;
/**
* Set the vertex code content of this material.
*
* Surface Domain
* --------------
*
* Materials in the SURFACE domain must declare a function:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* void materialVertex(inout MaterialVertexInputs material) {
*
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Post-process Domain
* -------------------
*
* Materials in the POST_PROCESS domain must declare a function:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* void postProcessVertex(inout PostProcessVertexInputs postProcess) {
*
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* @param code The source code of the material.
* @param line The line number offset of the material, where 0 is the first line. Used for error
* reporting
*/
MaterialBuilder& materialVertex(const char* code, size_t line = 0) noexcept;
MaterialBuilder& quality(ShaderQuality quality) noexcept;
MaterialBuilder& featureLevel(FeatureLevel featureLevel) noexcept;
/**
* Set the blending mode for this material. When set to MASKED, alpha to coverage is turned on.
* You can override this behavior using alphaToCoverage(false).
*/
MaterialBuilder& blending(BlendingMode blending) noexcept;
/**
* Set the blending mode of the post-lighting color for this material.
* Only OPAQUE, TRANSPARENT and ADD are supported, the default is TRANSPARENT.
* This setting requires the material property "postLightingColor" to be set.
*/
MaterialBuilder& postLightingBlending(BlendingMode blending) noexcept;
//! Set the vertex domain for this material.
MaterialBuilder& vertexDomain(VertexDomain domain) noexcept;
/**
* How triangles are culled by default (doesn't affect points or lines, BACK by default).
* Material instances can override this.
*/
MaterialBuilder& culling(CullingMode culling) noexcept;
//! Enable / disable color-buffer write (enabled by default, material instances can override).
MaterialBuilder& colorWrite(bool enable) noexcept;
//! Enable / disable depth-buffer write (enabled by default for opaque, disabled for others, material instances can override).
MaterialBuilder& depthWrite(bool enable) noexcept;
//! Enable / disable depth based culling (enabled by default, material instances can override).
MaterialBuilder& depthCulling(bool enable) noexcept;
//! Enable / disable instanced primitives (disabled by default).
MaterialBuilder& instanced(bool enable) noexcept;
/**
* Double-sided materials don't cull faces, equivalent to culling(CullingMode::NONE).
* doubleSided() overrides culling() if called.
* When called with "false", this enables the capability for a run-time toggle.
*/
MaterialBuilder& doubleSided(bool doubleSided) noexcept;
/**
* Any fragment with an alpha below this threshold is clipped (MASKED blending mode only).
* The mask threshold can also be controlled by using the float material parameter called
* `_maskThreshold`, or by calling
* @ref filament::MaterialInstance::setMaskThreshold "MaterialInstance::setMaskThreshold".
*/
MaterialBuilder& maskThreshold(float threshold) noexcept;
/**
* Enables or disables alpha-to-coverage. When enabled, the coverage of a fragment is based
* on its alpha value. This parameter is only useful when MSAA is in use. Alpha to coverage
* is enabled automatically when the blend mode is set to MASKED; this behavior can be
* overridden by calling alphaToCoverage(false).
*/
MaterialBuilder& alphaToCoverage(bool enable) noexcept;
//! The material output is multiplied by the shadowing factor (UNLIT model only).
MaterialBuilder& shadowMultiplier(bool shadowMultiplier) noexcept;
//! This material casts transparent shadows. The blending mode must be TRANSPARENT or FADE.
MaterialBuilder& transparentShadow(bool transparentShadow) noexcept;
/**
* Reduces specular aliasing for materials that have low roughness. Turning this feature on also
* helps preserve the shapes of specular highlights as an object moves away from the camera.
* When turned on, two float material parameters are added to control the effect:
* `_specularAAScreenSpaceVariance` and `_specularAAThreshold`. You can also use
* @ref filament::MaterialInstance::setSpecularAntiAliasingVariance
* "MaterialInstance::setSpecularAntiAliasingVariance" and
* @ref filament::MaterialInstance::setSpecularAntiAliasingThreshold
* "setSpecularAntiAliasingThreshold"
*
* Disabled by default.
*/
MaterialBuilder& specularAntiAliasing(bool specularAntiAliasing) noexcept;
/**
* Sets the screen-space variance of the filter kernel used when applying specular
* anti-aliasing. The default value is set to 0.15. The specified value should be between 0 and
* 1 and will be clamped if necessary.
*/
MaterialBuilder& specularAntiAliasingVariance(float screenSpaceVariance) noexcept;
/**
* Sets the clamping threshold used to suppress estimation errors when applying specular
* anti-aliasing. The default value is set to 0.2. The specified value should be between 0 and 1
* and will be clamped if necessary.
*/
MaterialBuilder& specularAntiAliasingThreshold(float threshold) noexcept;
/**
* Enables or disables the index of refraction (IoR) change caused by the clear coat layer when
* present. When the IoR changes, the base color is darkened. Disabling this feature preserves
* the base color as initially specified.
*
* Enabled by default.
*/
MaterialBuilder& clearCoatIorChange(bool clearCoatIorChange) noexcept;
//! Enable / disable flipping of the Y coordinate of UV attributes, enabled by default.
MaterialBuilder& flipUV(bool flipUV) noexcept;
//! Enable / disable multi-bounce ambient occlusion, disabled by default on mobile.
MaterialBuilder& multiBounceAmbientOcclusion(bool multiBounceAO) noexcept;
//! Set the specular ambient occlusion technique. Disabled by default on mobile.
MaterialBuilder& specularAmbientOcclusion(SpecularAmbientOcclusion specularAO) noexcept;
//! Specify the refraction
MaterialBuilder& refractionMode(RefractionMode refraction) noexcept;
//! Specify the refraction type
MaterialBuilder& refractionType(RefractionType refractionType) noexcept;
//! Specifies how reflections should be rendered (default is DEFAULT).
MaterialBuilder& reflectionMode(ReflectionMode mode) noexcept;
//! Specifies how transparent objects should be rendered (default is DEFAULT).
MaterialBuilder& transparencyMode(TransparencyMode mode) noexcept;
/**
* Enable / disable custom surface shading. Custom surface shading requires the LIT
* shading model. In addition, the following function must be defined in the fragment
* block:
*
* ~~~~~
* vec3 surfaceShading(const MaterialInputs materialInputs,
* const ShadingData shadingData, const LightData lightData) {
*
* return vec3(1.0); // Compute surface shading with custom BRDF, etc.
* }
* ~~~~~
*
* This function is invoked once per light. Please refer to the materials documentation
* for more information about the different parameters.
*
* @param customSurfaceShading Enables or disables custom surface shading
*/
MaterialBuilder& customSurfaceShading(bool customSurfaceShading) noexcept;
/**
* Specifies desktop vs mobile; works in concert with TargetApi to determine the shader models
* (used to generate code) and final output representations (spirv and/or text).
*/
MaterialBuilder& platform(Platform platform) noexcept;
/**
* Specifies OpenGL, Vulkan, or Metal.
* This can be called repeatedly to build for multiple APIs.
* Works in concert with Platform to determine the shader models (used to generate code) and
* final output representations (spirv and/or text).
* If linking against filamat_lite, only `OPENGL` is allowed.
*/
MaterialBuilder& targetApi(TargetApi targetApi) noexcept;
/**
* Specifies the level of optimization to apply to the shaders (default is PERFORMANCE).
* If linking against filamat_lite, this _must_ be called with Optimization::NONE.
*/
MaterialBuilder& optimization(Optimization optimization) noexcept;
// TODO: this is present here for matc's "--print" flag, but ideally does not belong inside
// MaterialBuilder.
//! If true, will output the generated GLSL shader code to stdout.
MaterialBuilder& printShaders(bool printShaders) noexcept;
//! If true, will include debugging information in generated SPIRV.
MaterialBuilder& generateDebugInfo(bool generateDebugInfo) noexcept;
//! Specifies a list of variants that should be filtered out during code generation.
MaterialBuilder& variantFilter(filament::UserVariantFilterMask variantFilter) noexcept;
//! Adds a new preprocessor macro definition to the shader code. Can be called repeatedly.
MaterialBuilder& shaderDefine(const char* name, const char* value) noexcept;
//! Add a new fragment shader output variable. Only valid for materials in the POST_PROCESS domain.
MaterialBuilder& output(VariableQualifier qualifier, OutputTarget target, Precision precision,
OutputType type, const char* name, int location = -1) noexcept;
MaterialBuilder& enableFramebufferFetch() noexcept;
MaterialBuilder& vertexDomainDeviceJittered(bool enabled) noexcept;
/**
* Legacy morphing uses the data in the VertexAttribute slots (\c MORPH_POSITION_0, etc) and is
* limited to 4 morph targets. See filament::RenderableManager::Builder::morphing().
*/
MaterialBuilder& useLegacyMorphing() noexcept;
//! specify compute kernel group size
MaterialBuilder& groupSize(filament::math::uint3 groupSize) noexcept;
/**
* Build the material. If you are using the Filament engine with this library, you should use
* the job system provided by Engine.
*/
Package build(utils::JobSystem& jobSystem) noexcept;
public:
// The methods and types below are for internal use
/// @cond never
/**
* Add a subpass parameter to this material.
*/
MaterialBuilder& subpass(SubpassType subpassType,
SamplerFormat format, ParameterPrecision precision, const char* name) noexcept;
MaterialBuilder& subpass(SubpassType subpassType,
SamplerFormat format, const char* name) noexcept;
MaterialBuilder& subpass(SubpassType subpassType,
ParameterPrecision precision, const char* name) noexcept;
MaterialBuilder& subpass(SubpassType subpassType, const char* name) noexcept;
struct Parameter {
Parameter() noexcept: parameterType(INVALID) {}
// Sampler
Parameter(const char* paramName, SamplerType t, SamplerFormat f, ParameterPrecision p)
: name(paramName), size(1), precision(p), samplerType(t), format(f), parameterType(SAMPLER) { }
// Uniform
Parameter(const char* paramName, UniformType t, size_t typeSize, ParameterPrecision p)
: name(paramName), size(typeSize), uniformType(t), precision(p), parameterType(UNIFORM) { }
// Subpass
Parameter(const char* paramName, SubpassType t, SamplerFormat f, ParameterPrecision p)
: name(paramName), size(1), precision(p), subpassType(t), format(f), parameterType(SUBPASS) { }
utils::CString name;
size_t size;
UniformType uniformType;
ParameterPrecision precision;
SamplerType samplerType;
SubpassType subpassType;
SamplerFormat format;
enum {
INVALID,
UNIFORM,
SAMPLER,
SUBPASS
} parameterType;
bool isSampler() const { return parameterType == SAMPLER; }
bool isUniform() const { return parameterType == UNIFORM; }
bool isSubpass() const { return parameterType == SUBPASS; }
};
struct Output {
Output() noexcept = default;
Output(const char* outputName, VariableQualifier qualifier, OutputTarget target,
Precision precision, OutputType type, int location) noexcept
: name(outputName), qualifier(qualifier), target(target), precision(precision),
type(type), location(location) { }
utils::CString name;
VariableQualifier qualifier;
OutputTarget target;
Precision precision;
OutputType type;
int location;
};
struct Constant {
utils::CString name;
ConstantType type;
union {
int32_t i;
float f;
bool b;
} defaultValue;
};
static constexpr size_t MATERIAL_PROPERTIES_COUNT = filament::MATERIAL_PROPERTIES_COUNT;
using Property = filament::Property;
using PropertyList = bool[MATERIAL_PROPERTIES_COUNT];
using VariableList = utils::CString[MATERIAL_VARIABLES_COUNT];
using OutputList = std::vector<Output>;
static constexpr size_t MAX_COLOR_OUTPUT = filament::backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
static constexpr size_t MAX_DEPTH_OUTPUT = 1;
static_assert(MAX_COLOR_OUTPUT == 8,
"When updating MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT, manually update post_process_inputs.fs"
" and post_process.fs");
// Preview the first shader generated by the given CodeGenParams.
// This is used to run Static Code Analysis before generating a package.
std::string peek(filament::backend::ShaderStage type,
const CodeGenParams& params, const PropertyList& properties) noexcept;
// Returns true if any of the parameter samplers is of type samplerExternal
bool hasExternalSampler() const noexcept;
static constexpr size_t MAX_PARAMETERS_COUNT = 48;
static constexpr size_t MAX_SUBPASS_COUNT = 1;
static constexpr size_t MAX_BUFFERS_COUNT = 4;
using ParameterList = Parameter[MAX_PARAMETERS_COUNT];
using SubpassList = Parameter[MAX_SUBPASS_COUNT];
using BufferList = std::vector<std::unique_ptr<filament::BufferInterfaceBlock>>;
using ConstantList = std::vector<Constant>;
// returns the number of parameters declared in this material
uint8_t getParameterCount() const noexcept { return mParameterCount; }
// returns a list of at least getParameterCount() parameters
const ParameterList& getParameters() const noexcept { return mParameters; }
// returns the number of parameters declared in this material
uint8_t getSubpassCount() const noexcept { return mSubpassCount; }
// returns a list of at least getParameterCount() parameters
const SubpassList& getSubPasses() const noexcept { return mSubpasses; }
filament::UserVariantFilterMask getVariantFilter() const { return mVariantFilter; }
FeatureLevel getFeatureLevel() const noexcept { return mFeatureLevel; }
/// @endcond
struct Attribute {
std::string_view name;
AttributeType type;
MaterialBuilder::VertexAttribute location;
std::string getAttributeName() const noexcept {
return "mesh_" + std::string{ name };
}
std::string getDefineName() const noexcept {
std::string uppercase{ name };
transform(uppercase.cbegin(), uppercase.cend(), uppercase.begin(), ::toupper);
return "HAS_ATTRIBUTE_" + uppercase;
}
};
using AttributeDatabase = std::array<Attribute, filament::backend::MAX_VERTEX_ATTRIBUTE_COUNT>;
static inline AttributeDatabase const& getAttributeDatabase() noexcept {
return sAttributeDatabase;
}
private:
static const AttributeDatabase sAttributeDatabase;
void prepareToBuild(MaterialInfo& info) noexcept;
// Return true if the shader is syntactically and semantically valid.
// This method finds all the properties defined in the fragment and
// vertex shaders of the material.
bool findAllProperties(CodeGenParams const& semanticCodeGenParams) noexcept;
// Multiple calls to findProperties accumulate the property sets across fragment
// and vertex shaders in mProperties.
bool findProperties(filament::backend::ShaderStage type,
MaterialBuilder::PropertyList& allProperties,
CodeGenParams const& semanticCodeGenParams) noexcept;
bool runSemanticAnalysis(MaterialInfo const& info,
CodeGenParams const& semanticCodeGenParams) noexcept;
bool checkLiteRequirements() noexcept;
bool checkMaterialLevelFeatures(MaterialInfo const& info) const noexcept;
void writeCommonChunks(ChunkContainer& container, MaterialInfo& info) const noexcept;
void writeSurfaceChunks(ChunkContainer& container) const noexcept;
bool generateShaders(
utils::JobSystem& jobSystem,
const std::vector<filamat::Variant>& variants, ChunkContainer& container,
const MaterialInfo& info) const noexcept;
bool hasCustomVaryings() const noexcept;
bool needsStandardDepthProgram() const noexcept;
bool isLit() const noexcept { return mShading != filament::Shading::UNLIT; }
utils::CString mMaterialName;
utils::CString mFileName;
class ShaderCode {
public:
void setLineOffset(size_t offset) noexcept { mLineOffset = offset; }
void setUnresolved(const utils::CString& code) noexcept {
mIncludesResolved = false;
mCode = code;
}
// Resolve all the #include directives, returns true if successful.
bool resolveIncludes(IncludeCallback callback, const utils::CString& fileName) noexcept;
const utils::CString& getResolved() const noexcept {
assert(mIncludesResolved);
return mCode;
}
size_t getLineOffset() const noexcept { return mLineOffset; }
private:
utils::CString mCode;
size_t mLineOffset = 0;
bool mIncludesResolved = false;
};
ShaderCode mMaterialFragmentCode;
ShaderCode mMaterialVertexCode;
IncludeCallback mIncludeCallback = nullptr;
PropertyList mProperties;
ParameterList mParameters;
ConstantList mConstants;
SubpassList mSubpasses;
VariableList mVariables;
OutputList mOutputs;
BufferList mBuffers;
ShaderQuality mShaderQuality = ShaderQuality::DEFAULT;
FeatureLevel mFeatureLevel = FeatureLevel::FEATURE_LEVEL_1;
BlendingMode mBlendingMode = BlendingMode::OPAQUE;
BlendingMode mPostLightingBlendingMode = BlendingMode::TRANSPARENT;
CullingMode mCullingMode = CullingMode::BACK;
Shading mShading = Shading::LIT;
MaterialDomain mMaterialDomain = MaterialDomain::SURFACE;
RefractionMode mRefractionMode = RefractionMode::NONE;
RefractionType mRefractionType = RefractionType::SOLID;
ReflectionMode mReflectionMode = ReflectionMode::DEFAULT;
Interpolation mInterpolation = Interpolation::SMOOTH;
VertexDomain mVertexDomain = VertexDomain::OBJECT;
TransparencyMode mTransparencyMode = TransparencyMode::DEFAULT;
filament::AttributeBitset mRequiredAttributes;
float mMaskThreshold = 0.4f;
float mSpecularAntiAliasingVariance = 0.15f;
float mSpecularAntiAliasingThreshold = 0.2f;
filament::math::uint3 mGroupSize = { 1, 1, 1 };
bool mShadowMultiplier = false;
bool mTransparentShadow = false;
uint8_t mParameterCount = 0;
uint8_t mSubpassCount = 0;
bool mDoubleSided = false;
bool mDoubleSidedCapability = false;
bool mColorWrite = true;
bool mDepthTest = true;
bool mInstanced = false;
bool mDepthWrite = true;
bool mDepthWriteSet = false;
bool mAlphaToCoverage = false;
bool mAlphaToCoverageSet = false;
bool mSpecularAntiAliasing = false;
bool mClearCoatIorChange = true;
bool mFlipUV = true;
bool mMultiBounceAO = false;
bool mMultiBounceAOSet = false;
SpecularAmbientOcclusion mSpecularAO = SpecularAmbientOcclusion::NONE;
bool mSpecularAOSet = false;
bool mCustomSurfaceShading = false;
bool mEnableFramebufferFetch = false;
bool mVertexDomainDeviceJittered = false;
bool mUseLegacyMorphing = false;
PreprocessorDefineList mDefines;
filament::UserVariantFilterMask mVariantFilter = {};
bool mNoSamplerValidation = false;
};
} // namespace filamat
template<> struct utils::EnableBitMaskOperators<filamat::MaterialBuilder::TargetApi>
: public std::true_type {};
#endif

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMAT_PACKAGE_H
#define TNT_FILAMAT_PACKAGE_H
#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
#include <cstddef>
#include <functional>
#include <utils/compiler.h>
namespace filamat {
class UTILS_PUBLIC Package {
public:
Package() = default;
// Regular constructor
explicit Package(size_t size) : mSize(size) {
mPayload = new uint8_t[size];
}
Package(const void* src, size_t size) : Package(size) {
memcpy(mPayload, src, size);
}
// Move Constructor
Package(Package&& other) noexcept : mPayload(other.mPayload), mSize(other.mSize),
mValid(other.mValid) {
other.mPayload = nullptr;
other.mSize = 0;
other.mValid = false;
}
// Move assignment
Package& operator=(Package&& other) noexcept {
std::swap(mPayload, other.mPayload);
std::swap(mSize, other.mSize);
std::swap(mValid, other.mValid);
return *this;
}
// Copy assignment operator disallowed.
Package& operator=(const Package& other) = delete;
// Copy constructor disallowed.
Package(const Package& other) = delete;
~Package() {
delete[] mPayload;
}
uint8_t* getData() const noexcept {
return mPayload;
}
size_t getSize() const noexcept {
return mSize;
}
uint8_t* getEnd() const noexcept {
return mPayload + mSize;
}
void setValid(bool valid) noexcept {
mValid = valid;
}
bool isValid() const noexcept {
return mValid;
}
static Package invalidPackage() {
Package package(0);
package.setValid(false);
return package;
}
private:
uint8_t* mPayload = nullptr;
size_t mSize = 0;
bool mValid = true;
};
} // namespace filamat
#endif

View File

@@ -0,0 +1,339 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_IBL_PREFILTER_IBLPREFILTER_H
#define TNT_IBL_PREFILTER_IBLPREFILTER_H
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <filament/Texture.h>
namespace filament {
class Engine;
class View;
class Scene;
class Renderer;
class Material;
class MaterialInstance;
class VertexBuffer;
class IndexBuffer;
class Camera;
class Texture;
} // namespace filament
/**
* IBLPrefilterContext creates and initializes GPU state common to all environment map filters
* supported. Typically, only one instance per filament Engine of this object needs to exist.
*
* Usage Example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
*
* IBLPrefilterContext context(engine);
* IBLPrefilterContext::SpecularFilter filter(context);
* Texture* texture = filter(environment_cubemap);
*
* IndirectLight* indirectLight = IndirectLight::Builder()
* .reflections(texture)
* .build(engine);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
class UTILS_PUBLIC IBLPrefilterContext {
public:
enum class Kernel : uint8_t {
D_GGX, // Trowbridge-reitz distribution
};
/**
* Creates an IBLPrefilter context.
* @param engine filament engine to use
*/
explicit IBLPrefilterContext(filament::Engine& engine);
/**
* Destroys all GPU resources created during initialization.
*/
~IBLPrefilterContext() noexcept;
// not copyable
IBLPrefilterContext(IBLPrefilterContext const&) = delete;
IBLPrefilterContext& operator=(IBLPrefilterContext const&) = delete;
// movable
IBLPrefilterContext(IBLPrefilterContext&& rhs) noexcept;
IBLPrefilterContext& operator=(IBLPrefilterContext&& rhs) noexcept;
// -------------------------------------------------------------------------------------------
/**
* EquirectangularToCubemap is use to convert an equirectangluar image to a cubemap.
*/
class EquirectangularToCubemap {
public:
/**
* Creates a EquirectangularToCubemap processor.
* @param context IBLPrefilterContext to use
*/
explicit EquirectangularToCubemap(IBLPrefilterContext& context);
/**
* Destroys all GPU resources created during initialization.
*/
~EquirectangularToCubemap() noexcept;
EquirectangularToCubemap(EquirectangularToCubemap const&) = delete;
EquirectangularToCubemap& operator=(EquirectangularToCubemap const&) = delete;
EquirectangularToCubemap(EquirectangularToCubemap&& rhs) noexcept;
EquirectangularToCubemap& operator=(EquirectangularToCubemap&& rhs) noexcept;
/**
* Converts an equirectangular image to a cubemap.
* @param equirectangular Texture to convert to a cubemap.
* - Can't be null.
* - Must be a 2d texture
* - Must have equirectangular geometry, that is width == 2*height.
* - Must be allocated with all mip levels.
* - Must be SAMPLEABLE
* @param outCubemap Output cubemap. If null the texture is automatically created
* with default parameters (size of 256 with 9 levels).
* - Must be a cubemap
* - Must have SAMPLEABLE and COLOR_ATTACHMENT usage bits
* @return returns outCubemap
*/
filament::Texture* operator()(
filament::Texture const* equirectangular,
filament::Texture* outCubemap = nullptr);
private:
IBLPrefilterContext& mContext;
filament::Material* mEquirectMaterial = nullptr;
};
/**
* IrradianceFilter is a GPU based implementation of the diffuse probe pre-integration filter.
* An instance of IrradianceFilter is needed per filter configuration. A filter configuration
* contains the filter's kernel and sample count.
*/
class IrradianceFilter {
public:
using Kernel = Kernel;
/**
* Filter configuration.
*/
struct Config {
uint16_t sampleCount = 1024u; //!< filter sample count (max 2048)
Kernel kernel = Kernel::D_GGX; //!< filter kernel
};
/**
* Filtering options for the current environment.
*/
struct Options {
float hdrLinear = 1024.0f; //!< no HDR compression up to this value
float hdrMax = 16384.0f; //!< HDR compression between hdrLinear and hdrMax
float lodOffset = 2.0f; //!< Good values are 2.0 or 3.0. Higher values help with heavily HDR inputs.
bool generateMipmap = true; //!< set to false if the input environment map already has mipmaps
};
/**
* Creates a IrradianceFilter processor.
* @param context IBLPrefilterContext to use
* @param config Configuration of the filter
*/
IrradianceFilter(IBLPrefilterContext& context, Config config);
/**
* Creates a filter with the default configuration.
* @param context IBLPrefilterContext to use
*/
explicit IrradianceFilter(IBLPrefilterContext& context);
/**
* Destroys all GPU resources created during initialization.
*/
~IrradianceFilter() noexcept;
IrradianceFilter(IrradianceFilter const&) = delete;
IrradianceFilter& operator=(IrradianceFilter const&) = delete;
IrradianceFilter(IrradianceFilter&& rhs) noexcept;
IrradianceFilter& operator=(IrradianceFilter&& rhs) noexcept;
/**
* Generates an irradiance cubemap. Mipmaps are not generated even if present.
* @param options Options for this environment
* @param environmentCubemap Environment cubemap (input). Can't be null.
* This cubemap must be SAMPLEABLE and must have all its
* levels allocated. If Options.generateMipmap is true,
* the mipmap levels will be overwritten, otherwise
* it is assumed that all levels are correctly initialized.
* @param outIrradianceTexture Output irradiance texture or, if null, it is
* automatically created with some default parameters.
* outIrradianceTexture must be a cubemap, it must have
* at least COLOR_ATTACHMENT and SAMPLEABLE usages.
*
* @return returns outIrradianceTexture
*/
filament::Texture* operator()(Options options,
filament::Texture const* environmentCubemap,
filament::Texture* outIrradianceTexture = nullptr);
/**
* Generates a prefiltered cubemap.
* @param environmentCubemap Environment cubemap (input). Can't be null.
* This cubemap must be SAMPLEABLE and must have all its
* levels allocated. If Options.generateMipmap is true,
* the mipmap levels will be overwritten, otherwise
* it is assumed that all levels are correctly initialized.
* @param outIrradianceTexture Output irradiance texture or, if null, it is
* automatically created with some default parameters.
* outIrradianceTexture must be a cubemap, it must have
* at least COLOR_ATTACHMENT and SAMPLEABLE usages.
*
* @return returns outReflectionsTexture
*/
filament::Texture* operator()(
filament::Texture const* environmentCubemap,
filament::Texture* outIrradianceTexture = nullptr);
private:
filament::Texture* createIrradianceTexture();
IBLPrefilterContext& mContext;
filament::Material* mKernelMaterial = nullptr;
filament::Texture* mKernelTexture = nullptr;
uint32_t mSampleCount = 0u;
};
/**
* SpecularFilter is a GPU based implementation of the specular probe pre-integration filter.
* An instance of SpecularFilter is needed per filter configuration. A filter configuration
* contains the filter's kernel and sample count.
*/
class SpecularFilter {
public:
using Kernel = Kernel;
/**
* Filter configuration.
*/
struct Config {
uint16_t sampleCount = 1024u; //!< filter sample count (max 2048)
uint8_t levelCount = 5u; //!< number of roughness levels
Kernel kernel = Kernel::D_GGX; //!< filter kernel
};
/**
* Filtering options for the current environment.
*/
struct Options {
float hdrLinear = 1024.0f; //!< no HDR compression up to this value
float hdrMax = 16384.0f; //!< HDR compression between hdrLinear and hdrMax
float lodOffset = 1.0f; //!< Good values are 1.0 or 2.0. Higher values help with heavily HDR inputs.
bool generateMipmap = true; //!< set to false if the input environment map already has mipmaps
};
/**
* Creates a SpecularFilter processor.
* @param context IBLPrefilterContext to use
* @param config Configuration of the filter
*/
SpecularFilter(IBLPrefilterContext& context, Config config);
/**
* Creates a filter with the default configuration.
* @param context IBLPrefilterContext to use
*/
explicit SpecularFilter(IBLPrefilterContext& context);
/**
* Destroys all GPU resources created during initialization.
*/
~SpecularFilter() noexcept;
SpecularFilter(SpecularFilter const&) = delete;
SpecularFilter& operator=(SpecularFilter const&) = delete;
SpecularFilter(SpecularFilter&& rhs) noexcept;
SpecularFilter& operator=(SpecularFilter&& rhs) noexcept;
/**
* Generates a prefiltered cubemap.
* @param options Options for this environment
* @param environmentCubemap Environment cubemap (input). Can't be null.
* This cubemap must be SAMPLEABLE and must have all its
* levels allocated. If Options.generateMipmap is true,
* the mipmap levels will be overwritten, otherwise
* it is assumed that all levels are correctly initialized.
* @param outReflectionsTexture Output prefiltered texture or, if null, it is
* automatically created with some default parameters.
* outReflectionsTexture must be a cubemap, it must have
* at least COLOR_ATTACHMENT and SAMPLEABLE usages and at
* least the same number of levels than requested by Config.
* @return returns outReflectionsTexture
*/
filament::Texture* operator()(Options options,
filament::Texture const* environmentCubemap,
filament::Texture* outReflectionsTexture = nullptr);
/**
* Generates a prefiltered cubemap.
* @param environmentCubemap Environment cubemap (input). Can't be null.
* This cubemap must be SAMPLEABLE and must have all its
* levels allocated. All mipmap levels will be overwritten.
* @param outReflectionsTexture Output prefiltered texture or, if null, it is
* automatically created with some default parameters.
* outReflectionsTexture must be a cubemap, it must have
* at least COLOR_ATTACHMENT and SAMPLEABLE usages and at
* least the same number of levels than requested by Config.
* @return returns outReflectionsTexture
*/
filament::Texture* operator()(
filament::Texture const* environmentCubemap,
filament::Texture* outReflectionsTexture = nullptr);
// TODO: option for progressive filtering
// TODO: add a callback for when the processing is done?
private:
filament::Texture* createReflectionsTexture();
IBLPrefilterContext& mContext;
filament::Material* mKernelMaterial = nullptr;
filament::Texture* mKernelTexture = nullptr;
uint32_t mSampleCount = 0u;
uint8_t mLevelCount = 1u;
};
private:
friend class Filter;
filament::Engine& mEngine;
filament::Renderer* mRenderer{};
filament::Scene* mScene{};
filament::VertexBuffer* mVertexBuffer{};
filament::IndexBuffer* mIndexBuffer{};
filament::Camera* mCamera{};
utils::Entity mFullScreenQuadEntity{};
utils::Entity mCameraEntity{};
filament::View* mView{};
filament::Material* mIntegrationMaterial{};
filament::Material* mIrradianceIntegrationMaterial{};
};
#endif //TNT_IBL_PREFILTER_IBLPREFILTER_H

View File

@@ -0,0 +1,120 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_FILAMENT_FILAMESHIO_MESHREADER_H
#define TNT_FILAMENT_FILAMESHIO_MESHREADER_H
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <utils/CString.h>
namespace filament {
class Engine;
class VertexBuffer;
class IndexBuffer;
class MaterialInstance;
}
namespace utils {
class Path;
}
namespace filamesh {
/**
* This API can be used to read meshes stored in the "filamesh" format produced
* by the command line tool of the same name. This file format is documented in
* "docs/filamesh.md" in the Filament distribution.
*/
class UTILS_PUBLIC MeshReader {
public:
using Callback = void(*)(void* buffer, size_t size, void* user);
// Class to track material instances
class MaterialRegistry {
public:
MaterialRegistry();
MaterialRegistry(const MaterialRegistry& rhs);
MaterialRegistry& operator=(const MaterialRegistry& rhs);
~MaterialRegistry();
MaterialRegistry(MaterialRegistry&&);
MaterialRegistry& operator=(MaterialRegistry&&);
filament::MaterialInstance* getMaterialInstance(const utils::CString& name);
void registerMaterialInstance(const utils::CString& name,
filament::MaterialInstance* materialInstance);
void unregisterMaterialInstance(const utils::CString& name);
void unregisterAll();
size_t numRegistered() const noexcept;
void getRegisteredMaterials(filament::MaterialInstance** materialList,
utils::CString* materialNameList) const;
void getRegisteredMaterials(filament::MaterialInstance** materialList) const;
void getRegisteredMaterialNames(utils::CString* materialNameList) const;
private:
struct MaterialRegistryImpl;
MaterialRegistryImpl* mImpl;
};
struct Mesh {
utils::Entity renderable;
filament::VertexBuffer* vertexBuffer = nullptr;
filament::IndexBuffer* indexBuffer = nullptr;
};
/**
* Loads a filamesh renderable from the specified file. The material registry
* can be used to provide named materials. If a material found in the filamesh
* file cannot be matched to a material in the registry, a default material is
* used instead. The default material can be overridden by adding a material
* named "DefaultMaterial" to the registry.
*/
static Mesh loadMeshFromFile(filament::Engine* engine,
const utils::Path& path,
MaterialRegistry& materials);
/**
* Loads a filamesh renderable from an in-memory buffer. The material registry
* can be used to provide named materials. If a material found in the filamesh
* file cannot be matched to a material in the registry, a default material is
* used instead. The default material can be overridden by adding a material
* named "DefaultMaterial" to the registry.
*/
static Mesh loadMeshFromBuffer(filament::Engine* engine,
void const* data, Callback destructor, void* user,
MaterialRegistry& materials);
/**
* Loads a filamesh renderable from an in-memory buffer. The material registry
* can be used to provide named materials. All the primitives of the decoded
* renderable are assigned the specified default material.
*/
static Mesh loadMeshFromBuffer(filament::Engine* engine,
void const* data, Callback destructor, void* user,
filament::MaterialInstance* defaultMaterial);
};
} // namespace filamesh
#endif // TNT_FILAMENT_FILAMESHIO_MESHREADER_H

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_GEOMETRY_SURFACEORIENTATION_H
#define TNT_GEOMETRY_SURFACEORIENTATION_H
#include <math/quat.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/compiler.h>
namespace filament {
/**
* Mesh-related utilities.
*/
namespace geometry {
struct OrientationBuilderImpl;
struct OrientationImpl;
/**
* The surface orientation helper can be used to populate Filament-style TANGENTS buffers.
*/
class UTILS_PUBLIC SurfaceOrientation {
public:
/**
* The Builder is used to construct an immutable surface orientation helper.
*
* Clients provide pointers into their own data, which is synchronously consumed during build().
* At a minimum, clients must supply a vertex count. They can supply data in any of the
* following combinations:
*
* 1. normals only ........................... not recommended, selects arbitrary orientation
* 2. normals + tangents ..................... sign of W determines bitangent orientation
* 3. normals + uvs + positions + indices .... selects Lengyels Method
* 4. positions + indices .................... generates normals for flat shading only
*
* Additionally, the client-side data has the following type constraints:
*
* - Normals must be float3
* - Tangents must be float4
* - UVs must be float2
* - Positions must be float3
* - Triangles must be uint3 or ushort3
*
* Currently, mikktspace is not supported because it requires re-indexing the mesh. Instead
* we use the method described by Eric Lengyel in "Foundations of Game Engine Development"
* (Volume 2, Chapter 7).
*/
class Builder {
public:
Builder() noexcept;
~Builder() noexcept;
Builder(Builder&& that) noexcept;
Builder& operator=(Builder&& that) noexcept;
/**
* This attribute is required.
*/
Builder& vertexCount(size_t vertexCount) noexcept;
Builder& normals(const filament::math::float3*, size_t stride = 0) noexcept;
Builder& tangents(const filament::math::float4*, size_t stride = 0) noexcept;
Builder& uvs(const filament::math::float2*, size_t stride = 0) noexcept;
Builder& positions(const filament::math::float3*, size_t stride = 0) noexcept;
Builder& triangleCount(size_t triangleCount) noexcept;
Builder& triangles(const filament::math::uint3*) noexcept;
Builder& triangles(const filament::math::ushort3*) noexcept;
/**
* Generates quats or returns null if the submitted data is an incomplete combination.
*/
SurfaceOrientation* build();
private:
OrientationBuilderImpl* mImpl;
Builder(const Builder&) = delete;
Builder& operator=(const Builder&) = delete;
};
~SurfaceOrientation() noexcept;
SurfaceOrientation(SurfaceOrientation&& that) noexcept;
SurfaceOrientation& operator=(SurfaceOrientation&& that) noexcept;
/**
* Returns the vertex count.
*/
size_t getVertexCount() const noexcept;
/**
* Converts quaternions into the desired output format and writes up to "quatCount"
* to the given output pointer. Normally quatCount should be equal to the vertex count.
* The optional stride is the desired quat-to-quat stride in bytes.
* @{
*/
void getQuats(filament::math::quatf* out, size_t quatCount, size_t stride = 0) const noexcept;
void getQuats(filament::math::short4* out, size_t quatCount, size_t stride = 0) const noexcept;
void getQuats(filament::math::quath* out, size_t quatCount, size_t stride = 0) const noexcept;
/**
* @}
*/
private:
SurfaceOrientation(OrientationImpl*) noexcept;
SurfaceOrientation(const SurfaceOrientation&) = delete;
SurfaceOrientation& operator=(const SurfaceOrientation&) = delete;
OrientationImpl* mImpl;
friend struct OrientationBuilderImpl;
};
} // namespace geometry
} // namespace filament
#endif // TNT_GEOMETRY_SURFACEORIENTATION_H

View File

@@ -0,0 +1,334 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_GEOMETRY_TANGENTSPACEMESH_H
#define TNT_GEOMETRY_TANGENTSPACEMESH_H
#include <math/quat.h>
#include <math/vec3.h>
#include <math/vec4.h>
namespace filament {
namespace geometry {
struct TangentSpaceMeshInput;
struct TangentSpaceMeshOutput;
/**
* This class builds Filament-style TANGENTS buffers given an input mesh.
*
* This class enables the client to chose between several algorithms. The client can retrieve the
* result through the `get` methods on the class. If the chosen algorithm did not remesh the input,
* the client is advised to just use the data they provided instead of querying. For example, if
* the chosen method is Algorithm::FRISVAD, then the client should not need to call getPositions().
* We will simply copy from the input `positions` in that case.
*
* If the client calls getPositions() and positions were not provided as input, we will throw
* and exception. Similar behavior will apply to UVs.
*
* This class supersedes the implementation in SurfaceOrientation.h
*/
class TangentSpaceMesh {
public:
enum class Algorithm : uint8_t {
/**
* default
*
* Tries to select the best possible algorithm given the input. The corresponding algorithms
* are detailed in the corresponding enums.
* <pre>
* INPUT ALGORITHM
* -----------------------------------------------------------
* normals FRISVAD
* positions + indices FLAT_SHADING
* normals + uvs + positions + indices MIKKTSPACE
* </pre>
*/
DEFAULT = 0,
/**
* mikktspace
*
* **Requires**: `normals + uvs + positions + indices` <br/>
* **Reference**:
* - Mikkelsen, M., 2008. Simulation of wrinkled surfaces revisited.
* - https://github.com/mmikk/MikkTSpace
* - https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview
*
* **Note**: Will remesh
*/
MIKKTSPACE = 1,
/**
* Lengyel's method
*
* **Requires**: `normals + uvs + positions + indices` <br/>
* **Reference**: Lengyel, E., 2019. Foundations of Game Engine Development: Rendering. Terathon
* Software LLC.. (Chapter 7)
*/
LENGYEL = 2,
/**
* Hughes-Moller method
*
* **Requires**: `normals` <br/>
* **Reference**:
* - Hughes, J.F. and Moller, T., 1999. Building an orthonormal basis from a unit
* vector. journal of graphics tools, 4(4), pp.33-35.
* - Parker, S.G., Bigler, J., Dietrich, A., Friedrich, H., Hoberock, J., Luebke, D.,
* McAllister, D., McGuire, M., Morley, K., Robison, A. and Stich, M., 2010.
* Optix: a general purpose ray tracing engine. Acm transactions on graphics (tog),
* 29(4), pp.1-13.
* **Note**: We implement the Optix variant, which is documented in the second reference above.
*/
HUGHES_MOLLER = 3,
/**
* Frisvad's method
*
* **Requires**: `normals` <br/>
* **Reference**:
* - Frisvad, J.R., 2012. Building an orthonormal basis from a 3D unit vector without
* normalization. Journal of Graphics Tools, 16(3), pp.151-159.
* - http://people.compute.dtu.dk/jerf/code/hairy/
*/
FRISVAD = 4,
/**
* Flat Shading
*
* **Requires**: `positions + indices` <br/>
* **Note**: Will remesh
*/
FLAT_SHADING = 5
};
/**
* Use this class to provide input to the TangentSpaceMesh computation. **Important**:
* Computation of the tangent space is intended to be synchronous (working on the same thread).
* Client is expected to keep the input immutable and in a good state for the duration of both
* computation *and* query. That is, when querying the result of the tangent spaces, part of the
* result might depend on the input data.
*/
class Builder {
public:
Builder() noexcept;
~Builder() noexcept;
/**
* Move constructor
*/
Builder(Builder&& that) noexcept;
/**
* Move constructor
*/
Builder& operator=(Builder&& that) noexcept;
Builder(Builder const&) = delete;
Builder& operator=(Builder const&) = delete;
/**
* Client must provide this parameter
*
* @param vertexCount The input number of vertcies
*/
Builder& vertexCount(size_t vertexCount) noexcept;
/**
* @param normals The input normals
* @param stride The stride for iterating through `normals`
* @return Builder
*/
Builder& normals(filament::math::float3 const* normals, size_t stride = 0) noexcept;
/**
* @param tangents The input tangents. The `w` component is for use with
* Algorithm::SIGN_OF_W.
* @param stride The stride for iterating through `tangents`
* @return Builder
*/
Builder& tangents(filament::math::float4 const* tangents, size_t stride = 0) noexcept;
/**
* @param uvs The input uvs
* @param stride The stride for iterating through `uvs`
* @return Builder
*/
Builder& uvs(filament::math::float2 const* uvs, size_t stride = 0) noexcept;
/**
* @param positions The input positions
* @param stride The stride for iterating through `positions`
* @return Builder
*/
Builder& positions(filament::math::float3 const* positions, size_t stride = 0) noexcept;
Builder& triangleCount(size_t triangleCount) noexcept;
Builder& triangles(filament::math::uint3 const* triangles) noexcept;
Builder& triangles(filament::math::ushort3 const* triangles) noexcept;
Builder& algorithm(Algorithm algorithm) noexcept;
/**
* Computes the tangent space mesh. The resulting mesh object is owned by the callee. The
* callee must call TangentSpaceMesh::destroy on the object once they are finished with it.
*
* The state of the Builder will be reset after each call to build(). The client needs to
* populate the builder with parameters again if they choose to re-use it.
*
* @return A TangentSpaceMesh
*/
TangentSpaceMesh* build();
private:
TangentSpaceMesh* mMesh = nullptr;
};
/**
* Destory the mesh object
* @param mesh A pointer to a TangentSpaceMesh ready to be destroyed
*/
static void destroy(TangentSpaceMesh* mesh) noexcept;
/**
* Move constructor
*/
TangentSpaceMesh(TangentSpaceMesh&& that) noexcept;
/**
* Move constructor
*/
TangentSpaceMesh& operator=(TangentSpaceMesh&& that) noexcept;
TangentSpaceMesh(TangentSpaceMesh const&) = delete;
TangentSpaceMesh& operator=(TangentSpaceMesh const&) = delete;
/**
* Number of output vertices
*
* The number of output vertices can be the same as the input if the selected algorithm did not
* "remesh" the input.
*
* @return The number of vertices
*/
size_t getVertexCount() const noexcept;
/**
* Get output vertex positions.
* Assumes the `out` param is at least of getVertexCount() length (while accounting for
* `stride`). The output vertices can be the same as the input if the selected algorithm did
* not "remesh" the input. The remeshed vertices are not guarranteed to have correlation in
* order with the input mesh.
*
* @param out Client-allocated array that will be used for copying out positions.
* @param stride Stride for iterating through `out`
*/
void getPositions(filament::math::float3* out, size_t stride = 0) const;
/**
* Get output UVs.
* Assumes the `out` param is at least of getVertexCount() length (while accounting for
* `stride`). The output uvs can be the same as the input if the selected algorithm did
* not "remesh" the input. The remeshed UVs are not guarranteed to have correlation in order
* with the input mesh.
*
* @param out Client-allocated array that will be used for copying out UVs.
* @param stride Stride for iterating through `out`
*/
void getUVs(filament::math::float2* out, size_t stride = 0) const;
/**
* Get output tangent space.
* Assumes the `out` param is at least of getVertexCount() length (while accounting for
* `stride`).
*
* @param out Client-allocated array that will be used for copying out tangent space in
* 32-bit floating points.
* @param stride Stride for iterating through `out`
*/
void getQuats(filament::math::quatf* out, size_t stride = 0) const noexcept;
/**
* Get output tangent space.
* Assumes the `out` param is at least of getVertexCount() length (while accounting for
* `stride`).
*
* @param out Client-allocated array that will be used for copying out tangent space in
* 16-bit signed integers.
* @param stride Stride for iterating through `out`
*/
void getQuats(filament::math::short4* out, size_t stride = 0) const noexcept;
/**
* Get output tangent space.
* Assumes the `out` param is at least of getVertexCount() length (while accounting for
* `stride`).
*
* @param out Client-allocated array that will be used for copying out tangent space in
* 16-bit floating points.
* @param stride Stride for iterating through `out`
*/
void getQuats(filament::math::quath* out, size_t stride = 0) const noexcept;
/**
* Get number of output triangles.
* The number of output triangles is the same as the number of input triangles. However, when a
* "remesh" is carried out the output triangles are not guarranteed to have any correlation with
* the input.
*
* @return The number of vertices
*/
size_t getTriangleCount() const noexcept;
/**
* Get output triangles.
* This method assumes that the `out` param provided by the client is at least of
* getTriangleCount() length. If the client calls getTriangles() and triangles were not
* provided as input, we will throw and exception.
*
* @param out Client's array for the output triangles in unsigned 32-bit indices.
*/
void getTriangles(filament::math::uint3* out) const;
/**
* Get output triangles.
* This method assumes that the `out` param provided by the client is at least of
* getTriangleCount() length. If the client calls getTriangles() and triangles were not
* provided as input, we will throw and exception.
*
* @param out Client's array for the output triangles in unsigned 16-bit indices.
*/
void getTriangles(filament::math::ushort3* out) const;
/**
* @return The algorithm used to compute the output mesh.
*/
Algorithm getAlgorithm() const noexcept;
private:
~TangentSpaceMesh() noexcept;
TangentSpaceMesh() noexcept;
TangentSpaceMeshInput* mInput;
TangentSpaceMeshOutput* mOutput;
friend class Builder;
};
} // namespace geometry
} // namespace filament
#endif //TNT_GEOMETRY_TANGENTSPACEMESH_H

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* 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.
*/
#ifndef TNT_GEOMETRY_TRANSCODER_H
#define TNT_GEOMETRY_TRANSCODER_H
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
namespace geometry {
enum class ComponentType {
BYTE, //!< If normalization is enabled, this maps from [-127,127] to [-1,+1]
UBYTE, //!< If normalization is enabled, this maps from [0,255] to [0, +1]
SHORT, //!< If normalization is enabled, this maps from [-32767,32767] to [-1,+1]
USHORT, //!< If normalization is enabled, this maps from [0,65535] to [0, +1]
HALF, //!< 1 sign bit, 5 exponent bits, and 5 mantissa bits.
FLOAT, //!< Standard 32-bit float
};
/**
* Creates a function object that can convert vertex attribute data into tightly packed floats.
*
* This is especially useful for 3-component formats which are not supported by all backends.
* e.g. The Vulkan minspec includes float3 but not short3.
*
* Usage Example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* using filament::geometry::Transcoder;
* using filament::geometry::ComponentType;
*
* Transcoder transcode({
* .componentType = ComponentType::BYTE,
* .normalized = true,
* .componentCount = 3,
* .inputStrideBytes = 0
* });
*
* transcode(outputPtr, inputPtr, count);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The interpretation of signed normalized data is consistent with Vulkan and OpenGL ES 3.0+.
* Note that this slightly differs from earlier versions of OpenGL ES. For example, a signed byte
* value of -127 maps exactly to -1.0f under ES3 and VK rules, but not ES2.
*/
class UTILS_PUBLIC Transcoder {
public:
/**
* Describes the format of all input data that get passed to this transcoder object.
*/
struct Config {
ComponentType componentType;
bool normalized;
uint32_t componentCount;
uint32_t inputStrideBytes = 0; //!< If stride is 0, the transcoder assumes tight packing.
};
/**
* Creates an immutable function object with the specified configuration.
*
* The config is not passed by const reference to allow for type inference at the call site.
*/
Transcoder(Config config) noexcept : mConfig(config) {}
/**
* Converts arbitrary data into tightly packed 32-bit floating point values.
*
* If target is non-null, writes up to "count" items into target and returns the number of bytes
* actually written.
*
* If target is null, returns the number of bytes required.
*
* @param target Client owned area to write into, or null for a size query
* @param source Pointer to the data to read from (does not get retained)
* @param count The maximum number of items to write (i.e. number of float3 values, not bytes)
* @return Number of bytes required to contain "count" items after conversion to packed floats
*
*/
size_t operator()(float* UTILS_RESTRICT target, void const* UTILS_RESTRICT source,
size_t count) const noexcept;
private:
const Config mConfig;
};
} // namespace geometry
} // namespace filament
#endif // TNT_GEOMETRY_TRANSCODER_H

View File

@@ -0,0 +1,120 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_ANIMATOR_H
#define GLTFIO_ANIMATOR_H
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
namespace filament::gltfio {
struct FFilamentAsset;
struct FFilamentInstance;
struct AnimatorImpl;
/**
* \class Animator Animator.h gltfio/Animator.h
* \brief Updates matrices according to glTF \c animation and \c skin definitions.
*
* Animator can be used for two things:
* - Updating matrices in filament::TransformManager components according to glTF \c animation definitions.
* - Updating bone matrices in filament::RenderableManager components according to glTF \c skin definitions.
*
* For a usage example, see the documentation for AssetLoader.
*/
class UTILS_PUBLIC Animator {
public:
/**
* Applies rotation, translation, and scale to entities that have been targeted by the given
* animation definition. Uses filament::TransformManager.
*
* @param animationIndex Zero-based index for the \c animation of interest.
* @param time Elapsed time of interest in seconds.
*/
void applyAnimation(size_t animationIndex, float time) const;
/**
* Computes root-to-node transforms for all bone nodes, then passes
* the results into filament::RenderableManager::setBones.
* Uses filament::TransformManager and filament::RenderableManager.
*
* NOTE: this operation is independent of \c animation.
*/
void updateBoneMatrices();
/**
* Applies a blended transform to the union of nodes affected by two animations.
* Used for cross-fading from a previous skinning-based animation or rigid body animation.
*
* First, this stashes the current transform hierarchy into a transient memory buffer.
*
* Next, this applies previousAnimIndex / previousAnimTime to the actual asset by internally
* calling applyAnimation().
*
* Finally, the stashed local transforms are lerped (via the scale / translation / rotation
* components) with their live counterparts, and the results are pushed to the asset.
*
* To achieve a cross fade effect with skinned models, clients will typically call animator
* methods in this order: (1) applyAnimation (2) applyCrossFade (3) updateBoneMatrices. The
* animation that clients pass to applyAnimation is the "current" animation corresponding to
* alpha=1, while the "previous" animation passed to applyCrossFade corresponds to alpha=0.
*/
void applyCrossFade(size_t previousAnimIndex, float previousAnimTime, float alpha);
/**
* Pass the identity matrix into all bone nodes, useful for returning to the T pose.
*
* NOTE: this operation is independent of \c animation.
*/
void resetBoneMatrices();
/** Returns the number of \c animation definitions in the glTF asset. */
size_t getAnimationCount() const;
/** Returns the duration of the specified glTF \c animation in seconds. */
float getAnimationDuration(size_t animationIndex) const;
/**
* Returns a weak reference to the string name of the specified \c animation, or an
* empty string if none was specified.
*/
const char* getAnimationName(size_t animationIndex) const;
// For internal use only.
void addInstance(FFilamentInstance* instance);
private:
/*! \cond PRIVATE */
friend struct FFilamentAsset;
friend struct FFilamentInstance;
/*! \endcond */
// If "instance" is null, then this is the primary animator.
Animator(FFilamentAsset const* asset, FFilamentInstance* instance);
~Animator();
Animator(const Animator& animator) = delete;
Animator(Animator&& animator) = delete;
Animator& operator=(const Animator&) = delete;
AnimatorImpl* mImpl;
};
} // namespace filament::gltfio
#endif // GLTFIO_ANIMATOR_H

View File

@@ -0,0 +1,249 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_ASSETLOADER_H
#define GLTFIO_ASSETLOADER_H
#include <filament/Engine.h>
#include <filament/Material.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/MaterialProvider.h>
#include <utils/compiler.h>
namespace utils {
class EntityManager;
class NameComponentManager;
}
/**
* Loader and pipeline for glTF 2.0 assets.
*/
namespace filament::gltfio {
class NodeManager;
/**
* \struct AssetConfiguration AssetLoader.h gltfio/AssetLoader.h
* \brief Construction parameters for AssetLoader.
*/
struct AssetConfiguration {
//! The engine that the loader should pass to builder objects (e.g.
//! filament::VertexBuffer::Builder).
class filament::Engine* engine;
//! Controls whether the loader uses filamat to generate materials on the fly, or loads a small
//! set of precompiled ubershader materials. Deleting the MaterialProvider is the client's
//! responsibility. See createJitShaderProvider() and createUbershaderProvider().
MaterialProvider* materials;
//! Optional manager for associating string names with entities in the transform hierarchy.
utils::NameComponentManager* names = nullptr;
//! Overrides the factory used for creating entities in the transform hierarchy. If this is not
//! specified, AssetLoader will use the singleton EntityManager associated with the current
//! process.
utils::EntityManager* entities = nullptr;
//! Optional default node name for anonymous nodes
char* defaultNodeName = nullptr;
};
/**
* \class AssetLoader AssetLoader.h gltfio/AssetLoader.h
* \brief Consumes glTF content and produces FilamentAsset objects.
*
* AssetLoader consumes a blob of glTF 2.0 content (either JSON or GLB) and produces a FilamentAsset
* object, which is a bundle of Filament textures, vertex buffers, index buffers, etc. An asset is
* composed of 1 or more FilamentInstance objects which contain entities and components.
*
* Clients must use AssetLoader to create and destroy FilamentAsset objects. This is similar to
* how filament::Engine is used to create and destroy core objects like VertexBuffer.
*
* AssetLoader does not fetch external buffer data or create textures on its own. Clients can use
* ResourceLoader for this, which obtains the URI list from the asset. This is demonstrated in the
* code snippet below.
*
* AssetLoader also owns a cache of filament::Material objects that may be re-used across multiple
* loads.
*
* Example usage:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* auto engine = Engine::create();
* auto materials = createJitShaderProvider(engine);
* auto decoder = createStbProvider(engine);
* auto loader = AssetLoader::create({engine, materials});
*
* // Parse the glTF content and create Filament entities.
* std::vector<uint8_t> content(...);
* FilamentAsset* asset = loader->createAsset(content.data(), content.size());
* content.clear();
*
* // Load buffers and textures from disk.
* ResourceLoader resourceLoader({engine, ".", true});
* resourceLoader.addTextureProvider("image/png", decoder)
* resourceLoader.addTextureProvider("image/jpeg", decoder)
* resourceLoader.loadResources(asset);
*
* // Free the glTF hierarchy as it is no longer needed.
* asset->releaseSourceData();
*
* // Add renderables to the scene.
* scene->addEntities(asset->getEntities(), asset->getEntityCount());
*
* // Extract the animator interface from the FilamentInstance.
* auto animator = asset->getInstance()->getAnimator();
*
* // Execute the render loop and play the first animation.
* do {
* animator->applyAnimation(0, time);
* animator->updateBoneMatrices();
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
* } while (!quit);
*
* scene->removeEntities(asset->getEntities(), asset->getEntityCount());
* loader->destroyAsset(asset);
* materials->destroyMaterials();
* delete materials;
* delete decoder;
* AssetLoader::destroy(&loader);
* Engine::destroy(&engine);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
class UTILS_PUBLIC AssetLoader {
public:
/**
* Creates an asset loader for the given configuration, which specifies the Filament engine.
*
* The engine is held weakly, used only for the creation and destruction of Filament objects.
* The optional name component manager can be used to assign names to renderables.
* The material source specifies whether to use filamat to generate materials on the fly, or to
* load a small set of precompiled ubershader materials.
*/
static AssetLoader* create(const AssetConfiguration& config);
/**
* Frees the loader.
*
* This does not not automatically free the cache of materials, nor
* does it free the entities for created assets (see destroyAsset).
*/
static void destroy(AssetLoader** loader);
/**
* Takes a pointer to the contents of a GLB or a JSON-based glTF 2.0 file and returns an asset
* with one instance, or null on failure.
*/
FilamentAsset* createAsset(const uint8_t* bytes, uint32_t nbytes);
/**
* Consumes the contents of a glTF 2.0 file and produces a primary asset with one or more
* instances. The primary asset has ownership over the instances.
*
* The returned instances share their textures, materials, and vertex buffers with the primary
* asset. However each instance has its own unique set of entities, transform components,
* material instances, and renderable components. Instances are freed when the primary asset is
* freed.
*
* Light components are not instanced, they belong only to the primary asset.
*
* Clients must use ResourceLoader to load resources on the primary asset.
*
* The entity accessor and renderable stack API in the primary asset can be used to control the
* union of all instances. The individual FilamentInstance objects can be used to access each
* instance's partition of entities. Similarly, the Animator in the primary asset controls all
* instances. To animate instances individually, use FilamentInstance::getAnimator().
*
* @param bytes the contents of a glTF 2.0 file (JSON or GLB)
* @param numBytes the number of bytes in "bytes"
* @param instances destination pointer, to be populated by the requested number of instances
* @param numInstances requested number of instances
* @return the primary asset that has ownership over all instances
*/
FilamentAsset* createInstancedAsset(const uint8_t* bytes, uint32_t numBytes,
FilamentInstance** instances, size_t numInstances);
/**
* Adds a new instance to the asset.
*
* Use this with caution. It is more efficient to pre-allocate a max number of instances, and
* gradually add them to the scene as needed. Instances can also be "recycled" by removing and
* re-adding them to the scene.
*
* NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
* entity lists and instance lists, which would be slow to shift. We also wish to discourage
* create/destroy churn, as noted above.
*
* This cannot be called after FilamentAsset::releaseSourceData().
* See also AssetLoader::createInstancedAsset().
*/
FilamentInstance* createInstance(FilamentAsset* primary);
/**
* Allows clients to enable diagnostic shading on newly-loaded assets.
*/
void enableDiagnostics(bool enable = true);
/**
* Destroys the given asset, all of its associated Filament objects, and all associated
* FilamentInstance objects.
*
* This destroys entities, components, material instances, vertex buffers, index buffers,
* and textures. This does not necessarily immediately free all source data, since
* texture decoding or GPU uploading might be underway.
*/
void destroyAsset(const FilamentAsset* asset);
/**
* Gets a weak reference to an array of cached materials, used internally to create material
* instances for assets.
*/
const filament::Material* const* getMaterials() const noexcept;
/**
* Gets the number of cached materials.
*/
size_t getMaterialsCount() const noexcept;
utils::NameComponentManager* getNames() const noexcept;
NodeManager& getNodeManager() noexcept;
MaterialProvider& getMaterialProvider() noexcept;
/*! \cond PRIVATE */
protected:
AssetLoader() noexcept = default;
~AssetLoader() = default;
public:
AssetLoader(AssetLoader const&) = delete;
AssetLoader(AssetLoader&&) = delete;
AssetLoader& operator=(AssetLoader const&) = delete;
AssetLoader& operator=(AssetLoader&&) = delete;
/*! \endcond */
};
} // namespace filament::gltfio
#endif // GLTFIO_ASSETLOADER_H

View File

@@ -0,0 +1,303 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_FILAMENTASSET_H
#define GLTFIO_FILAMENTASSET_H
#include <filament/Box.h>
#include <filament/TextureSampler.h>
#include <gltfio/NodeManager.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
namespace filament {
class Camera;
class Engine;
class MaterialInstance;
class Scene;
}
namespace filament::gltfio {
class Animator;
class FilamentInstance;
/**
* \class FilamentAsset FilamentAsset.h gltfio/FilamentAsset.h
* \brief Owns a bundle of Filament objects that have been created by AssetLoader.
*
* For usage instructions, see the documentation for AssetLoader.
*
* This class owns a hierarchy of entities that have been loaded from a glTF asset. Every entity has
* a filament::TransformManager component, and some entities also have \c Name, \c Renderable,
* \c Light, \c Camera, or \c Node components.
*
* In addition to the aforementioned entities, an asset has strong ownership over a list of
* filament::VertexBuffer, filament::IndexBuffer, filament::Texture,
* and, optionally, a simple animation engine (gltfio::Animator).
*
* Clients must use ResourceLoader to create filament::Texture objects, compute tangent quaternions,
* and upload data into vertex buffers and index buffers.
*
* \todo Only the default glTF scene is loaded, other glTF scenes are ignored.
*/
class UTILS_PUBLIC FilamentAsset {
public:
using Entity = utils::Entity;
using SceneMask = NodeManager::SceneMask;
/**
* Gets the list of entities, one for each glTF node. All of these have a Transform component.
* Some of the returned entities may also have a Renderable component and/or a Light component.
*/
const Entity* getEntities() const noexcept;
/**
* Gets the number of entities returned by getEntities().
*/
size_t getEntityCount() const noexcept;
/**
* Gets the list of entities in the scene representing lights. All of these have a Light component.
*/
const Entity* getLightEntities() const noexcept;
/**
* Gets the number of entities returned by getLightEntities().
*/
size_t getLightEntityCount() const noexcept;
/**
* Gets the list of entities in the asset that have renderable components.
*/
const utils::Entity* getRenderableEntities() const noexcept;
/**
* Gets the number of entities returned by getRenderableEntities().
*/
size_t getRenderableEntityCount() const noexcept;
/**
* Gets the list of entities in the scene representing cameras. All of these have a \c Camera
* component.
*
* Note about aspect ratios:
* gltfio always uses an aspect ratio of 1.0 when setting the projection matrix for perspective
* cameras. gltfio then sets the camera's scaling matrix with the aspect ratio specified in the
* glTF file (if present).
*
* The camera's scaling matrix allows clients to adjust the aspect ratio independently from the
* camera's projection.
*
* To change the aspect ratio of the glTF camera:
*
* camera->setScaling(double4 {1.0 / newAspectRatio, 1.0, 1.0, 1.0});
*
* @see filament::Camera::setScaling
*/
const Entity* getCameraEntities() const noexcept;
/**
* Gets the number of entities returned by getCameraEntities().
*/
size_t getCameraEntityCount() const noexcept;
/**
* Gets the transform root for the asset, which has no matching glTF node.
*
* This node exists for convenience, allowing users to transform the entire asset. For instanced
* assets, this is a "super root" where each of its children is a root in a particular instance.
* This allows users to transform all instances en masse if they wish to do so.
*/
Entity getRoot() const noexcept;
/**
* Pops a ready renderable off the queue, or returns 0 if no renderables have become ready.
*
* NOTE: To determine the progress percentage or completion status, please use
* ResourceLoader#asyncGetLoadProgress. To get the number of ready renderables,
* please use popRenderables().
*
* This method allows clients to progressively add the asset's renderables to the scene as
* textures gradually become ready through asynchronous loading. For example, on every frame
* progressive applications can do something like this:
*
* while (Entity e = popRenderable()) { scene.addEntity(e); }
*
* Progressive reveal is not supported for dynamically added instances.
*
* \see ResourceLoader#asyncBeginLoad
* \see popRenderables()
*/
Entity popRenderable() noexcept;
/**
* Pops up to "count" ready renderables off the queue, or returns the available number.
*
* The given pointer should either be null or point to memory that can hold up to count
* entities. If the pointer is null, returns the number of available renderables. Otherwise
* returns the number of entities that have been written.
*
* \see ResourceLoader#asyncBeginLoad
*/
size_t popRenderables(Entity* entities, size_t count) noexcept;
/** Gets resource URIs for all externally-referenced buffers. */
const char* const* getResourceUris() const noexcept;
/** Gets the number of resource URIs returned by getResourceUris(). */
size_t getResourceUriCount() const noexcept;
/**
* Gets the bounding box computed from the supplied min / max values in glTF accessors.
*
* This does not return a bounding box over all FilamentInstance, it's just a straightforward
* AAAB that can be determined at load time from the asset data.
*/
filament::Aabb getBoundingBox() const noexcept;
/** Gets the NameComponentManager label for the given entity, if it exists. */
const char* getName(Entity) const noexcept;
/** Returns the first entity with the given name, or 0 if none exist. */
Entity getFirstEntityByName(const char* name) noexcept;
/**
* Gets a list of entities with the given name.
*
* @param name Null-terminated string to match.
* @param entities Pointer to an array to populate.
* @param maxCount Maximum number of entities to retrieve.
*
* @return If entities is non-null, the number of entities written to the entity pointer.
* Otherwise this returns the number of entities with the given name.
*/
size_t getEntitiesByName(const char* name, Entity* entities,
size_t maxCount) const noexcept;
/**
* Gets a list of entities whose names start with the given prefix.
*
* @param prefix Null-terminated prefix string to match.
* @param entities Pointer to an array to populate.
* @param maxCount Maximum number of entities to retrieve.
*
* @return If entities is non-null, the number of entities written to the entity pointer.
* Otherwise this returns the number of entities with the given prefix.
*/
size_t getEntitiesByPrefix(const char* prefix, Entity* entities,
size_t maxCount) const noexcept;
/** Gets the glTF extras string for a specific node, or for the asset, if it exists. */
const char* getExtras(Entity entity = {}) const noexcept;
/**
* Gets the morph target name at the given index in the given entity.
*/
const char* getMorphTargetNameAt(Entity entity, size_t targetIndex) const noexcept;
/**
* Returns the number of morph targets in the given entity.
*/
size_t getMorphTargetCountAt(Entity entity) const noexcept;
/**
* Lazily creates a single LINES renderable that draws the transformed bounding-box hierarchy
* for diagnostic purposes. The wireframe is owned by the asset so clients should not delete it.
*/
Entity getWireframe() noexcept;
/**
* Returns the Filament engine associated with the AssetLoader that created this asset.
*/
filament::Engine* getEngine() const noexcept;
/**
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
*
* This should only be called after ResourceLoader::loadResources().
* If this is an instanced asset, this prevents creation of new instances.
*/
void releaseSourceData() noexcept;
/**
* Returns a weak reference to the underlying cgltf hierarchy. This becomes invalid after
* calling releaseSourceData().
*/
const void* getSourceAsset() noexcept;
/**
* Returns the number of scenes in the asset.
*/
size_t getSceneCount() const noexcept;
/**
* Returns the name of the given scene.
*
* Returns null if the given scene does not have a name or is out of bounds.
*/
const char* getSceneName(size_t sceneIndex) const noexcept;
/**
* Adds entities to a Filament scene only if they belong to at least one of the given glTF
* scenes.
*
* This is just a helper that provides an alternative to directly calling scene->addEntities()
* and provides filtering functionality.
*/
void addEntitiesToScene(filament::Scene& targetScene, const Entity* entities, size_t count,
SceneMask sceneFilter) const;
/**
* Releases ownership of entities and their Filament components.
*
* This makes the client take responsibility for destroying Filament
* components (e.g. Renderable, TransformManager component) as well as
* the underlying entities.
*/
void detachFilamentComponents() noexcept;
bool areFilamentComponentsDetached() const noexcept;
/**
* Convenience function to get the first instance, or null if it doesn't exist.
*/
FilamentInstance* getInstance() noexcept {
return getAssetInstanceCount() > 0 ? getAssetInstances()[0] : nullptr;
}
/*! \cond PRIVATE */
FilamentInstance** getAssetInstances() noexcept;
size_t getAssetInstanceCount() const noexcept;
protected:
FilamentAsset() noexcept = default;
~FilamentAsset() = default;
public:
FilamentAsset(FilamentAsset const&) = delete;
FilamentAsset(FilamentAsset&&) = delete;
FilamentAsset& operator=(FilamentAsset const&) = delete;
FilamentAsset& operator=(FilamentAsset&&) = delete;
/*! \endcond */
};
} // namespace filament::gltfio
#endif // GLTFIO_FILAMENTASSET_H

View File

@@ -0,0 +1,174 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_FILAMENTINSTANCE_H
#define GLTFIO_FILAMENTINSTANCE_H
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <filament/Box.h>
namespace filament {
class MaterialInstance;
}
namespace filament::gltfio {
class Animator;
class FilamentAsset;
/**
* \class FilamentInstance FilamentInstance.h gltfio/FilamentInstance.h
* \brief Provides access to a hierarchy of entities that have been instanced from a glTF asset.
*
* Every entity has a TransformManager component, and some entities also have \c Name or
* \c Renderable components.
*
* \see AssetLoader::createInstancedAsset()
*/
class UTILS_PUBLIC FilamentInstance {
public:
/**
* Gets the owner of this instance.
*/
FilamentAsset const* getAsset() const noexcept;
/**
* Gets the list of entities in this instance, one for each glTF node. All of these have a
* Transform component. Some of the returned entities may also have a Renderable component or
* Name component.
*/
const utils::Entity* getEntities() const noexcept;
/**
* Gets the number of entities returned by getEntities().
*/
size_t getEntityCount() const noexcept;
/** Gets the transform root for the instance, which has no matching glTF node. */
utils::Entity getRoot() const noexcept;
/**
* Applies the given material variant to all primitives in this instance.
*
* Ignored if variantIndex is out of bounds.
*/
void applyMaterialVariant(size_t variantIndex) noexcept;
/**
* Returns the number of material variants in the asset.
*/
size_t getMaterialVariantCount() const noexcept;
/**
* Returns the name of the given material variant, or null if it is out of bounds.
*/
const char* getMaterialVariantName(size_t variantIndex) const noexcept;
/**
* Returns the animation engine for the instance.
*
* Note that an animator can be obtained either from an individual instance, or from the
* originating FilamentAsset. In the latter case, the animation frame is shared amongst all
* instances. If individual control is desired, users must obtain the animator from the
* individual instances.
*
* The animator is owned by the asset and should not be manually deleted.
*/
Animator* getAnimator() noexcept;
/**
* Gets the number of skins.
*/
size_t getSkinCount() const noexcept;
/**
* Gets the skin name at skin index.
*/
const char* getSkinNameAt(size_t skinIndex) const noexcept;
/**
* Gets the number of joints at skin index.
*/
size_t getJointCountAt(size_t skinIndex) const noexcept;
/**
* Gets joints at skin index.
*/
const utils::Entity* getJointsAt(size_t skinIndex) const noexcept;
/**
* Attaches the given skin to the given node, which must have an associated mesh with
* BONE_INDICES and BONE_WEIGHTS attributes.
*
* This is a no-op if the given skin index or target is invalid.
*/
void attachSkin(size_t skinIndex, utils::Entity target) noexcept;
/**
* Detaches the given skin from the given node.
*
* This is a no-op if the given skin index or target is invalid.
*/
void detachSkin(size_t skinIndex, utils::Entity target) noexcept;
/**
* Gets inverse bind matrices for all joints at the given skin index.
*
* See getJointCountAt for determining the number of matrices returned (i.e. the number of joints).
*/
math::mat4f const* getInverseBindMatricesAt(size_t skinIndex) const;
/**
* Resets the AABB on all renderables by manually computing the bounding box.
*
* THIS IS ONLY USEFUL FOR MALFORMED ASSETS THAT DO NOT HAVE MIN/MAX SET UP CORRECTLY.
*
* Does not affect the return value of getBoundingBox() on the owning asset.
* Cannot be called after releaseSourceData() on the owning asset.
* Can only be called after loadResources() or asyncBeginLoad().
*/
void recomputeBoundingBoxes();
/**
* Gets the axis-aligned bounding box from the supplied min / max values in glTF accessors.
*
* If recomputeBoundingBoxes() has been called, then this returns the recomputed AABB.
*/
Aabb getBoundingBox() const noexcept;
/** Gets all material instances. These are already bound to renderables. */
const MaterialInstance* const* getMaterialInstances() const noexcept;
/** Gets all material instances (non-const). These are already bound to renderables. */
MaterialInstance* const* getMaterialInstances() noexcept;
/** Gets the number of materials returned by getMaterialInstances(). */
size_t getMaterialInstanceCount() const noexcept;
/**
* Releases ownership of material instances.
*
* This makes the client take responsibility for destroying MaterialInstance
* objects. The getMaterialInstances query becomes invalid after detachment.
*/
void detachMaterialInstances();
};
} // namespace filament::gltfio
#endif // GLTFIO_FILAMENTINSTANCE_H

View File

@@ -0,0 +1,214 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_MATERIALPROVIDER_H
#define GLTFIO_MATERIALPROVIDER_H
#include <filament/Engine.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
#include <utils/compiler.h>
#include <array>
#include <string>
namespace filament::gltfio {
enum class AlphaMode : uint8_t {
OPAQUE,
MASK,
BLEND
};
// The following struct gets hashed so all padding bits should be explicit.
// Tell the compiler to emit a warning if it adds any padding.
UTILS_WARNING_PUSH
UTILS_WARNING_ENABLE_PADDED
/**
* \struct MaterialKey MaterialProvider.h gltfio/MaterialProvider.h
* \brief Small POD structure that specifies the requirements for a glTF material.
* \note This key is processed by MurmurHashFn so please make padding explicit.
*/
struct alignas(4) MaterialKey {
// -- 32 bit boundary --
bool doubleSided : 1;
bool unlit : 1;
bool hasVertexColors : 1;
bool hasBaseColorTexture : 1;
bool hasNormalTexture : 1;
bool hasOcclusionTexture : 1;
bool hasEmissiveTexture : 1;
bool useSpecularGlossiness : 1;
AlphaMode alphaMode : 4;
bool enableDiagnostics : 4;
union {
struct {
bool hasMetallicRoughnessTexture : 1;
uint8_t metallicRoughnessUV : 7;
};
struct {
bool hasSpecularGlossinessTexture : 1;
uint8_t specularGlossinessUV : 7;
};
};
uint8_t baseColorUV;
// -- 32 bit boundary --
bool hasClearCoatTexture : 1;
uint8_t clearCoatUV : 7;
bool hasClearCoatRoughnessTexture : 1;
uint8_t clearCoatRoughnessUV : 7;
bool hasClearCoatNormalTexture : 1;
uint8_t clearCoatNormalUV : 7;
bool hasClearCoat : 1;
bool hasTransmission : 1;
bool hasTextureTransforms : 6;
// -- 32 bit boundary --
uint8_t emissiveUV;
uint8_t aoUV;
uint8_t normalUV;
bool hasTransmissionTexture : 1;
uint8_t transmissionUV : 7;
// -- 32 bit boundary --
bool hasSheenColorTexture : 1;
uint8_t sheenColorUV : 7;
bool hasSheenRoughnessTexture : 1;
uint8_t sheenRoughnessUV : 7;
bool hasVolumeThicknessTexture : 1;
uint8_t volumeThicknessUV : 7;
bool hasSheen : 1;
bool hasIOR : 1;
bool hasVolume : 1;
uint8_t padding : 5;
};
static_assert(sizeof(MaterialKey) == 16, "MaterialKey has unexpected size.");
UTILS_WARNING_POP
bool operator==(const MaterialKey& k1, const MaterialKey& k2);
// Define a mapping from a uv set index in the source asset to one of Filament's uv sets.
enum UvSet : uint8_t { UNUSED, UV0, UV1 };
constexpr int UvMapSize = 8;
using UvMap = std::array<UvSet, UvMapSize>;
inline uint8_t getNumUvSets(const UvMap& uvmap) {
return std::max({
uvmap[0], uvmap[1], uvmap[2], uvmap[3],
uvmap[4], uvmap[5], uvmap[6], uvmap[7],
});
};
/**
* \class MaterialProvider MaterialProvider.h gltfio/MaterialProvider.h
* \brief Interface to a provider of glTF materials (has two implementations).
*
* - The \c JitShaderProvider implementation generates materials at run time (which can be slow) and
* requires the filamat library, but produces streamlined shaders. See createJitShaderProvider().
*
* - The \c UbershaderProvider implementation uses a small number of pre-built materials with complex
* fragment shaders, but does not require any run time work or usage of filamat. See
* createUbershaderProvider().
*
* Both implementations of MaterialProvider maintain a small cache of materials which must be
* explicitly freed using destroyMaterials(). These materials are not freed automatically when the
* MaterialProvider is destroyed, which allows clients to take ownership if desired.
*
*/
class UTILS_PUBLIC MaterialProvider {
public:
virtual ~MaterialProvider() {}
/**
* Creates or fetches a compiled Filament material, then creates an instance from it.
*
* @param config Specifies requirements; might be mutated due to resource constraints.
* @param uvmap Output argument that gets populated with a small table that maps from a glTF uv
* index to a Filament uv index.
* @param label Optional tag that is not a part of the cache key.
* @param extras Optional extras as stringified JSON (not a part of the cache key).
* Does not store the pointer.
*/
virtual MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap,
const char* label = "material", const char* extras = nullptr) = 0;
/**
* Creates or fetches a compiled Filament material corresponding to the given config.
*/
virtual Material* getMaterial(MaterialKey* config, UvMap* uvmap,
const char* label = "material") { return nullptr; }
/**
* Gets a weak reference to the array of cached materials.
*/
virtual const Material* const* getMaterials() const noexcept = 0;
/**
* Gets the number of cached materials.
*/
virtual size_t getMaterialsCount() const noexcept = 0;
/**
* Destroys all cached materials.
*
* This is not called automatically when MaterialProvider is destroyed, which allows
* clients to take ownership of the cache if desired.
*/
virtual void destroyMaterials() = 0;
/**
* Returns true if the presence of the given vertex attribute is required.
*
* Some types of providers (e.g. ubershader) require dummy attribute values
* if the glTF model does not provide them.
*/
virtual bool needsDummyData(VertexAttribute attrib) const noexcept = 0;
};
void constrainMaterial(MaterialKey* key, UvMap* uvmap);
void processShaderString(std::string* shader, const UvMap& uvmap,
const MaterialKey& config);
/**
* Creates a material provider that builds materials on the fly, composing GLSL at run time.
*
* @param optimizeShaders Optimizes shaders, but at significant cost to construction time.
* @return New material provider that can build materials at run time.
*
* Requires \c libfilamat to be linked in. Not available in \c libgltfio_core.
*
* @see createUbershaderProvider
*/
UTILS_PUBLIC
MaterialProvider* createJitShaderProvider(Engine* engine, bool optimizeShaders = false);
/**
* Creates a material provider that loads a small set of pre-built materials.
*
* @return New material provider that can quickly load a material from a cache.
*
* @see createJitShaderProvider
*/
UTILS_PUBLIC
MaterialProvider* createUbershaderProvider(Engine* engine, const void* archive,
size_t archiveByteCount);
} // namespace filament::gltfio
#endif // GLTFIO_MATERIALPROVIDER_H

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_NODEMANAGER_H
#define GLTFIO_NODEMANAGER_H
#include <filament/FilamentAPI.h>
#include <utils/bitset.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/EntityInstance.h>
#include <utils/FixedCapacityVector.h>
namespace utils {
class Entity;
} // namespace utils
namespace filament::gltfio {
class FNodeManager;
/**
* NodeManager is used to add annotate entities with glTF-specific information.
*
* Node components are created by gltfio and exposed to users to allow inspection.
*
* Nodes do not store the glTF hierarchy or names; see TransformManager and NameComponentManager.
*/
class UTILS_PUBLIC NodeManager {
public:
using Instance = utils::EntityInstance<NodeManager>;
using Entity = utils::Entity;
using CString = utils::CString;
using SceneMask = utils::bitset32;
static constexpr size_t MAX_SCENE_COUNT = 32;
/**
* Returns whether a particular Entity is associated with a component of this NodeManager
* @param e An Entity.
* @return true if this Entity has a component associated with this manager.
*/
bool hasComponent(Entity e) const noexcept;
/**
* Gets an Instance representing the node component associated with the given Entity.
* @param e An Entity.
* @return An Instance object, which represents the node component associated with the Entity e.
* @note Use Instance::isValid() to make sure the component exists.
* @see hasComponent()
*/
Instance getInstance(Entity e) const noexcept;
/**
* Creates a node component and associates it with the given entity.
* @param entity An Entity to associate a node component with.
*
* If this component already exists on the given entity, it is first destroyed as if
* destroy(Entity e) was called.
*
* @see destroy()
*/
void create(Entity entity);
/**
* Destroys this component from the given entity.
* @param e An entity.
*
* @see create()
*/
void destroy(Entity e) noexcept;
void setMorphTargetNames(Instance ci, utils::FixedCapacityVector<CString> names) noexcept;
const utils::FixedCapacityVector<CString>& getMorphTargetNames(Instance ci) const noexcept;
void setExtras(Instance ci, CString extras) noexcept;
const CString& getExtras(Instance ci) const noexcept;
void setSceneMembership(Instance ci, SceneMask scenes) noexcept;
SceneMask getSceneMembership(Instance ci) const noexcept;
protected:
NodeManager() noexcept = default;
~NodeManager() = default;
public:
NodeManager(NodeManager const&) = delete;
NodeManager(NodeManager&&) = delete;
NodeManager& operator=(NodeManager const&) = delete;
NodeManager& operator=(NodeManager&&) = delete;
};
} // namespace filament::gltfio
#endif // GLTFIO_NODEMANAGER_H

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_RESOURCELOADER_H
#define GLTFIO_RESOURCELOADER_H
#include <gltfio/FilamentAsset.h>
#include <filament/VertexBuffer.h>
#include <utils/compiler.h>
namespace filament {
class Engine;
}
namespace filament::gltfio {
struct FFilamentAsset;
class AssetPool;
class TextureProvider;
/**
* \struct ResourceConfiguration ResourceLoader.h gltfio/ResourceLoader.h
* \brief Construction parameters for ResourceLoader.
*/
struct ResourceConfiguration {
//! The engine that the loader should pass to builder objects (e.g.
//! filament::Texture::Builder).
class filament::Engine* engine;
//! Optional path or URI that points to the base glTF file. This is used solely
//! to resolve relative paths. The string pointer is not retained.
const char* gltfPath;
//! If true, adjusts skinning weights to sum to 1. Well formed glTF files do not need this,
//! but it is useful for robustness.
bool normalizeSkinningWeights;
};
/**
* \class ResourceLoader ResourceLoader.h gltfio/ResourceLoader.h
* \brief Prepares and uploads vertex buffers and textures to the GPU.
*
* For a usage example, see the documentation for AssetLoader.
*
* ResourceLoader must be destroyed on the same thread that calls filament::Renderer::render()
* because it listens to filament::backend::BufferDescriptor callbacks in order to determine when to
* free CPU-side data blobs.
*
* \todo If clients persist their ResourceLoader, Filament textures are currently re-created upon
* subsequent re-loads of the same asset. To fix this, we would need to enable shared ownership
* of Texture objects between ResourceLoader and FilamentAsset.
*/
class UTILS_PUBLIC ResourceLoader {
public:
using BufferDescriptor = filament::backend::BufferDescriptor;
ResourceLoader(const ResourceConfiguration& config);
~ResourceLoader();
/**
* Feeds the binary content of an external resource into the loader's URI cache.
*
* On some platforms, `ResourceLoader` does not know how to download external resources on its
* own (external resources might come from a filesystem, a database, or the internet) so this
* method allows clients to download external resources and push them to the loader.
*
* Every resource should be passed in before calling #loadResources or #asyncBeginLoad. See
* also FilamentAsset#getResourceUris.
*
* When loading GLB files (as opposed to JSON-based glTF files), clients typically do not
* need to call this method.
*/
void addResourceData(const char* uri, BufferDescriptor&& buffer);
/**
* Register a plugin that can consume PNG / JPEG content and produce filament::Texture objects.
*
* Destruction of the given provider is the client's responsibility.
*/
void addTextureProvider(const char* mimeType, TextureProvider* provider);
/**
* Checks if the given resource has already been added to the URI cache.
*/
bool hasResourceData(const char* uri) const;
/**
* Frees memory by evicting the URI cache that was populated via addResourceData.
*
* This can be called only after a model is fully loaded or after loading has been cancelled.
*/
void evictResourceData();
/**
* Loads resources for the given asset from the filesystem or data cache and "finalizes" the
* asset by transforming the vertex data format if necessary, decoding image files, supplying
* tangent data, etc.
*
* Returns false if resources have already been loaded, or if one or more resources could not
* be loaded.
*
* Note: this method is synchronous and blocks until all textures have been decoded.
* For an asynchronous alternative, see #asyncBeginLoad.
*/
bool loadResources(FilamentAsset* asset);
/**
* Starts an asynchronous resource load.
*
* Returns false if the loading process was unable to start.
*
* This is an alternative to #loadResources and requires periodic calls to #asyncUpdateLoad.
* On multi-threaded systems this creates threads for texture decoding.
*/
bool asyncBeginLoad(FilamentAsset* asset);
/**
* Gets the status of an asynchronous resource load as a percentage in [0,1].
*/
float asyncGetLoadProgress() const;
/**
* Updates an asynchronous load by performing any pending work that must take place
* on the main thread.
*
* Clients must periodically call this until #asyncGetLoadProgress returns 100%.
* After progress reaches 100%, calling this is harmless; it just does nothing.
*/
void asyncUpdateLoad();
/**
* Cancels pending decoder jobs, frees all CPU-side texel data, and flushes the Engine.
*
* Calling this is only necessary if the asyncBeginLoad API was used
* and cancellation is required before progress reaches 100%.
*/
void asyncCancelLoad();
private:
bool loadResources(FFilamentAsset* asset, bool async);
void normalizeSkinningWeights(FFilamentAsset* asset) const;
AssetPool* mPool;
struct Impl;
Impl* pImpl;
};
} // namespace filament::gltfio
#endif // GLTFIO_RESOURCELOADER_H

View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_TEXTUREPROVIDER_H
#define GLTFIO_TEXTUREPROVIDER_H
#include <stddef.h>
#include <stdint.h>
#include <utils/compiler.h>
#include <utils/BitmaskEnum.h>
namespace filament {
class Engine;
class Texture;
}
namespace filament::gltfio {
/**
* TextureProvider is an interface that allows clients to implement their own texture decoding
* facility for JPEG, PNG, or KTX2 content. It constructs Filament Texture objects synchronously,
* but populates their miplevels asynchronously.
*
* gltfio calls all public methods from the foreground thread, i.e. the thread that the Filament
* engine was created with. However the implementation may create 0 or more background threads to
* perform decoding work.
*
* The following pseudocode illustrates how this interface could be used, but in practice the only
* client is the gltfio ResourceLoader.
*
* filament::Engine* engine = ...;
* TextureProvider* provider = createStbProvider(engine);
*
* for (auto filename : textureFiles) {
* std::vector<uint8_t> buf = readEntireFile(filename);
* Texture* texture = provider->pushTexture(buf.data(), buf.size(), "image/png", 0);
* if (texture == nullptr) { puts(provider->getPushMessage()); exit(1); }
* }
*
* // At this point, the returned textures can be bound to material instances, but none of their
* // miplevel images have been populated yet.
*
* while (provider->getPoppedCount() < provider->getPushedCount()) {
* sleep(200);
*
* // The following call gives the provider an opportunity to reap the results of any
* // background decoder work that has been completed (e.g. by calling Texture::setImage).
* provider->updateQueue();
*
* // Check for textures that now have all their miplevels initialized.
* while (Texture* texture = provider->popTexture()) {
* printf("%p has all its miplevels ready.\n", texture);
* }
* }
*
* delete provider;
*/
class UTILS_PUBLIC TextureProvider {
public:
using Texture = filament::Texture;
enum class TextureFlags : uint64_t {
NONE = 0,
sRGB = 1 << 0,
};
/**
* Creates a Filament texture and pushes it to the asynchronous decoding queue.
*
* The provider synchronously determines the texture dimensions in order to create a Filament
* texture object, then populates the miplevels asynchronously.
*
* If construction fails, nothing is pushed to the queue and null is returned. The failure
* reason can be obtained with getPushMessage(). The given buffer pointer is not held, so the
* caller can free it immediately. It is also the caller's responsibility to free the returned
* Texture object, but it is only safe to do so after it has been popped from the queue.
*/
virtual Texture* pushTexture(const uint8_t* data, size_t byteCount,
const char* mimeType, TextureFlags flags) = 0;
/**
* Checks if any texture is ready to be removed from the asynchronous decoding queue, and if so
* pops it off.
*
* Unless an error or cancellation occurred during the decoding process, the returned texture
* should have all its miplevels populated. If the texture is not complete, the reason can be
* obtained with getPopMessage().
*
* Due to concurrency, textures are not necessarily popped off in the same order they were
* pushed. Returns null if there are no textures that are ready to be popped.
*/
virtual Texture* popTexture() = 0;
/**
* Polls textures in the queue and uploads mipmap images if any have emerged from the decoder.
*
* This gives the provider an opportunity to call Texture::setImage() on the foreground thread.
* If needed, it can also call Texture::generateMipmaps() here.
*
* Items in the decoding queue can become "poppable" only during this call.
*/
virtual void updateQueue() = 0;
/**
* Returns a failure message for the most recent call to pushTexture(), or null for success.
*
* Note that this method does not pertain to the decoding process. If decoding fails, clients to
* can pop the incomplete texture off the queue and obtain a failure message using the
* getPopFailure() method.
*
* The returned string is owned by the provider and becomes invalid after the next call to
* pushTexture().
*/
virtual const char* getPushMessage() const = 0;
/**
* Returns a failure message for the most recent call to popTexture(), or null for success.
*
* If the most recent call to popTexture() returned null, then no error occurred and this
* returns null. If the most recent call to popTexture() returned a "complete" texture (i.e.
* all miplevels present), then this returns null. This returns non-null only if an error or
* cancellation occurred while decoding the popped texture.
*
* The returned string is owned by the provider and becomes invalid after the next call to
* popTexture().
*/
virtual const char* getPopMessage() const = 0;
/**
* Waits for all outstanding decoding jobs to complete.
*
* Clients should call updateQueue() afterwards if they wish to update the push / pop queue.
*/
virtual void waitForCompletion() = 0;
/**
* Cancels all not-yet-started decoding jobs and waits for all other jobs to complete.
*
* Jobs that have already started cannot be canceled. Textures whose decoding process has
* been cancelled will be made poppable on the subsequent call to updateQueue().
*/
virtual void cancelDecoding() = 0;
/** Total number of successful push calls since the provider was created. */
virtual size_t getPushedCount() const = 0;
/** Total number of successful pop calls since the provider was created. */
virtual size_t getPoppedCount() const = 0;
/** Total number of textures that have become ready-to-pop since the provider was created. */
virtual size_t getDecodedCount() const = 0;
virtual ~TextureProvider() = default;
};
/**
* Creates a simple decoder based on stb_image that can handle "image/png" and "image/jpeg".
* This works only if your build configuration includes STB.
*/
TextureProvider* createStbProvider(filament::Engine* engine);
/**
* Creates a decoder that can handle certain types of "image/ktx2" content as specified in
* the KHR_texture_basisu specification.
*/
TextureProvider* createKtx2Provider(filament::Engine* engine);
} // namespace filament::gltfio
template<> struct utils::EnableBitMaskOperators<filament::gltfio::TextureProvider::TextureFlags>
: public std::true_type {};
#endif // GLTFIO_TEXTUREPROVIDER_H

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_TRSTRANSFORMMANAGER_H
#define GLTFIO_TRSTRANSFORMMANAGER_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <utils/EntityInstance.h>
#include <math/quat.h>
#include <math/vec3.h>
#include <math/mat4.h>
using namespace filament::math;
namespace utils {
class Entity;
} // namespace utils
namespace filament::gltfio {
class FTrsTransformManager;
/**
* TrsTransformManager is used to add entities with glTF-specific trs information.
*
* Trs information here just used for Animation, DON'T use for transform.
*/
class UTILS_PUBLIC TrsTransformManager {
public:
using Instance = utils::EntityInstance<TrsTransformManager>;
using Entity = utils::Entity;
/**
* Returns whether a particular Entity is associated with a component of this TrsTransformManager
* @param e An Entity.
* @return true if this Entity has a component associated with this manager.
*/
bool hasComponent(Entity e) const noexcept;
/**
* Gets an Instance representing the trs transform component associated with the given Entity.
* @param e An Entity.
* @return An Instance object, which represents the trs transform component associated with the Entity e.
* @note Use Instance::isValid() to make sure the component exists.
* @see hasComponent()
*/
Instance getInstance(Entity e) const noexcept;
/**
* Creates a trs transform component and associates it with the given entity.
* @param entity An Entity to associate a trs transform component with.
* @param translation The translation to initialize the trs transform component with.
* @param rotation The rotation to initialize the trs transform component with.
* @param scale The scale to initialize the trs transform component with.
*
* If this component already exists on the given entity, it is first destroyed as if
* destroy(Entity e) was called.
*
* @see destroy()
*/
void create(Entity entity);
void create(Entity entity, const float3& translation, const quatf& rotation,
const float3& scale); //!< \overload
/**
* Destroys this component from the given entity.
* @param e An entity.
*
* @see create()
*/
void destroy(Entity e) noexcept;
void setTranslation(Instance ci, const float3& translation) noexcept;
const float3& getTranslation(Instance ci) const noexcept;
void setRotation(Instance ci, const quatf& rotation) noexcept;
const quatf& getRotation(Instance ci) const noexcept;
void setScale(Instance ci, const float3& scale) noexcept;
const float3& getScale(Instance ci) const noexcept;
void setTrs(Instance ci, const float3& translation, const quatf& rotation,
const float3& scale) noexcept;
const mat4f getTransform(Instance ci) const noexcept;
protected:
TrsTransformManager() noexcept = default;
~TrsTransformManager() = default;
public:
TrsTransformManager(TrsTransformManager const&) = delete;
TrsTransformManager(TrsTransformManager&&) = delete;
TrsTransformManager& operator=(TrsTransformManager const&) = delete;
TrsTransformManager& operator=(TrsTransformManager&&) = delete;
};
} // namespace filament::gltfio
#endif // GLTFIO_TRSTRANSFORMMANAGER_H

View File

@@ -0,0 +1,13 @@
#ifndef UBERARCHIVE_H_
#define UBERARCHIVE_H_
#include <stdint.h>
extern "C" {
extern const uint8_t UBERARCHIVE_PACKAGE[];
extern int UBERARCHIVE_DEFAULT_OFFSET;
extern int UBERARCHIVE_DEFAULT_SIZE;
}
#define UBERARCHIVE_DEFAULT_DATA (UBERARCHIVE_PACKAGE + UBERARCHIVE_DEFAULT_OFFSET)
#endif

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#ifndef GLTFIO_MATH_H
#define GLTFIO_MATH_H
#include <math/quat.h>
#include <math/vec3.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/TVecHelpers.h>
#include <utils/compiler.h>
namespace filament::gltfio {
template <typename T>
UTILS_PUBLIC T cubicSpline(const T& vert0, const T& tang0, const T& vert1, const T& tang1, float t) {
float tt = t * t, ttt = tt * t;
float s2 = -2 * ttt + 3 * tt, s3 = ttt - tt;
float s0 = 1 - s2, s1 = s3 - tt + t;
T p0 = vert0;
T m0 = tang0;
T p1 = vert1;
T m1 = tang1;
return s0 * p0 + s1 * m0 * t + s2 * p1 + s3 * m1 * t;
}
UTILS_PUBLIC inline void decomposeMatrix(const filament::math::mat4f& mat, filament::math::float3* translation,
filament::math::quatf* rotation, filament::math::float3* scale) {
using namespace filament::math;
// Extract translation.
*translation = mat[3].xyz;
// Extract upper-left for determinant computation.
const float a = mat[0][0];
const float b = mat[0][1];
const float c = mat[0][2];
const float d = mat[1][0];
const float e = mat[1][1];
const float f = mat[1][2];
const float g = mat[2][0];
const float h = mat[2][1];
const float i = mat[2][2];
const float A = e * i - f * h;
const float B = f * g - d * i;
const float C = d * h - e * g;
// Extract scale.
const float det(a * A + b * B + c * C);
float scalex = length(float3({a, b, c}));
float scaley = length(float3({d, e, f}));
float scalez = length(float3({g, h, i}));
float3 s = { scalex, scaley, scalez };
if (det < 0) {
s = -s;
}
*scale = s;
// Remove scale from the matrix if it is not close to zero.
mat4f clone = mat;
if (std::abs(det) > std::numeric_limits<float>::epsilon()) {
clone[0] /= s.x;
clone[1] /= s.y;
clone[2] /= s.z;
// Extract rotation
*rotation = clone.toQuaternion();
} else {
// Set to identity if close to zero
*rotation = quatf(1.0f);
}
}
UTILS_PUBLIC inline filament::math::mat4f composeMatrix(const filament::math::float3& translation,
const filament::math::quatf& rotation, const filament::math::float3& scale) {
float tx = translation[0];
float ty = translation[1];
float tz = translation[2];
float qx = rotation[0];
float qy = rotation[1];
float qz = rotation[2];
float qw = rotation[3];
float sx = scale[0];
float sy = scale[1];
float sz = scale[2];
return filament::math::mat4f(
(1 - 2 * qy*qy - 2 * qz*qz) * sx,
(2 * qx*qy + 2 * qz*qw) * sx,
(2 * qx*qz - 2 * qy*qw) * sx,
0.f,
(2 * qx*qy - 2 * qz*qw) * sy,
(1 - 2 * qx*qx - 2 * qz*qz) * sy,
(2 * qy*qz + 2 * qx*qw) * sy,
0.f,
(2 * qx*qz + 2 * qy*qw) * sz,
(2 * qy*qz - 2 * qx*qw) * sz,
(1 - 2 * qx*qx - 2 * qy*qy) * sz,
0.f, tx, ty, tz, 1.f);
}
inline filament::math::mat3f matrixFromUvTransform(const float offset[2], float rotation,
const float scale[2]) {
float tx = offset[0];
float ty = offset[1];
float sx = scale[0];
float sy = scale[1];
float c = cos(rotation);
float s = sin(rotation);
return filament::math::mat3f(sx * c, sx * s, tx, -sy * s, sy * c, ty, 0.0f, 0.0f, 1.0f);
};
} // namespace filament::gltfio
#endif // GLTFIO_MATH_H

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_CUBEMAP_H
#define IBL_CUBEMAP_H
#include <ibl/Image.h>
#include <utils/compiler.h>
#include <math/vec4.h>
#include <math/vec3.h>
#include <math/vec2.h>
#include <algorithm>
namespace filament {
namespace ibl {
/**
* Generic cubemap class. It handles writing / reading into the 6 faces of a cubemap.
*
* Seamless trilinear filtering is handled.
*
* This class doesn't own the face data, it's just a "view" on the 6 images.
*
* @see CubemapUtils
*
*/
class UTILS_PUBLIC Cubemap {
public:
/**
* Initialize the cubemap with a given size, but no face is set and no memory is allocated.
*
* Usually Cubemaps are created using CubemapUtils.
*
* @see CubemapUtils
*/
explicit Cubemap(size_t dim);
Cubemap(Cubemap&&) = default;
Cubemap& operator=(Cubemap&&) = default;
~Cubemap();
enum class Face : uint8_t {
PX = 0, // left +----+
NX, // right | PY |
PY, // bottom +----+----+----+----+
NY, // top | NX | PZ | PX | NZ |
PZ, // back +----+----+----+----+
NZ // front | NY |
// +----+
};
using Texel = filament::math::float3;
//! releases all images and reset the cubemap size
void resetDimensions(size_t dim);
//! assigns an image to a face.
void setImageForFace(Face face, const Image& image);
//! retrieves the image attached to a face
inline const Image& getImageForFace(Face face) const;
//! retrieves the image attached to a face
inline Image& getImageForFace(Face face);
//! computes the center of a pixel at coordinate x, y
static inline filament::math::float2 center(size_t x, size_t y);
//! computes a direction vector from a face and a location of the center of pixel in an Image
inline filament::math::float3 getDirectionFor(Face face, size_t x, size_t y) const;
//! computes a direction vector from a face and a location in pixel in an Image
inline filament::math::float3 getDirectionFor(Face face, float x, float y) const;
//! samples the cubemap at the given direction using nearest neighbor filtering
inline Texel const& sampleAt(const filament::math::float3& direction) const;
//! samples the cubemap at the given direction using bilinear filtering
inline Texel filterAt(const filament::math::float3& direction) const;
//! samples an image at the given location in pixel using bilinear filtering
static Texel filterAt(const Image& image, float x, float y);
static Texel filterAtCenter(const Image& image, size_t x, size_t y);
//! samples two cubemaps in a given direction and lerps the result by a given lerp factor
static Texel trilinearFilterAt(const Cubemap& c0, const Cubemap& c1, float lerp,
const filament::math::float3& direction);
//! reads a texel at a given address
inline static const Texel& sampleAt(void const* data) {
return *static_cast<Texel const*>(data);
}
//! writes a texel at a given address
inline static void writeAt(void* data, const Texel& texel) {
*static_cast<Texel*>(data) = texel;
}
//! returns the size of the cubemap in pixels
size_t getDimensions() const;
/**
* Prepares a cubemap for seamless access to its faces.
*
* @warning All faces of the cubemap must be backed-up by the same Image, and must already
* be spaced by 2 lines/rows.
*/
void makeSeamless();
struct Address {
Face face;
float s = 0;
float t = 0;
};
//! returns the face and texture coordinates of the given direction
static Address getAddressFor(const filament::math::float3& direction);
private:
size_t mDimensions = 0;
float mScale = 1;
float mUpperBound = 0;
Image mFaces[6];
};
// ------------------------------------------------------------------------------------------------
inline const Image& Cubemap::getImageForFace(Face face) const {
return mFaces[int(face)];
}
inline Image& Cubemap::getImageForFace(Face face) {
return mFaces[int(face)];
}
inline filament::math::float2 Cubemap::center(size_t x, size_t y) {
return { x + 0.5f, y + 0.5f };
}
inline filament::math::float3 Cubemap::getDirectionFor(Face face, size_t x, size_t y) const {
return getDirectionFor(face, x + 0.5f, y + 0.5f);
}
inline filament::math::float3 Cubemap::getDirectionFor(Face face, float x, float y) const {
// map [0, dim] to [-1,1] with (-1,-1) at bottom left
float cx = (x * mScale) - 1;
float cy = 1 - (y * mScale);
filament::math::float3 dir;
const float l = std::sqrt(cx * cx + cy * cy + 1);
switch (face) {
case Face::PX: dir = { 1, cy, -cx }; break;
case Face::NX: dir = { -1, cy, cx }; break;
case Face::PY: dir = { cx, 1, -cy }; break;
case Face::NY: dir = { cx, -1, cy }; break;
case Face::PZ: dir = { cx, cy, 1 }; break;
case Face::NZ: dir = { -cx, cy, -1 }; break;
}
return dir * (1 / l);
}
inline Cubemap::Texel const& Cubemap::sampleAt(const filament::math::float3& direction) const {
Cubemap::Address addr(getAddressFor(direction));
const size_t x = std::min(size_t(addr.s * mDimensions), mDimensions - 1);
const size_t y = std::min(size_t(addr.t * mDimensions), mDimensions - 1);
return sampleAt(getImageForFace(addr.face).getPixelRef(x, y));
}
inline Cubemap::Texel Cubemap::filterAt(const filament::math::float3& direction) const {
Cubemap::Address addr(getAddressFor(direction));
addr.s = std::min(addr.s * mDimensions, mUpperBound);
addr.t = std::min(addr.t * mDimensions, mUpperBound);
return filterAt(getImageForFace(addr.face), addr.s, addr.t);
}
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAP_H */

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_CUBEMAPIBL_H
#define IBL_CUBEMAPIBL_H
#include <math/vec3.h>
#include <utils/Slice.h>
#include <utils/compiler.h>
#include <vector>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class Cubemap;
class Image;
/**
* Generates cubemaps for the IBL.
*/
class UTILS_PUBLIC CubemapIBL {
public:
typedef void (*Progress)(size_t, float, void*);
/**
* Computes a roughness LOD using prefiltered importance sampling GGX
*
* @param dst the destination cubemap
* @param levels a list of prefiltered lods of the source environment
* @param linearRoughness roughness
* @param maxNumSamples number of samples for importance sampling
* @param updater a callback for the caller to track progress
*/
static void roughnessFilter(
utils::JobSystem& js, Cubemap& dst, const utils::Slice<Cubemap>& levels,
float linearRoughness, size_t maxNumSamples, math::float3 mirror, bool prefilter,
Progress updater = nullptr, void* userdata = nullptr);
static void roughnessFilter(
utils::JobSystem& js, Cubemap& dst, const std::vector<Cubemap>& levels,
float linearRoughness, size_t maxNumSamples, math::float3 mirror, bool prefilter,
Progress updater = nullptr, void* userdata = nullptr);
//! Computes the "DFG" term of the "split-sum" approximation and stores it in a 2D image
static void DFG(utils::JobSystem& js, Image& dst, bool multiscatter, bool cloth);
/**
* Computes the diffuse irradiance using prefiltered importance sampling GGX
*
* @note Usually this is done using spherical harmonics instead.
*
* @param dst the destination cubemap
* @param levels a list of prefiltered lods of the source environment
* @param maxNumSamples number of samples for importance sampling
* @param updater a callback for the caller to track progress
*
* @see CubemapSH
*/
static void diffuseIrradiance(utils::JobSystem& js, Cubemap& dst, const std::vector<Cubemap>& levels,
size_t maxNumSamples = 1024, Progress updater = nullptr, void* userdata = nullptr);
// for debugging. ignore.
static void brdf(utils::JobSystem& js, Cubemap& dst, float linearRoughness);
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAPIBL_H */

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_CUBEMAPSH_H
#define IBL_CUBEMAPSH_H
#include <utils/compiler.h>
#include <math/mat3.h>
#include <math/vec3.h>
#include <memory>
#include <vector>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class Cubemap;
/**
* Computes spherical harmonics
*/
class UTILS_PUBLIC CubemapSH {
public:
/**
* Spherical Harmonics decomposition of the given cubemap
* Optionally calculates irradiance by convolving with truncated cos.
*/
static std::unique_ptr<math::float3[]> computeSH(
utils::JobSystem& js, const Cubemap& cm, size_t numBands, bool irradiance);
/**
* Render given spherical harmonics into a cubemap
*/
static void renderSH(utils::JobSystem& js, Cubemap& cm,
const std::unique_ptr<math::float3[]>& sh, size_t numBands);
static void windowSH(std::unique_ptr<math::float3[]>& sh, size_t numBands, float cutoff);
/**
* Compute spherical harmonics of the irradiance of the given cubemap.
* The SH basis are pre-scaled for easier rendering by the shader. The resulting coefficients
* are not spherical harmonics (as they're scalled by various factors). In particular they
* cannot be rendered with renderSH() above. Instead use renderPreScaledSH3Bands() which
* is exactly the code ran by our shader.
*/
static void preprocessSHForShader(std::unique_ptr<math::float3[]>& sh);
/**
* Render pre-scaled irrandiance SH
*/
static void renderPreScaledSH3Bands(utils::JobSystem& js, Cubemap& cm,
const std::unique_ptr<math::float3[]>& sh);
static constexpr size_t getShIndex(ssize_t m, size_t l) {
return SHindex(m, l);
}
private:
class float5 {
float v[5];
public:
float5() = default;
constexpr float5(float a, float b, float c, float d, float e) : v{ a, b, c, d, e } {}
constexpr float operator[](size_t i) const { return v[i]; }
float& operator[](size_t i) { return v[i]; }
};
static inline const float5 multiply(const float5 M[5], float5 x) noexcept {
return float5{
M[0][0] * x[0] + M[1][0] * x[1] + M[2][0] * x[2] + M[3][0] * x[3] + M[4][0] * x[4],
M[0][1] * x[0] + M[1][1] * x[1] + M[2][1] * x[2] + M[3][1] * x[3] + M[4][1] * x[4],
M[0][2] * x[0] + M[1][2] * x[1] + M[2][2] * x[2] + M[3][2] * x[3] + M[4][2] * x[4],
M[0][3] * x[0] + M[1][3] * x[1] + M[2][3] * x[2] + M[3][3] * x[3] + M[4][3] * x[4],
M[0][4] * x[0] + M[1][4] * x[1] + M[2][4] * x[2] + M[3][4] * x[3] + M[4][4] * x[4]
};
};
static inline constexpr size_t SHindex(ssize_t m, size_t l) {
return l * (l + 1) + m;
}
static void computeShBasis(float* SHb, size_t numBands, const math::float3& s);
static float Kml(ssize_t m, size_t l);
static std::vector<float> Ki(size_t numBands);
static constexpr float computeTruncatedCosSh(size_t l);
static float sincWindow(size_t l, float w);
static math::float3 rotateShericalHarmonicBand1(math::float3 band1, math::mat3f const& M);
static float5 rotateShericalHarmonicBand2(float5 const& band2, math::mat3f const& M);
// debugging only...
static float Legendre(ssize_t l, ssize_t m, float x);
static float TSH(int l, int m, const math::float3& d);
static void printShBase(std::ostream& out, int l, int m);
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAPSH_H */

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_CUBEMAP_UTILS_H
#define IBL_CUBEMAP_UTILS_H
#include <ibl/Cubemap.h>
#include <ibl/Image.h>
#include <utils/compiler.h>
#include <functional>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class CubemapIBL;
/**
* Create and convert Cubemap formats
*/
class UTILS_PUBLIC CubemapUtils {
public:
//! Creates a cubemap object and its backing Image
static Cubemap create(Image& image, size_t dim, bool horizontal = true);
struct EmptyState {
};
template<typename STATE>
using ScanlineProc = std::function<
void(STATE& state, size_t y, Cubemap::Face f, Cubemap::Texel* data, size_t width)>;
template<typename STATE>
using ReduceProc = std::function<void(STATE& state)>;
//! process the cubemap using multithreading
template<typename STATE>
static void process(Cubemap& cm,
utils::JobSystem& js,
ScanlineProc<STATE> proc,
ReduceProc<STATE> reduce = [](STATE&) {},
const STATE& prototype = STATE());
//! process the cubemap
template<typename STATE>
static void processSingleThreaded(Cubemap& cm,
utils::JobSystem& js,
ScanlineProc<STATE> proc,
ReduceProc<STATE> reduce = [](STATE&) {},
const STATE& prototype = STATE());
//! clamps image to acceptable range
static void clamp(Image& src);
static void highlight(Image& src);
//! Downsamples a cubemap by helf in x and y using a box filter
static void downsampleCubemapLevelBoxFilter(utils::JobSystem& js, Cubemap& dst, const Cubemap& src);
//! Return the name of a face (suitable for a file name)
static const char* getFaceName(Cubemap::Face face);
//! computes the solid angle of a pixel of a face of a cubemap
static float solidAngle(size_t dim, size_t u, size_t v);
//! Sets a Cubemap faces from a cross image
static void setAllFacesFromCross(Cubemap& cm, const Image& image);
private:
//move these into cmgen?
static void setFaceFromCross(Cubemap& cm, Cubemap::Face face, const Image& image);
static Image createCubemapImage(size_t dim, bool horizontal = true);
#ifndef FILAMENT_IBL_LITE
public:
//! Converts horizontal or vertical cross Image to a Cubemap
static void crossToCubemap(utils::JobSystem& js, Cubemap& dst, const Image& src);
//! Converts equirectangular Image to a Cubemap
static void equirectangularToCubemap(utils::JobSystem& js, Cubemap& dst, const Image& src);
//! Converts a Cubemap to an equirectangular Image
static void cubemapToEquirectangular(utils::JobSystem& js, Image& dst, const Cubemap& src);
//! Converts a Cubemap to an octahedron
static void cubemapToOctahedron(utils::JobSystem& js, Image& dst, const Cubemap& src);
//! mirror the cubemap in the horizontal direction
static void mirrorCubemap(utils::JobSystem& js, Cubemap& dst, const Cubemap& src);
//! generates a UV grid in the cubemap -- useful for debugging.
static void generateUVGrid(utils::JobSystem& js, Cubemap& cml, size_t gridFrequencyX, size_t gridFrequencyY);
#endif
friend class CubemapIBL;
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAP_UTILS_H */

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_IMAGE_H
#define IBL_IMAGE_H
#include <math/scalar.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/compiler.h>
#include <memory>
namespace filament {
namespace ibl {
class UTILS_PUBLIC Image {
public:
Image();
Image(size_t w, size_t h, size_t stride = 0);
void reset();
void set(Image const& image);
void subset(Image const& image, size_t x, size_t y, size_t w, size_t h);
bool isValid() const { return mData != nullptr; }
size_t getWidth() const { return mWidth; }
size_t getStride() const { return mBpr / getBytesPerPixel(); }
size_t getHeight() const { return mHeight; }
size_t getBytesPerRow() const { return mBpr; }
size_t getBytesPerPixel() const { return sizeof(math::float3); }
void* getData() const { return mData; }
size_t getSize() const { return mBpr * mHeight; }
void* getPixelRef(size_t x, size_t y) const;
std::unique_ptr<uint8_t[]> detach() { return std::move(mOwnedData); }
private:
size_t mBpr = 0;
size_t mWidth = 0;
size_t mHeight = 0;
std::unique_ptr<uint8_t[]> mOwnedData;
void* mData = nullptr;
};
inline void* Image::getPixelRef(size_t x, size_t y) const {
return static_cast<uint8_t*>(mData) + y * getBytesPerRow() + x * getBytesPerPixel();
}
} // namespace ibl
} // namespace filament
#endif /* IBL_IMAGE_H */

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
#ifndef IBL_UTILITIES_H
#define IBL_UTILITIES_H
#include <math.h>
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament {
namespace ibl {
template<typename T>
static inline constexpr T sq(T x) {
return x * x;
}
template<typename T>
static inline constexpr T log4(T x) {
// log2(x)/log2(4)
// log2(x)/2
return std::log2(x) * T(0.5);
}
inline bool isPOT(size_t x) {
return !(x & (x - 1));
}
inline filament::math::float2 hammersley(uint32_t i, float iN) {
constexpr float tof = 0.5f / 0x80000000U;
uint32_t bits = i;
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return { i * iN, bits * tof };
}
} // namespace ibl
} // namespace filament
#endif /* IBL_UTILITIES_H */

View File

@@ -0,0 +1,381 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef IMAGE_COLORTRANSFORM_H_
#define IMAGE_COLORTRANSFORM_H_
#include <image/LinearImage.h>
#include <utils/compiler.h>
#include <math/scalar.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/half.h>
#include <algorithm>
#include <memory>
namespace image {
template <typename T>
uint32_t linearToRGB_10_11_11_REV(const T& linear) {
using fp11 = filament::math::fp<0, 5, 6>;
using fp10 = filament::math::fp<0, 5, 5>;
// the max value for a RGB_11_11_10 is {65024, 65024, 64512} : (2 - 2^-M) * 2^(E-1)
// we clamp to the min of that
fp11 r = fp11::fromf(std::min(64512.0f, linear[0]));
fp11 g = fp11::fromf(std::min(64512.0f, linear[1]));
fp10 b = fp10::fromf(std::min(64512.0f, linear[2]));
uint32_t ir = r.bits & 0x7FF;
uint32_t ig = g.bits & 0x7FF;
uint32_t ib = b.bits & 0x3FF;
return (ib << 22) | (ig << 11) | ir;
}
template <typename T>
inline filament::math::float4 linearToRGBM(const T& linear) {
using filament::math::float4;
float4 RGBM(linear[0], linear[1], linear[2], 1.0f);
// Linear to gamma space
RGBM.rgb = sqrt(RGBM.rgb);
// Set the range
RGBM.rgb /= 16.0f;
float maxComponent = std::max(std::max(RGBM.r, RGBM.g), std::max(RGBM.b, 1e-6f));
// Don't let M go below 1 in the [0..16] range
RGBM.a = filament::math::clamp(maxComponent, 1.0f / 16.0f, 1.0f);
RGBM.a = std::ceil(RGBM.a * 255.0f) / 255.0f;
RGBM.rgb = saturate(RGBM.rgb / RGBM.a);
return RGBM;
}
template <typename T>
inline filament::math::float3 RGBMtoLinear(const T& rgbm) {
using filament::math::float3;
float3 linear(rgbm[0], rgbm[1], rgbm[2]);
linear *= rgbm.a * 16.0f;
// Gamma to linear space
return linear * linear;
}
template <typename T>
inline filament::math::float3 linearTosRGB(const T& linear) {
using filament::math::float3;
constexpr float a = 0.055f;
constexpr float a1 = 1.055f;
constexpr float p = 1 / 2.4f;
float3 sRGB;
for (size_t i=0 ; i<3 ; i++) {
if (linear[i] <= 0.0031308f) {
sRGB[i] = linear[i] * 12.92f;
} else {
sRGB[i] = a1 * std::pow(linear[i], p) - a;
}
}
return sRGB;
}
inline float linearTosRGB(float linear) {
if (linear <= 0.0031308f) {
return linear * 12.92f;
} else {
constexpr float a = 0.055f;
constexpr float a1 = 1.055f;
constexpr float p = 1 / 2.4f;
return a1 * std::pow(linear, p) - a;
}
}
template<typename T>
T sRGBToLinear(const T& sRGB);
template<>
inline filament::math::float3 sRGBToLinear(const filament::math::float3& sRGB) {
using filament::math::float3;
constexpr float a = 0.055f;
constexpr float a1 = 1.055f;
constexpr float p = 2.4f;
float3 linear;
for (size_t i=0 ; i<3 ; i++) {
if (sRGB[i] <= 0.04045f) {
linear[i] = sRGB[i] * (1.0f / 12.92f);
} else {
linear[i] = std::pow((sRGB[i] + a) / a1, p);
}
}
return linear;
}
template<>
inline filament::math::float4 sRGBToLinear(const filament::math::float4& sRGB) {
using filament::math::float4;
constexpr float a = 0.055f;
constexpr float a1 = 1.055f;
constexpr float p = 2.4f;
float4 linear;
for (size_t i=0 ; i<3 ; i++) {
if (sRGB[i] <= 0.04045f) {
linear[i] = sRGB[i] * (1.0f / 12.92f);
} else {
linear[i] = std::pow((sRGB[i] + a) / a1, p);
}
}
linear[3] = sRGB[3];
return linear;
}
template<typename T>
T linearToSRGB(const T& color);
template<>
inline filament::math::float3 linearToSRGB(const filament::math::float3& color) {
using filament::math::float3;
float3 sRGBColor{color};
UTILS_NOUNROLL
for (size_t i = 0; i < sRGBColor.size(); i++) {
sRGBColor[i] = (sRGBColor[i] <= 0.0031308f) ?
sRGBColor[i] * 12.92f : (powf(sRGBColor[i], 1.0f / 2.4f) * 1.055f) - 0.055f;
}
return sRGBColor;
}
// Creates a N-channel sRGB image from a linear floating-point image.
// The source image can have more than N channels, but only the first 3 are converted to sRGB.
template<typename T, int N = 3>
std::unique_ptr<uint8_t[]> fromLinearTosRGB(const LinearImage& image) {
const size_t w = image.getWidth();
const size_t h = image.getHeight();
const size_t nchan = image.getChannels();
assert(nchan >= N);
std::unique_ptr<uint8_t[]> dst(new uint8_t[w * h * N * sizeof(T)]);
T* d = reinterpret_cast<T*>(dst.get());
for (size_t y = 0; y < h; ++y) {
float const* p = image.getPixelRef(0, y);
for (size_t x = 0; x < w; ++x, p += nchan, d += N) {
for (int n = 0; n < N; n++) {
float source = n < 3 ? linearTosRGB(p[n]) : p[n];
float target = filament::math::saturate(source) * std::numeric_limits<T>::max() + 0.5f;
d[n] = T(target);
}
}
}
return dst;
}
// Creates a N-channel RGB u8 image from a f32 image.
template<typename T, int N = 3>
std::unique_ptr<uint8_t[]> fromLinearToRGB(const LinearImage& image) {
size_t w = image.getWidth();
size_t h = image.getHeight();
size_t channels = image.getChannels();
assert(channels >= N);
std::unique_ptr<uint8_t[]> dst(new uint8_t[w * h * N * sizeof(T)]);
T* d = reinterpret_cast<T*>(dst.get());
for (size_t y = 0; y < h; ++y) {
float const* p = image.getPixelRef(0, y);
for (size_t x = 0; x < w; ++x, p += channels, d += N) {
for (int n = 0; n < N; n++) {
float target = filament::math::saturate(p[n]) * std::numeric_limits<T>::max() + 0.5f;
d[n] = T(target);
}
}
}
return dst;
}
// Creates a 4-channel RGBM u8 image from a f32 image.
// The source image can have three or more channels, but only the first three are honored.
template <typename T>
std::unique_ptr<uint8_t[]> fromLinearToRGBM(const LinearImage& image) {
using namespace filament::math;
size_t w = image.getWidth();
size_t h = image.getHeight();
UTILS_UNUSED_IN_RELEASE size_t channels = image.getChannels();
assert(channels >= 3);
std::unique_ptr<uint8_t[]> dst(new uint8_t[w * h * 4 * sizeof(T)]);
T* d = reinterpret_cast<T*>(dst.get());
for (size_t y = 0; y < h; ++y) {
for (size_t x = 0; x < w; ++x, d += 4) {
auto src = image.get<float3>((uint32_t) x, (uint32_t) y);
float4 l(linearToRGBM(*src) * std::numeric_limits<T>::max() + 0.5f);
for (size_t i = 0; i < 4; i++) {
d[i] = T(l[i]);
}
}
}
return dst;
}
// Creates a 3-channel RGB_10_11_11_REV image from a f32 image.
// The source image can have three or more channels, but only the first three are honored.
inline std::unique_ptr<uint8_t[]> fromLinearToRGB_10_11_11_REV(const LinearImage& image) {
using namespace filament::math;
size_t w = image.getWidth();
size_t h = image.getHeight();
UTILS_UNUSED_IN_RELEASE size_t channels = image.getChannels();
assert(channels >= 3);
std::unique_ptr<uint8_t[]> dst(new uint8_t[w * h * sizeof(uint32_t)]);
uint8_t* d = dst.get();
for (size_t y = 0; y < h; ++y) {
for (size_t x = 0; x < w; ++x, d += sizeof(uint32_t)) {
auto src = image.get<float3>((uint32_t)x, (uint32_t)y);
uint32_t v = linearToRGB_10_11_11_REV(*src);
*reinterpret_cast<uint32_t*>(d) = v;
}
}
return dst;
}
// Creates a packed single-channel integer-based image from a floating-point image.
// For example if T is uint8_t, then this performs a transformation from [0,1] to [0,255].
template <typename T>
std::unique_ptr<uint8_t[]> fromLinearToGrayscale(const LinearImage& image) {
const size_t w = image.getWidth();
const size_t h = image.getHeight();
assert(image.getChannels() == 1);
std::unique_ptr<uint8_t[]> dst(new uint8_t[w * h * sizeof(T)]);
T* d = reinterpret_cast<T*>(dst.get());
for (size_t y = 0; y < h; ++y) {
float const* p = image.getPixelRef(0, y);
for (size_t x = 0; x < w; ++x, ++p, ++d) {
const float gray = filament::math::saturate(*p) * std::numeric_limits<T>::max() + 0.5f;
d[0] = T(gray);
}
}
return dst;
}
// Constructs a 3-channel LinearImage from an untyped data blob.
// The "proc" lambda converts a single color component into a float.
// The "transform" lambda performs an arbitrary float-to-float transformation.
template<typename T, typename PROCESS, typename TRANSFORM>
static LinearImage toLinear(size_t w, size_t h, size_t bpr,
const uint8_t* src, PROCESS proc, TRANSFORM transform) {
LinearImage result((uint32_t) w, (uint32_t) h, 3);
auto d = result.get< filament::math::float3>();
for (size_t y = 0; y < h; ++y) {
T const* p = reinterpret_cast<T const*>(src + y * bpr);
for (size_t x = 0; x < w; ++x, p += 3) {
filament::math::float3 sRGB(proc(p[0]), proc(p[1]), proc(p[2]));
sRGB /= std::numeric_limits<T>::max();
*d++ = transform(sRGB);
}
}
return result;
}
// Constructs a 3-channel LinearImage from an untyped data blob.
// The "proc" lambda converts a single color component into a float.
// The "transform" lambda performs an arbitrary float-to-float transformation.
template<typename T, typename PROCESS, typename TRANSFORM>
static LinearImage toLinear(size_t w, size_t h, size_t bpr,
const std::unique_ptr<uint8_t[]>& src, PROCESS proc, TRANSFORM transform) {
return toLinear<T>(w, h, bpr, src.get(), proc, transform);
}
// Constructs a 4-channel LinearImage from an untyped data blob.
// The "proc" lambda converts a single color component into a float.
// the "transform" lambda performs an arbitrary float-to-float transformation.
template<typename T, typename PROCESS, typename TRANSFORM>
static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr,
const uint8_t* src, PROCESS proc, TRANSFORM transform) {
LinearImage result((uint32_t) w, (uint32_t) h, 4);
auto d = result.get< filament::math::float4>();
for (size_t y = 0; y < h; ++y) {
T const* p = reinterpret_cast<T const*>(src + y * bpr);
for (size_t x = 0; x < w; ++x, p += 4) {
filament::math::float4 sRGB(proc(p[0]), proc(p[1]), proc(p[2]), proc(p[3]));
sRGB /= std::numeric_limits<T>::max();
*d++ = transform(sRGB);
}
}
return result;
}
// Constructs a 4-channel LinearImage from an untyped data blob.
// The "proc" lambda converts a single color component into a float.
// the "transform" lambda performs an arbitrary float-to-float transformation.
template<typename T, typename PROCESS, typename TRANSFORM>
static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr,
const std::unique_ptr<uint8_t[]>& src, PROCESS proc, TRANSFORM transform) {
return toLinearWithAlpha<T>(w, h, bpr, src.get(), proc, transform);
}
// Constructs a 3-channel LinearImage from RGBM data.
inline LinearImage toLinearFromRGBM( filament::math::float4 const* src, uint32_t w, uint32_t h) {
LinearImage result(w, h, 3);
auto dst = result.get< filament::math::float3>();
for (uint32_t row = 0; row < h; ++row) {
for (uint32_t col = 0; col < w; ++col, ++src, ++dst) {
*dst = RGBMtoLinear(*src);
}
}
return result;
}
inline LinearImage fromLinearToRGBM(const LinearImage& image) {
assert(image.getChannels() == 3);
const uint32_t w = image.getWidth(), h = image.getHeight();
LinearImage result(w, h, 4);
auto src = image.get< filament::math::float3>();
auto dst = result.get< filament::math::float4>();
for (uint32_t row = 0; row < h; ++row) {
for (uint32_t col = 0; col < w; ++col, ++src, ++dst) {
*dst = linearToRGBM(*src);
}
}
return result;
}
template<typename T>
static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr, const uint8_t* src) {
LinearImage result(w, h, 4);
filament::math::float4* d = reinterpret_cast<filament::math::float4*>(result.getPixelRef(0, 0));
for (size_t y = 0; y < h; ++y) {
T const* p = reinterpret_cast<T const*>(src + y * bpr);
for (size_t x = 0; x < w; ++x, p += 4) {
filament::math::float3 sRGB(p[0], p[1], p[2]);
sRGB /= std::numeric_limits<T>::max();
*d++ = filament::math::float4(sRGBToLinear(sRGB), 1.0f);
}
}
return result;
}
template<typename T>
static LinearImage toLinear(size_t w, size_t h, size_t bpr, const uint8_t* src) {
LinearImage result(w, h, 3);
filament::math::float3* d = reinterpret_cast<filament::math::float3*>(result.getPixelRef(0, 0));
for (size_t y = 0; y < h; ++y) {
T const* p = reinterpret_cast<T const*>(src + y * bpr);
for (size_t x = 0; x < w; ++x, p += 3) {
filament::math::float3 sRGB(p[0], p[1], p[2]);
sRGB /= std::numeric_limits<T>::max();
*d++ = sRGBToLinear(sRGB);
}
}
return result;
}
} // namespace Image
#endif // IMAGE_COLORTRANSFORM_H_

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef IMAGE_IMAGEOPS_H
#define IMAGE_IMAGEOPS_H
#include <image/LinearImage.h>
#include <utils/compiler.h>
#include <cstddef>
#include <initializer_list>
namespace image {
// Concatenates images horizontally to create a filmstrip atlas, similar to numpy's hstack.
UTILS_PUBLIC LinearImage horizontalStack(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage horizontalStack(LinearImage const* img, size_t count);
// Concatenates images vertically to create a filmstrip atlas, similar to numpy's vstack.
UTILS_PUBLIC LinearImage verticalStack(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage verticalStack(LinearImage const* img, size_t count);
// Horizontally or vertically mirror the given image.
UTILS_PUBLIC LinearImage horizontalFlip(const LinearImage& image);
UTILS_PUBLIC LinearImage verticalFlip(const LinearImage& image);
// Transforms normals (components live in [-1,+1]) into colors (components live in [0,+1]).
UTILS_PUBLIC LinearImage vectorsToColors(const LinearImage& image);
UTILS_PUBLIC LinearImage colorsToVectors(const LinearImage& image);
// Creates a single-channel image by extracting the selected channel.
UTILS_PUBLIC LinearImage extractChannel(const LinearImage& image, uint32_t channel);
// Constructs a multi-channel image by copying data from a sequence of single-channel images.
UTILS_PUBLIC LinearImage combineChannels(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage combineChannels(LinearImage const* img, size_t count);
// Generates a new image with rows & columns swapped.
UTILS_PUBLIC LinearImage transpose(const LinearImage& image);
// Extracts pixels by specifying a crop window where (0,0) is the top-left corner of the image.
// The boundary is specified as Left Top Right Bottom.
UTILS_PUBLIC
LinearImage cropRegion(const LinearImage& image, uint32_t l, uint32_t t, uint32_t r, uint32_t b);
// Lexicographically compares two images, similar to memcmp.
UTILS_PUBLIC int compare(const LinearImage& a, const LinearImage& b, float epsilon = 0.0f);
// Sets all pixels in all channels to the given value.
UTILS_PUBLIC void clearToValue(LinearImage& img, float value);
// Called by the coordinate field generator to query if a pixel is within the region of interest.
using PresenceCallback = bool(*)(const LinearImage& img, uint32_t col, uint32_t row, void* user);
// Generates a two-channel field of non-normalized coordinates that indicate the nearest pixel
// whose presence function returns true. This is the first step before generating a distance
// field or generalized Voronoi map.
UTILS_PUBLIC
LinearImage computeCoordField(const LinearImage& src, PresenceCallback presence, void* user);
// Generates a single-channel Euclidean distance field with positive values outside the region
// of interest in the source image, and zero values inside. If sqrt is false, the computed
// distances are squared. If signed distance (SDF) is desired, this function can be called a second
// time using an inverted source field.
UTILS_PUBLIC LinearImage edtFromCoordField(const LinearImage& coordField, bool sqrt);
// Dereferences the given coordinate field. Useful for creating Voronoi diagrams or dilated images.
UTILS_PUBLIC
LinearImage voronoiFromCoordField(const LinearImage& coordField, const LinearImage& src);
// Copies content of a source image into a target image. Requires width/height/channels to match.
UTILS_PUBLIC void blitImage(LinearImage& target, const LinearImage& source);
} // namespace image
#endif /* IMAGE_LINEARIMAGE_H */

View File

@@ -0,0 +1,164 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
#ifndef IMAGE_IMAGESAMPLER_H
#define IMAGE_IMAGESAMPLER_H
#include <image/LinearImage.h>
#include <utils/compiler.h>
namespace image {
/**
* Value of a single point sample, allocated according to the number of image channels.
*/
struct UTILS_PUBLIC SingleSample {
float& operator[](int index) { return *(data + index); }
float* data = nullptr;
~SingleSample();
};
/**
* Controls the weighted average used across a window of source samples.
*/
enum class Filter {
DEFAULT, // Selects MITCHELL or LANCZOS dynamically.
BOX, // Computes the un-weighted average over the filter radius.
NEAREST, // Copies the source sample nearest to the center of the filter.
HERMITE, // Also known as "smoothstep", has some nice properties.
GAUSSIAN_SCALARS, // Standard Gaussian filter with sigma = 0.5
GAUSSIAN_NORMALS, // Same as GAUSSIAN_SCALARS, but interpolates unitized vectors.
MITCHELL, // Cubic resampling per Mitchell-Netravali, default for magnification.
LANCZOS, // Popular sinc-based filter, default for minification.
MINIMUM // Takes a min val rather than avg, perhaps useful for depth maps and SDF's.
};
/**
* Defines a viewport inside the texture such that (0,0) is at the top-left corner of the top-left
* pixel, and (1,1) is at the bottom-right corner of the bottom-corner pixel.
*/
struct Region {
float left;
float top;
float right;
float bottom;
};
/**
* Transforms the texel fetching operation when sampling from adjacent images.
*/
enum class Orientation {
STANDARD = 0,
FLIP_X = 1 << 0,
FLIP_Y = 1 << 1,
FLIP_XY = FLIP_X | FLIP_Y
};
/**
* Specifies how to generate samples that lie outside the boundaries of the source region.
*/
struct Boundary {
enum {
EXCLUDE, // Ignore the samples and renormalize the filter. This is probably what you want.
REGION, // Keep samples that are outside sourceRegion if they are still within the image.
CLAMP, // Pretend the edge pixel is repeated forever. Gives edge pixels more weight.
REPEAT, // Resample from the region, wrapping back to the front of the row or column.
MIRROR, // Resample from the region but assume that it has been flipped.
COLOR, // Use the specified constant color.
NEIGHBOR // Sample from an adjacent image.
} mode = EXCLUDE;
SingleSample color; // Used only if mode = COLOR
LinearImage* neighbor = nullptr; // Used only if mode = NEIGHBOR
Orientation orientation; // Used only if mode = NEIGHBOR
};
/**
* Configuration for the resampleImage function. Provides reasonable defaults.
*/
struct ImageSampler {
Filter horizontalFilter = Filter::DEFAULT;
Filter verticalFilter = Filter::DEFAULT;
Region sourceRegion = {0, 0, 1, 1};
float filterRadiusMultiplier = 1;
Boundary east;
Boundary north;
Boundary west;
Boundary south;
};
/**
* Resizes or blurs the given linear image, producing a new linear image with the given dimensions.
*/
UTILS_PUBLIC
LinearImage resampleImage(const LinearImage& source, uint32_t width, uint32_t height,
const ImageSampler& sampler);
/**
* Resizes the given linear image using a simplified API that takes target dimensions and filter.
*/
UTILS_PUBLIC
LinearImage resampleImage(const LinearImage& source, uint32_t width, uint32_t height,
Filter filter = Filter::DEFAULT);
/**
* Computes a single sample for the given texture coordinate and writes the resulting color
* components into the given output holder.
*
* For decent performance, do not call this across the entire image, instead call resampleImage.
* On the first call, pass in a default SingleSample to allocate the result holder. For example:
*
* SingleSample result;
* computeSingleSample(img, 0.5f, 0.5f, &result);
* printf("r g b = %f %f %f\n", result[0], result[1], result[2]);
* computeSingleSample(img, 0.9f, 0.1f, &result);
* printf("r g b = %f %f %f\n", result[0], result[1], result[2]);
*
* The x y coordinates live in "texture space" such that (0.0f, 0.0f) is the upper-left boundary of
* the top-left pixel and (+1.0f, +1.0f) is the lower-right boundary of the bottom-right pixel.
*/
UTILS_PUBLIC
void computeSingleSample(const LinearImage& source, float x, float y, SingleSample* result,
Filter filter = Filter::BOX);
/**
* Generates a sequence of miplevels using the requested filter. To determine the number of mips
* it would take to get down to 1x1, see getMipmapCount.
*
* Source image need not be power-of-two. In the result vector, the half-size image is returned at
* index 0, the quarter-size image is at index 1, etc. Please note that the original-sized image is
* not included.
*/
UTILS_PUBLIC
void generateMipmaps(const LinearImage& source, Filter, LinearImage* result, uint32_t mipCount);
/**
* Returns the number of miplevels it would take to downsample the given image down to 1x1. This
* number does not include the original image (i.e. mip 0).
*/
UTILS_PUBLIC
uint32_t getMipmapCount(const LinearImage& source);
/**
* Given the string name of a filter, converts it to uppercase and returns the corresponding
* enum value. If no corresponding enumerant exists, returns DEFAULT.
*/
UTILS_PUBLIC
Filter filterFromString(const char* name);
} // namespace image
#endif /* IMAGE_IMAGESAMPLER_H */

Some files were not shown because too many files have changed in this diff Show More