add macOS implementation

This commit is contained in:
Nick Fisher
2023-09-05 23:13:59 +08:00
parent c522cd6ee9
commit 84e3124e04
457 changed files with 169627 additions and 15 deletions

View File

@@ -0,0 +1,100 @@
#pragma once
#include <filament/Scene.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/ResourceLoader.h>
#include "SceneAsset.hpp"
#include "ResourceBuffer.hpp"
typedef int32_t EntityId;
namespace polyvox {
using namespace filament;
using namespace filament::gltfio;
class AssetManager {
public:
AssetManager(const ResourceLoaderWrapper* const loader,
NameComponentManager *ncm,
Engine *engine,
Scene *scene);
~AssetManager();
EntityId loadGltf(const char* uri, const char* relativeResourcePath);
EntityId loadGlb(const char* uri, bool unlit);
FilamentAsset* getAssetByEntityId(EntityId entityId);
void remove(EntityId entity);
void destroyAll();
unique_ptr<vector<string>> getAnimationNames(EntityId entity);
float getAnimationDuration(EntityId entity, int animationIndex);
unique_ptr<vector<string>> getMorphTargetNames(EntityId entity, const char *meshName);
void transformToUnitCube(EntityId e);
inline void updateTransform(EntityId e);
void setScale(EntityId e, float scale);
void setPosition(EntityId e, float x, float y, float z);
void setRotation(EntityId e, float rads, float x, float y, float z);
const utils::Entity *getCameraEntities(EntityId e);
size_t getCameraEntityCount(EntityId e);
const utils::Entity* getLightEntities(EntityId e) const noexcept;
size_t getLightEntityCount(EntityId e) const noexcept;
void updateAnimations();
bool setMaterialColor(EntityId e, const char* meshName, int materialInstance, const float r, const float g, const float b, const float a);
bool setMorphAnimationBuffer(
EntityId entityId,
const char* entityName,
const float* const morphData,
const int* const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
void setMorphTargetWeights(EntityId entityId, const char* const entityName, const float* const weights, int count);
bool setBoneAnimationBuffer(
EntityId entity,
const float* const frameData,
int numFrames,
int numBones,
const char** const boneNames,
const char** const meshName,
int numMeshTargets,
float frameLengthInMs);
void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f);
void stopAnimation(EntityId e, int index);
void setMorphTargetWeights(const char* const entityName, float *weights, int count);
void loadTexture(EntityId entity, const char* resourcePath, int renderableIndex);
void setAnimationFrame(EntityId entity, int animationIndex, int animationFrame);
bool hide(EntityId entity, const char* meshName);
bool reveal(EntityId entity, const char* meshName);
private:
AssetLoader* _assetLoader = nullptr;
const ResourceLoaderWrapper* const _resourceLoaderWrapper;
NameComponentManager* _ncm = nullptr;
Engine* _engine;
Scene* _scene;
MaterialProvider* _unlitProvider = nullptr;
MaterialProvider* _ubershaderProvider = nullptr;
gltfio::ResourceLoader* _gltfResourceLoader = nullptr;
gltfio::TextureProvider* _stbDecoder = nullptr;
gltfio::TextureProvider* _ktxDecoder = nullptr;
vector<SceneAsset> _assets;
tsl::robin_map<EntityId, int> _entityIdLookup;
utils::Entity findEntityByName(
SceneAsset asset,
const char* entityName
);
inline void updateTransform(SceneAsset& asset);
inline void setBoneTransform(SceneAsset& asset, int frameNumber);
};
}

View File

@@ -0,0 +1,178 @@
#pragma once
#include <filament/Camera.h>
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
#include <filament/RenderableManager.h>
#include <filament/Renderer.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/TransformManager.h>
#include <filament/VertexBuffer.h>
#include <filament/View.h>
#include <filament/LightManager.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/ResourceLoader.h>
#include <camutils/Manipulator.h>
#include <utils/NameComponentManager.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat3.h>
#include <math/norm.h>
#include <fstream>
#include <iostream>
#include <string>
#include <chrono>
#include "AssetManager.hpp"
using namespace std;
using namespace filament;
using namespace filament::math;
using namespace gltfio;
using namespace camutils;
typedef int32_t EntityId;
namespace polyvox {
enum ToneMapping {
ACES, FILMIC, LINEAR
};
class FilamentViewer {
public:
FilamentViewer(const void* context, const ResourceLoaderWrapper* const resourceLoaderWrapper);
~FilamentViewer();
void setToneMapping(ToneMapping toneMapping);
void setBloom(float strength);
void loadSkybox(const char* const skyboxUri);
void removeSkybox();
void loadIbl(const char* const iblUri, float intensity);
void removeIbl();
void removeAsset(EntityId asset);
// removes all add assets from the current scene
void clearAssets();
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
void render(uint64_t frameTimeInNanos);
void setFrameInterval(float interval);
bool setCamera(EntityId asset, const char* nodeName);
void createSwapChain(const void* surface, uint32_t width, uint32_t height);
void destroySwapChain();
void createRenderTarget(intptr_t textureId, uint32_t width,uint32_t height);
Renderer* getRenderer();
void setBackgroundColor(const float r, const float g, const float b, const float a);
void setBackgroundImage(const char* resourcePath);
void clearBackgroundImage();
void setBackgroundImagePosition(float x, float y, bool clamp);
void setCameraExposure(float aperture, float shutterSpeed, float sensitivity);
void setCameraPosition(float x, float y, float z);
void setCameraRotation(float rads, float x, float y, float z);
void setCameraModelMatrix(const float* const matrix);
void setCameraFocalLength(float fl);
void setCameraFocusDistance(float focusDistance);
void grabBegin(float x, float y, bool pan);
void grabUpdate(float x, float y);
void grabEnd();
void scrollBegin();
void scrollUpdate(float x, float y, float delta);
void scrollEnd();
int32_t addLight(LightManager::Type t, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void removeLight(EntityId entityId);
void clearLights();
AssetManager* const getAssetManager() {
return (AssetManager* const) _assetManager;
}
private:
void createImageRenderable();
void loadResources(std::string relativeResourcePath);
void cleanup();
bool _panning = false;
float _startX;
float _startY;
math::mat4f _cameraPosition;
math::mat4f _cameraRotation;
const ResourceLoaderWrapper* const _resourceLoaderWrapper;
Scene* _scene;
View* _view;
Engine* _engine;
// a default camera that we add to every scene
Camera* _mainCamera;
Renderer* _renderer;
RenderTarget* _rt;
Texture* _rtColor;
Texture* _rtDepth;
SwapChain* _swapChain = nullptr;
AssetManager* _assetManager = nullptr;
NameComponentManager* _ncm = nullptr;
std::mutex mtx; // mutex to ensure thread safety when removing assets
vector<utils::Entity> _lights;
Texture* _skyboxTexture = nullptr;
Skybox* _skybox = nullptr;
Texture* _iblTexture = nullptr;
IndirectLight* _indirectLight = nullptr;
bool _recomputeAabb = false;
bool _actualSize = false;
float _cameraFocalLength = 28.0f;
float _cameraFocusDistance = 0.0f;
ColorGrading *colorGrading = nullptr;
// background image properties
uint32_t _imageHeight = 0;
uint32_t _imageWidth = 0;
mat4f _imageScale;
Texture* _imageTexture = nullptr;
utils::Entity* _imageEntity = nullptr;
VertexBuffer* _imageVb = nullptr;
IndexBuffer* _imageIb = nullptr;
Material* _imageMaterial = nullptr;
TextureSampler _imageSampler;
void loadKtx2Texture(string path, ResourceBuffer data);
void loadKtxTexture(string path, ResourceBuffer data);
void loadPngTexture(string path, ResourceBuffer data);
void loadTextureFromPath(string path);
void _createManipulator();
uint32_t _lastFrameTimeInNanos;
};
}

3621
macos/include/GL/glcorearb.h Normal file

File diff suppressed because it is too large Load Diff

12050
macos/include/GL/glext.h Normal file

File diff suppressed because it is too large Load Diff

850
macos/include/GL/wglext.h Normal file
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

33
macos/include/Log.hpp Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#ifndef POLYVOX_FILAMENT_LOG_H
#define POLYVOX_FILAMENT_LOG_H
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#elif defined __ANDROID__
#include <android/log.h>
#define LOGTAG "PolyvoxFilament"
#else
#include <stdio.h>
#include <iostream>
#endif
static void Log(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
#ifdef __ANDROID__
__android_log_vprint(ANDROID_LOG_DEBUG, LOGTAG, fmt, args);
#elif defined __OBJC__
NSString *format = [[NSString alloc] initWithUTF8String:fmt];
NSLogv(format, args);
#else
vprintf(fmt, args);
std::cout << std::endl;
#endif
va_end(args);
}
#endif

View File

@@ -0,0 +1,103 @@
#ifndef _POLYVOX_FILAMENT_API_H
#define _POLYVOX_FILAMENT_API_H
#include "ResourceBuffer.hpp"
typedef int32_t EntityId;
const void* create_filament_viewer(const void* const context, const ResourceLoaderWrapper* const loader);
ResourceLoaderWrapper* make_resource_loader(LoadResourceFromOwner loadFn, FreeResourceFromOwner freeFn, void* owner);
void delete_filament_viewer(const void* const viewer);
void* get_asset_manager(const void* const viewer);
void create_render_target(const void* const viewer, intptr_t textureId, uint32_t width, uint32_t height);
void clear_background_image(const void* const viewer);
void set_background_image(const void* const viewer, const char *path);
void set_background_image_position(const void* const viewer, float x, float y, bool clamp);
void set_background_color(const void* const viewer, const float r, const float g, const float b, const float a);
void set_tone_mapping(const void* const viewer, int toneMapping);
void set_bloom(const void* const viewer, float strength);
void load_skybox(const void* const viewer, const char *skyboxPath);
void load_ibl(const void* const viewer, const char *iblPath, float intensity);
void remove_skybox(const void* const viewer);
void remove_ibl(const void* const viewer);
EntityId add_light(const void* const viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void remove_light(const void* const viewer, EntityId entityId);
void clear_lights(const void* const viewer);
EntityId load_glb(void *assetManager, const char *assetPath, bool unlit);
EntityId load_gltf(void *assetManager, const char *assetPath, const char *relativePath);
bool set_camera(const void* const viewer, EntityId asset, const char *nodeName);
void render(const void* const viewer, uint64_t frameTimeInNanos);
void create_swap_chain(const void* const viewer, const void* const surface, uint32_t width, uint32_t height);
void destroy_swap_chain(const void* const viewer);
void set_frame_interval(const void* const viewer, float interval);
void update_viewport_and_camera_projection(const void* const viewer, uint32_t width, uint32_t height, float scaleFactor);
void scroll_begin(const void* const viewer);
void scroll_update(const void* const viewer, float x, float y, float z);
void scroll_end(const void* const viewer);
void grab_begin(const void* const viewer, float x, float y, bool pan);
void grab_update(const void* const viewer, float x, float y);
void grab_end(const void* const viewer);
void apply_weights(
void* assetManager,
EntityId asset,
const char *const entityName,
float *const weights,
int count
);
void set_morph_target_weights(
void* assetManager,
EntityId asset,
const char *const entityName,
const float *const morphData,
int numWeights
);
bool set_morph_animation(
void* assetManager,
EntityId asset,
const char *const entityName,
const float *const morphData,
const int* const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
void set_bone_animation(
void* assetManager,
EntityId asset,
const float* const frameData,
int numFrames,
int numBones,
const char** const boneNames,
const char** const meshName,
int numMeshTargets,
float frameLengthInMs);
void play_animation(void* assetManager, EntityId asset, int index, bool loop, bool reverse, bool replaceActive, float crossfade);
void set_animation_frame(void* assetManager, EntityId asset, int animationIndex, int animationFrame);
void stop_animation(void* assetManager, EntityId asset, int index);
int get_animation_count(void* assetManager, EntityId asset);
void get_animation_name(void* assetManager, EntityId asset, char *const outPtr, int index);
float get_animation_duration(void* assetManager, EntityId asset, int index);
void get_morph_target_name(void* assetManager, EntityId asset, const char *meshName, char *const outPtr, int index);
int get_morph_target_name_count(void* assetManager, EntityId asset, const char *meshName);
void remove_asset(const void* const viewer, EntityId asset);
void clear_assets(const void* const viewer);
void load_texture(void* assetManager, EntityId asset, const char *assetPath, int renderableIndex);
void set_texture(void* assetManager, EntityId asset);
bool set_material_color(void* assetManager, EntityId asset, const char* meshName, int materialIndex, const float r, const float g, const float b, const float a);
void transform_to_unit_cube(void* assetManager, EntityId asset);
void set_position(void* assetManager, EntityId asset, float x, float y, float z);
void set_rotation(void* assetManager, EntityId asset, float rads, float x, float y, float z);
void set_scale(void* assetManager, EntityId asset, float scale);
void set_camera_exposure(const void* const viewer, float aperture, float shutterSpeed, float sensitivity);
void set_camera_position(const void* const viewer, float x, float y, float z);
void set_camera_rotation(const void* const viewer, float rads, float x, float y, float z);
void set_camera_model_matrix(const void* const viewer, const float *const matrix);
void set_camera_focal_length(const void* const viewer, float focalLength);
void set_camera_focus_distance(const void* const viewer, float focusDistance);
int hide_mesh(void* assetManager, EntityId asset, const char* meshName);
int reveal_mesh(void* assetManager, EntityId asset, const char* meshName);
void ios_dummy();
#endif

View File

@@ -0,0 +1,81 @@
#ifndef RESOURCE_BUFFER_H
#define RESOURCE_BUFFER_H
#include <stdint.h>
#if defined(__cplusplus)
#include "Log.hpp"
extern "C" {
#endif
//
// Pairs a memory buffer with an ID that can be used to unload the backing asset if needed.
// Use this when you want to load an asset from a resource that requires more than just `free` on the underlying buffer.
// e.g.
// ```
// uint64_t id = get_next_resource_id();
// AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
// off_t length = AAsset_getLength(asset);
// const void * buffer = AAsset_getBuffer(asset);
// uint8_t *buf = new uint8_t[length ];
// memcpy(buf,buffer, length);
// ResourceBuffer rb(buf, length, id);
// ...
// ...
// (elsewhere)
// AAsset* asset = get_asset_from_id(rb.id);
// AAsset_close(asset);
// free_asset_id(rb.id);
//
struct ResourceBuffer {
#if defined(__cplusplus)
ResourceBuffer(const void* const data, const uint32_t size, const uint32_t id) : data(data), size(size), id(id) {};
#endif
const void * const data;
const uint32_t size;
const uint32_t id;
};
typedef struct ResourceBuffer ResourceBuffer;
typedef ResourceBuffer (*FlutterFilamentLoadResource)(const char* uri);
typedef ResourceBuffer (*LoadResourceFromOwner)(const char* const, void* const owner);
typedef void (*FlutterFilamentFreeResource)(ResourceBuffer);
typedef void (*FreeResourceFromOwner)(ResourceBuffer, void* const owner);
// this may be compiled as either C or C++, depending on which compiler is being invoked (e.g. binding to Swift will compile as C).
// the former does not allow default initialization to be specified inline), so we need to explicitly set the unused members to nullptr
struct ResourceLoaderWrapper {
#if defined(__cplusplus)
ResourceLoaderWrapper(FlutterFilamentLoadResource loader, FlutterFilamentFreeResource freeResource) : mLoadResource(loader), mFreeResource(freeResource), mLoadResourceFromOwner(nullptr), mFreeResourceFromOwner(nullptr),
mOwner(nullptr) {}
ResourceLoaderWrapper(LoadResourceFromOwner loader, FreeResourceFromOwner freeResource, void* const owner) : mLoadResource(nullptr), mFreeResource(nullptr), mLoadResourceFromOwner(loader), mFreeResourceFromOwner(freeResource), mOwner(owner) {
};
ResourceBuffer load(const char* uri) const {
if(mLoadResourceFromOwner) {
return mLoadResourceFromOwner(uri, mOwner);
}
return mLoadResource(uri);
}
void free(ResourceBuffer rb) const {
if(mFreeResourceFromOwner) {
mFreeResourceFromOwner(rb, mOwner);
} else {
mFreeResource(rb);
}
}
#endif
FlutterFilamentLoadResource mLoadResource;
FlutterFilamentFreeResource mFreeResource;
LoadResourceFromOwner mLoadResourceFromOwner;
FreeResourceFromOwner mFreeResourceFromOwner;
void* mOwner;
};
typedef struct ResourceLoaderWrapper ResourceLoaderWrapper;
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,110 @@
#pragma once
#include "Log.hpp"
#include <filament/Engine.h>
#include <filament/RenderableManager.h>
#include <filament/Renderer.h>
#include <filament/Scene.h>
#include <filament/Texture.h>
#include <filament/TransformManager.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat3.h>
#include <math/norm.h>
#include <gltfio/Animator.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/ResourceLoader.h>
#include <utils/NameComponentManager.h>
extern "C" {
#include "PolyvoxFilamentApi.h"
}
template class std::vector<float>;
namespace polyvox {
using namespace filament;
using namespace filament::gltfio;
using namespace utils;
using namespace std;
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
enum AnimationType {
MORPH, BONE, GLTF
};
struct AnimationStatus {
time_point_t mStart = time_point_t::max();
bool mLoop = false;
bool mReverse = false;
float mDuration = 0;
AnimationType type;
int gltfIndex = -1;
};
//
// Use this to manually construct a buffer of frame data for morph animations.
//
struct MorphAnimationBuffer {
utils::Entity mMeshTarget;
int mNumFrames = -1;
float mFrameLengthInMs = 0;
vector<float> mFrameData;
vector<int> mMorphIndices;
};
//
// Use this to construct a dynamic (i.e. non-glTF embedded) bone animation.
// Only a single animation is supported at any time (i.e you can't blend animations).
// Multiple bones are supported but these must be skinned to a single mesh target.
//
struct BoneAnimationBuffer {
vector<utils::Entity> mMeshTargets;
vector<uint8_t> mBones;
vector<math::mat4f> mBaseTransforms;
// vector<math::float3> mBaseTranslations; // these are the base transforms for the bones we will animate; the translations/rotations in mFrameData will be relative to this.
// vector<math::quatf> mBaseRotations; // these are the base transforms for the bones we will animate; the translations/rotations in mFrameData will be relative to this.
// vector<math::float3> mBaseScales; // these are the base transforms for the bones we will animate; the translations/rotations in mFrameData will be relative to this.
size_t skinIndex = 0;
int mNumFrames = -1;
float mFrameLengthInMs = 0;
vector<float> mFrameData;
};
struct SceneAsset {
bool mAnimating = false;
FilamentAsset* mAsset = nullptr;
Animator* mAnimator = nullptr;
// vector containing AnimationStatus structs for the morph, bone and/or glTF animations.
vector<AnimationStatus> mAnimations;
// the index of the last active glTF animation,
// used to cross-fade
int fadeGltfAnimationIndex = -1;
float fadeDuration = 0.0f;
float fadeOutAnimationStart = 0.0f;
MorphAnimationBuffer mMorphAnimationBuffer;
BoneAnimationBuffer mBoneAnimationBuffer;
// a slot to preload textures
filament::Texture* mTexture = nullptr;
// initialized to identity
math::mat4f mPosition;
// initialized to identity
math::mat4f mRotation;
float mScale = 1;
SceneAsset(
FilamentAsset* asset
) : mAsset(asset) {
mAnimator = mAsset->getInstance()->getAnimator();
}
};
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <streambuf>
#include <functional>
#include <cassert>
#include <cstring>
namespace polyvox {
using namespace std;
//
// A generic adapter to expose any contiguous section of memory as a std::streambuf.
// Mostly for Android/iOS assets which may not be able to be directly loaded as streams.
//
class StreamBufferAdapter : public std::streambuf
{
public:
StreamBufferAdapter(const char *begin, const char *end);
~StreamBufferAdapter() {
}
streamsize size();
private:
int_type uflow() override;
int_type underflow() override;
int_type pbackfail(int_type ch) override;
streampos seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which) override;
streampos seekpos(streampos sp, ios_base::openmode which) override;
streamsize showmanyc() override;
};
}

View File

@@ -0,0 +1,7 @@
#ifndef SwiftPolyvoxFilamentPlugin_Bridging_Header_h
#define SwiftPolyvoxFilamentPlugin_Bridging_Header_h
#import "PolyvoxFilamentApi.h"
#endif

View File

@@ -0,0 +1,79 @@
/*
* This file is licensed under the zlib/libpng license, included in this
* distribution in the file COPYING.
*/
#include <future>
#include <thread>
#include <deque>
#include <vector>
#include <utility>
#include <chrono>
#include <functional>
#include <type_traits>
#ifndef _THREADPOOL_HPP
#define _THREADPOOL_HPP
namespace polyvox {
class ThreadPool {
std::vector<std::thread> pool;
bool stop;
std::mutex access;
std::condition_variable cond;
std::deque<std::function<void()>> tasks;
public:
explicit ThreadPool(int nr = 1) : stop(false) {
while(nr-->0) {
add_worker();
}
}
~ThreadPool() {
stop = true;
for(std::thread &t : pool) {
t.join();
}
pool.clear();
}
template<class Rt>
auto add_task(std::packaged_task<Rt()>& pt) -> std::future<Rt> {
std::unique_lock<std::mutex> lock(access);
auto ret = pt.get_future();
tasks.push_back([pt=std::make_shared<std::packaged_task<Rt()>>(std::move(pt))]{ (*pt)();});
cond.notify_one();
return ret;
}
private:
void add_worker() {
std::thread t([this]() {
while(!stop) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(access);
if(tasks.empty()) {
cond.wait_for(lock, std::chrono::duration<int, std::milli>(5));
continue;
}
task = std::move(tasks.front());
tasks.pop_front();
}
task();
}
});
pool.push_back(std::move(t));
}
};
}
#endif//_THREADPOOL_HPP
// vim: syntax=cpp11

32
macos/include/TimeIt.hpp Normal file
View File

@@ -0,0 +1,32 @@
#ifndef TIMEIT_H_
#define TIMEIT_H_
#pragma once
#if __cplusplus <= 199711L
#include <ctime>
#else
#include <chrono>
#endif
class Timer
{
public:
Timer() { reset(); }
void reset();
double elapsed();
private:
#if __cplusplus <= 199711L
timespec beg_, end_;
#else
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
#endif
};
#endif // TIMEIT_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();
};
} // 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,162 @@
/*
* 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;
~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 {
uint32_t id; // id set in glsl
std::variant<int32_t, float, bool> 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,295 @@
/*
* 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);
};
} // 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,153 @@
/*
* 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;
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;
} 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) 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.
*/
/**********************************************************************************************
* 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,994 @@
/*
* 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.
*/
/**********************************************************************************************
* Generated by bluevk/bluevk-gen.py
* DO NOT EDIT
**********************************************************************************************/
#ifndef TNT_FILAMENT_BLUEVK_H
#define TNT_FILAMENT_BLUEVK_H
#define VK_ENABLE_BETA_EXTENSIONS
// BlueVK dynamically loads all function pointers, so it cannot allow function prototypes, which
// would assume static linking for Vulkan entry points.
#if defined(VULKAN_H_) && !defined(VK_NO_PROTOTYPES)
#error Please do not include vulkan.h when using BlueVK
#endif
// Even though we don't use function prototypes, we still need to include vulkan.h for all Vulkan
// types, including the PFN_ types.
#ifndef VULKAN_H_
#ifndef VK_NO_PROTOTYPES
#define VK_NO_PROTOTYPES
#endif
#if defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR 1
#elif defined(IOS)
#define VK_USE_PLATFORM_IOS_MVK 1
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_XCB)
#define VK_USE_PLATFORM_XCB_KHR 1
#endif
#if defined(FILAMENT_SUPPORTS_XLIB)
#define VK_USE_PLATFORM_XLIB_KHR 1
#endif
#if defined(FILAMENT_SUPPORTS_WAYLAND)
#define VK_USE_PLATFORM_WAYLAND_KHR 1
#endif
#elif defined(__APPLE__)
#define VK_USE_PLATFORM_MACOS_MVK 1
#elif defined(WIN32)
#define VK_USE_PLATFORM_WIN32_KHR 1
#endif
#include <vulkan/vulkan.h>
#endif
#include <utils/unwindows.h>
namespace bluevk {
// Returns false if BlueGL could not find the Vulkan shared library.
bool initialize();
void bindInstance(VkInstance instance);
#if defined(VK_VERSION_1_0)
extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
extern PFN_vkAllocateMemory vkAllocateMemory;
extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
extern PFN_vkBindBufferMemory vkBindBufferMemory;
extern PFN_vkBindImageMemory vkBindImageMemory;
extern PFN_vkCmdBeginQuery vkCmdBeginQuery;
extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
extern PFN_vkCmdBlitImage vkCmdBlitImage;
extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
extern PFN_vkCmdClearColorImage vkCmdClearColorImage;
extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
extern PFN_vkCmdCopyImage vkCmdCopyImage;
extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
extern PFN_vkCmdDispatch vkCmdDispatch;
extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
extern PFN_vkCmdDraw vkCmdDraw;
extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
extern PFN_vkCmdEndQuery vkCmdEndQuery;
extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
extern PFN_vkCmdFillBuffer vkCmdFillBuffer;
extern PFN_vkCmdNextSubpass vkCmdNextSubpass;
extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
extern PFN_vkCmdPushConstants vkCmdPushConstants;
extern PFN_vkCmdResetEvent vkCmdResetEvent;
extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
extern PFN_vkCmdResolveImage vkCmdResolveImage;
extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
extern PFN_vkCmdSetEvent vkCmdSetEvent;
extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
extern PFN_vkCmdSetScissor vkCmdSetScissor;
extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
extern PFN_vkCmdSetViewport vkCmdSetViewport;
extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
extern PFN_vkCmdWaitEvents vkCmdWaitEvents;
extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
extern PFN_vkCreateBuffer vkCreateBuffer;
extern PFN_vkCreateBufferView vkCreateBufferView;
extern PFN_vkCreateCommandPool vkCreateCommandPool;
extern PFN_vkCreateComputePipelines vkCreateComputePipelines;
extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
extern PFN_vkCreateDevice vkCreateDevice;
extern PFN_vkCreateEvent vkCreateEvent;
extern PFN_vkCreateFence vkCreateFence;
extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
extern PFN_vkCreateImage vkCreateImage;
extern PFN_vkCreateImageView vkCreateImageView;
extern PFN_vkCreateInstance vkCreateInstance;
extern PFN_vkCreatePipelineCache vkCreatePipelineCache;
extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
extern PFN_vkCreateQueryPool vkCreateQueryPool;
extern PFN_vkCreateRenderPass vkCreateRenderPass;
extern PFN_vkCreateSampler vkCreateSampler;
extern PFN_vkCreateSemaphore vkCreateSemaphore;
extern PFN_vkCreateShaderModule vkCreateShaderModule;
extern PFN_vkDestroyBuffer vkDestroyBuffer;
extern PFN_vkDestroyBufferView vkDestroyBufferView;
extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
extern PFN_vkDestroyDevice vkDestroyDevice;
extern PFN_vkDestroyEvent vkDestroyEvent;
extern PFN_vkDestroyFence vkDestroyFence;
extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
extern PFN_vkDestroyImage vkDestroyImage;
extern PFN_vkDestroyImageView vkDestroyImageView;
extern PFN_vkDestroyInstance vkDestroyInstance;
extern PFN_vkDestroyPipeline vkDestroyPipeline;
extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
extern PFN_vkDestroyQueryPool vkDestroyQueryPool;
extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
extern PFN_vkDestroySampler vkDestroySampler;
extern PFN_vkDestroySemaphore vkDestroySemaphore;
extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
extern PFN_vkFreeMemory vkFreeMemory;
extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
extern PFN_vkGetEventStatus vkGetEventStatus;
extern PFN_vkGetFenceStatus vkGetFenceStatus;
extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
extern PFN_vkMapMemory vkMapMemory;
extern PFN_vkMergePipelineCaches vkMergePipelineCaches;
extern PFN_vkQueueBindSparse vkQueueBindSparse;
extern PFN_vkQueueSubmit vkQueueSubmit;
extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
extern PFN_vkResetCommandBuffer vkResetCommandBuffer;
extern PFN_vkResetCommandPool vkResetCommandPool;
extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
extern PFN_vkResetEvent vkResetEvent;
extern PFN_vkResetFences vkResetFences;
extern PFN_vkSetEvent vkSetEvent;
extern PFN_vkUnmapMemory vkUnmapMemory;
extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
extern PFN_vkWaitForFences vkWaitForFences;
#endif // defined(VK_VERSION_1_0)
#if defined(VK_VERSION_1_1)
extern PFN_vkBindBufferMemory2 vkBindBufferMemory2;
extern PFN_vkBindImageMemory2 vkBindImageMemory2;
extern PFN_vkCmdDispatchBase vkCmdDispatchBase;
extern PFN_vkCmdSetDeviceMask vkCmdSetDeviceMask;
extern PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate;
extern PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion;
extern PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate;
extern PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion;
extern PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
extern PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups;
extern PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2;
extern PFN_vkGetDescriptorSetLayoutSupport vkGetDescriptorSetLayoutSupport;
extern PFN_vkGetDeviceGroupPeerMemoryFeatures vkGetDeviceGroupPeerMemoryFeatures;
extern PFN_vkGetDeviceQueue2 vkGetDeviceQueue2;
extern PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2;
extern PFN_vkGetImageSparseMemoryRequirements2 vkGetImageSparseMemoryRequirements2;
extern PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties;
extern PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties;
extern PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties;
extern PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2;
extern PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2;
extern PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2;
extern PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2;
extern PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2;
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2;
extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2;
extern PFN_vkTrimCommandPool vkTrimCommandPool;
extern PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate;
#endif // defined(VK_VERSION_1_1)
#if defined(VK_VERSION_1_2)
extern PFN_vkCmdBeginRenderPass2 vkCmdBeginRenderPass2;
extern PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount;
extern PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount;
extern PFN_vkCmdEndRenderPass2 vkCmdEndRenderPass2;
extern PFN_vkCmdNextSubpass2 vkCmdNextSubpass2;
extern PFN_vkCreateRenderPass2 vkCreateRenderPass2;
extern PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress;
extern PFN_vkGetBufferOpaqueCaptureAddress vkGetBufferOpaqueCaptureAddress;
extern PFN_vkGetDeviceMemoryOpaqueCaptureAddress vkGetDeviceMemoryOpaqueCaptureAddress;
extern PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue;
extern PFN_vkResetQueryPool vkResetQueryPool;
extern PFN_vkSignalSemaphore vkSignalSemaphore;
extern PFN_vkWaitSemaphores vkWaitSemaphores;
#endif // defined(VK_VERSION_1_2)
#if defined(VK_VERSION_1_3)
extern PFN_vkCmdBeginRendering vkCmdBeginRendering;
extern PFN_vkCmdBindVertexBuffers2 vkCmdBindVertexBuffers2;
extern PFN_vkCmdBlitImage2 vkCmdBlitImage2;
extern PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2;
extern PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2;
extern PFN_vkCmdCopyImage2 vkCmdCopyImage2;
extern PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2;
extern PFN_vkCmdEndRendering vkCmdEndRendering;
extern PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2;
extern PFN_vkCmdResetEvent2 vkCmdResetEvent2;
extern PFN_vkCmdResolveImage2 vkCmdResolveImage2;
extern PFN_vkCmdSetCullMode vkCmdSetCullMode;
extern PFN_vkCmdSetDepthBiasEnable vkCmdSetDepthBiasEnable;
extern PFN_vkCmdSetDepthBoundsTestEnable vkCmdSetDepthBoundsTestEnable;
extern PFN_vkCmdSetDepthCompareOp vkCmdSetDepthCompareOp;
extern PFN_vkCmdSetDepthTestEnable vkCmdSetDepthTestEnable;
extern PFN_vkCmdSetDepthWriteEnable vkCmdSetDepthWriteEnable;
extern PFN_vkCmdSetEvent2 vkCmdSetEvent2;
extern PFN_vkCmdSetFrontFace vkCmdSetFrontFace;
extern PFN_vkCmdSetPrimitiveRestartEnable vkCmdSetPrimitiveRestartEnable;
extern PFN_vkCmdSetPrimitiveTopology vkCmdSetPrimitiveTopology;
extern PFN_vkCmdSetRasterizerDiscardEnable vkCmdSetRasterizerDiscardEnable;
extern PFN_vkCmdSetScissorWithCount vkCmdSetScissorWithCount;
extern PFN_vkCmdSetStencilOp vkCmdSetStencilOp;
extern PFN_vkCmdSetStencilTestEnable vkCmdSetStencilTestEnable;
extern PFN_vkCmdSetViewportWithCount vkCmdSetViewportWithCount;
extern PFN_vkCmdWaitEvents2 vkCmdWaitEvents2;
extern PFN_vkCmdWriteTimestamp2 vkCmdWriteTimestamp2;
extern PFN_vkCreatePrivateDataSlot vkCreatePrivateDataSlot;
extern PFN_vkDestroyPrivateDataSlot vkDestroyPrivateDataSlot;
extern PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements;
extern PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements;
extern PFN_vkGetDeviceImageSparseMemoryRequirements vkGetDeviceImageSparseMemoryRequirements;
extern PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties;
extern PFN_vkGetPrivateData vkGetPrivateData;
extern PFN_vkQueueSubmit2 vkQueueSubmit2;
extern PFN_vkSetPrivateData vkSetPrivateData;
#endif // defined(VK_VERSION_1_3)
#if defined(VK_AMD_buffer_marker)
extern PFN_vkCmdWriteBufferMarkerAMD vkCmdWriteBufferMarkerAMD;
#endif // defined(VK_AMD_buffer_marker)
#if defined(VK_AMD_display_native_hdr)
extern PFN_vkSetLocalDimmingAMD vkSetLocalDimmingAMD;
#endif // defined(VK_AMD_display_native_hdr)
#if defined(VK_AMD_draw_indirect_count)
extern PFN_vkCmdDrawIndexedIndirectCountAMD vkCmdDrawIndexedIndirectCountAMD;
extern PFN_vkCmdDrawIndirectCountAMD vkCmdDrawIndirectCountAMD;
#endif // defined(VK_AMD_draw_indirect_count)
#if defined(VK_AMD_shader_info)
extern PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD;
#endif // defined(VK_AMD_shader_info)
#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
extern PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
extern PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
#endif // defined(VK_ANDROID_external_memory_android_hardware_buffer)
#if defined(VK_ANDROID_native_buffer)
extern PFN_vkAcquireImageANDROID vkAcquireImageANDROID;
extern PFN_vkGetSwapchainGrallocUsage2ANDROID vkGetSwapchainGrallocUsage2ANDROID;
extern PFN_vkGetSwapchainGrallocUsageANDROID vkGetSwapchainGrallocUsageANDROID;
extern PFN_vkQueueSignalReleaseImageANDROID vkQueueSignalReleaseImageANDROID;
#endif // defined(VK_ANDROID_native_buffer)
#if defined(VK_EXT_acquire_drm_display)
extern PFN_vkAcquireDrmDisplayEXT vkAcquireDrmDisplayEXT;
extern PFN_vkGetDrmDisplayEXT vkGetDrmDisplayEXT;
#endif // defined(VK_EXT_acquire_drm_display)
#if defined(VK_EXT_acquire_xlib_display)
extern PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT;
extern PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT;
#endif // defined(VK_EXT_acquire_xlib_display)
#if defined(VK_EXT_buffer_device_address)
extern PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT;
#endif // defined(VK_EXT_buffer_device_address)
#if defined(VK_EXT_calibrated_timestamps)
extern PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT;
extern PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT;
#endif // defined(VK_EXT_calibrated_timestamps)
#if defined(VK_EXT_color_write_enable)
extern PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT;
#endif // defined(VK_EXT_color_write_enable)
#if defined(VK_EXT_conditional_rendering)
extern PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT;
extern PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT;
#endif // defined(VK_EXT_conditional_rendering)
#if defined(VK_EXT_debug_marker)
extern PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT;
extern PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT;
extern PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT;
extern PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT;
extern PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTagEXT;
#endif // defined(VK_EXT_debug_marker)
#if defined(VK_EXT_debug_report)
extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
extern PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
#endif // defined(VK_EXT_debug_report)
#if defined(VK_EXT_debug_utils)
extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
extern PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT;
extern PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT;
extern PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT;
extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
extern PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT;
extern PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT;
#endif // defined(VK_EXT_debug_utils)
#if defined(VK_EXT_direct_mode_display)
extern PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT;
#endif // defined(VK_EXT_direct_mode_display)
#if defined(VK_EXT_directfb_surface)
extern PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT;
extern PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT;
#endif // defined(VK_EXT_directfb_surface)
#if defined(VK_EXT_discard_rectangles)
extern PFN_vkCmdSetDiscardRectangleEXT vkCmdSetDiscardRectangleEXT;
#endif // defined(VK_EXT_discard_rectangles)
#if defined(VK_EXT_display_control)
extern PFN_vkDisplayPowerControlEXT vkDisplayPowerControlEXT;
extern PFN_vkGetSwapchainCounterEXT vkGetSwapchainCounterEXT;
extern PFN_vkRegisterDeviceEventEXT vkRegisterDeviceEventEXT;
extern PFN_vkRegisterDisplayEventEXT vkRegisterDisplayEventEXT;
#endif // defined(VK_EXT_display_control)
#if defined(VK_EXT_display_surface_counter)
extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT;
#endif // defined(VK_EXT_display_surface_counter)
#if defined(VK_EXT_extended_dynamic_state)
extern PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT;
extern PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT;
extern PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT;
extern PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT;
extern PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT;
extern PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT;
extern PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT;
extern PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT;
extern PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT;
extern PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT;
extern PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT;
extern PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT;
#endif // defined(VK_EXT_extended_dynamic_state)
#if defined(VK_EXT_extended_dynamic_state2)
extern PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT;
extern PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT;
extern PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT;
extern PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT;
extern PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT;
#endif // defined(VK_EXT_extended_dynamic_state2)
#if defined(VK_EXT_external_memory_host)
extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
#endif // defined(VK_EXT_external_memory_host)
#if defined(VK_EXT_full_screen_exclusive)
extern PFN_vkAcquireFullScreenExclusiveModeEXT vkAcquireFullScreenExclusiveModeEXT;
extern PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT vkGetPhysicalDeviceSurfacePresentModes2EXT;
extern PFN_vkReleaseFullScreenExclusiveModeEXT vkReleaseFullScreenExclusiveModeEXT;
#endif // defined(VK_EXT_full_screen_exclusive)
#if defined(VK_EXT_hdr_metadata)
extern PFN_vkSetHdrMetadataEXT vkSetHdrMetadataEXT;
#endif // defined(VK_EXT_hdr_metadata)
#if defined(VK_EXT_headless_surface)
extern PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT;
#endif // defined(VK_EXT_headless_surface)
#if defined(VK_EXT_host_query_reset)
extern PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT;
#endif // defined(VK_EXT_host_query_reset)
#if defined(VK_EXT_image_compression_control)
extern PFN_vkGetImageSubresourceLayout2EXT vkGetImageSubresourceLayout2EXT;
#endif // defined(VK_EXT_image_compression_control)
#if defined(VK_EXT_image_drm_format_modifier)
extern PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT;
#endif // defined(VK_EXT_image_drm_format_modifier)
#if defined(VK_EXT_line_rasterization)
extern PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT;
#endif // defined(VK_EXT_line_rasterization)
#if defined(VK_EXT_metal_objects)
extern PFN_vkExportMetalObjectsEXT vkExportMetalObjectsEXT;
#endif // defined(VK_EXT_metal_objects)
#if defined(VK_EXT_metal_surface)
extern PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT;
#endif // defined(VK_EXT_metal_surface)
#if defined(VK_EXT_multi_draw)
extern PFN_vkCmdDrawMultiEXT vkCmdDrawMultiEXT;
extern PFN_vkCmdDrawMultiIndexedEXT vkCmdDrawMultiIndexedEXT;
#endif // defined(VK_EXT_multi_draw)
#if defined(VK_EXT_pageable_device_local_memory)
extern PFN_vkSetDeviceMemoryPriorityEXT vkSetDeviceMemoryPriorityEXT;
#endif // defined(VK_EXT_pageable_device_local_memory)
#if defined(VK_EXT_pipeline_properties)
extern PFN_vkGetPipelinePropertiesEXT vkGetPipelinePropertiesEXT;
#endif // defined(VK_EXT_pipeline_properties)
#if defined(VK_EXT_private_data)
extern PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT;
extern PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT;
extern PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT;
extern PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT;
#endif // defined(VK_EXT_private_data)
#if defined(VK_EXT_sample_locations)
extern PFN_vkCmdSetSampleLocationsEXT vkCmdSetSampleLocationsEXT;
extern PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT vkGetPhysicalDeviceMultisamplePropertiesEXT;
#endif // defined(VK_EXT_sample_locations)
#if defined(VK_EXT_tooling_info)
extern PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT;
#endif // defined(VK_EXT_tooling_info)
#if defined(VK_EXT_transform_feedback)
extern PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT;
extern PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT;
extern PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT;
extern PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT;
extern PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT;
extern PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT;
#endif // defined(VK_EXT_transform_feedback)
#if defined(VK_EXT_validation_cache)
extern PFN_vkCreateValidationCacheEXT vkCreateValidationCacheEXT;
extern PFN_vkDestroyValidationCacheEXT vkDestroyValidationCacheEXT;
extern PFN_vkGetValidationCacheDataEXT vkGetValidationCacheDataEXT;
extern PFN_vkMergeValidationCachesEXT vkMergeValidationCachesEXT;
#endif // defined(VK_EXT_validation_cache)
#if defined(VK_EXT_vertex_input_dynamic_state)
extern PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT;
#endif // defined(VK_EXT_vertex_input_dynamic_state)
#if defined(VK_FUCHSIA_buffer_collection)
extern PFN_vkCreateBufferCollectionFUCHSIA vkCreateBufferCollectionFUCHSIA;
extern PFN_vkDestroyBufferCollectionFUCHSIA vkDestroyBufferCollectionFUCHSIA;
extern PFN_vkGetBufferCollectionPropertiesFUCHSIA vkGetBufferCollectionPropertiesFUCHSIA;
extern PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA vkSetBufferCollectionBufferConstraintsFUCHSIA;
extern PFN_vkSetBufferCollectionImageConstraintsFUCHSIA vkSetBufferCollectionImageConstraintsFUCHSIA;
#endif // defined(VK_FUCHSIA_buffer_collection)
#if defined(VK_FUCHSIA_external_memory)
extern PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA;
extern PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA vkGetMemoryZirconHandlePropertiesFUCHSIA;
#endif // defined(VK_FUCHSIA_external_memory)
#if defined(VK_FUCHSIA_external_semaphore)
extern PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA;
extern PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA;
#endif // defined(VK_FUCHSIA_external_semaphore)
#if defined(VK_FUCHSIA_imagepipe_surface)
extern PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA;
#endif // defined(VK_FUCHSIA_imagepipe_surface)
#if defined(VK_GGP_stream_descriptor_surface)
extern PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
#endif // defined(VK_GGP_stream_descriptor_surface)
#if defined(VK_GOOGLE_display_timing)
extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
#endif // defined(VK_GOOGLE_display_timing)
#if defined(VK_HUAWEI_invocation_mask)
extern PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
#endif // defined(VK_HUAWEI_invocation_mask)
#if defined(VK_HUAWEI_subpass_shading)
extern PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
extern PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
#endif // defined(VK_HUAWEI_subpass_shading)
#if defined(VK_INTEL_performance_query)
extern PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
extern PFN_vkCmdSetPerformanceMarkerINTEL vkCmdSetPerformanceMarkerINTEL;
extern PFN_vkCmdSetPerformanceOverrideINTEL vkCmdSetPerformanceOverrideINTEL;
extern PFN_vkCmdSetPerformanceStreamMarkerINTEL vkCmdSetPerformanceStreamMarkerINTEL;
extern PFN_vkGetPerformanceParameterINTEL vkGetPerformanceParameterINTEL;
extern PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL;
extern PFN_vkQueueSetPerformanceConfigurationINTEL vkQueueSetPerformanceConfigurationINTEL;
extern PFN_vkReleasePerformanceConfigurationINTEL vkReleasePerformanceConfigurationINTEL;
extern PFN_vkUninitializePerformanceApiINTEL vkUninitializePerformanceApiINTEL;
#endif // defined(VK_INTEL_performance_query)
#if defined(VK_KHR_acceleration_structure)
extern PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
extern PFN_vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresIndirectKHR;
extern PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
extern PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR;
extern PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR;
extern PFN_vkCmdCopyMemoryToAccelerationStructureKHR vkCmdCopyMemoryToAccelerationStructureKHR;
extern PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR;
extern PFN_vkCopyAccelerationStructureKHR vkCopyAccelerationStructureKHR;
extern PFN_vkCopyAccelerationStructureToMemoryKHR vkCopyAccelerationStructureToMemoryKHR;
extern PFN_vkCopyMemoryToAccelerationStructureKHR vkCopyMemoryToAccelerationStructureKHR;
extern PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
extern PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
extern PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
extern PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
extern PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR;
extern PFN_vkWriteAccelerationStructuresPropertiesKHR vkWriteAccelerationStructuresPropertiesKHR;
#endif // defined(VK_KHR_acceleration_structure)
#if defined(VK_KHR_android_surface)
extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#endif // defined(VK_KHR_android_surface)
#if defined(VK_KHR_bind_memory2)
extern PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
extern PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
#endif // defined(VK_KHR_bind_memory2)
#if defined(VK_KHR_buffer_device_address)
extern PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
extern PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR;
extern PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR;
#endif // defined(VK_KHR_buffer_device_address)
#if defined(VK_KHR_copy_commands2)
extern PFN_vkCmdBlitImage2KHR vkCmdBlitImage2KHR;
extern PFN_vkCmdCopyBuffer2KHR vkCmdCopyBuffer2KHR;
extern PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2KHR;
extern PFN_vkCmdCopyImage2KHR vkCmdCopyImage2KHR;
extern PFN_vkCmdCopyImageToBuffer2KHR vkCmdCopyImageToBuffer2KHR;
extern PFN_vkCmdResolveImage2KHR vkCmdResolveImage2KHR;
#endif // defined(VK_KHR_copy_commands2)
#if defined(VK_KHR_create_renderpass2)
extern PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR;
extern PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR;
extern PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR;
extern PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR;
#endif // defined(VK_KHR_create_renderpass2)
#if defined(VK_KHR_deferred_host_operations)
extern PFN_vkCreateDeferredOperationKHR vkCreateDeferredOperationKHR;
extern PFN_vkDeferredOperationJoinKHR vkDeferredOperationJoinKHR;
extern PFN_vkDestroyDeferredOperationKHR vkDestroyDeferredOperationKHR;
extern PFN_vkGetDeferredOperationMaxConcurrencyKHR vkGetDeferredOperationMaxConcurrencyKHR;
extern PFN_vkGetDeferredOperationResultKHR vkGetDeferredOperationResultKHR;
#endif // defined(VK_KHR_deferred_host_operations)
#if defined(VK_KHR_descriptor_update_template)
extern PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
extern PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
extern PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
#endif // defined(VK_KHR_descriptor_update_template)
#if defined(VK_KHR_device_group)
extern PFN_vkCmdDispatchBaseKHR vkCmdDispatchBaseKHR;
extern PFN_vkCmdSetDeviceMaskKHR vkCmdSetDeviceMaskKHR;
extern PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR vkGetDeviceGroupPeerMemoryFeaturesKHR;
#endif // defined(VK_KHR_device_group)
#if defined(VK_KHR_device_group_creation)
extern PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR;
#endif // defined(VK_KHR_device_group_creation)
#if defined(VK_KHR_display)
extern PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
extern PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
extern PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
extern PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
extern PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
extern PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
extern PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
#endif // defined(VK_KHR_display)
#if defined(VK_KHR_display_swapchain)
extern PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
#endif // defined(VK_KHR_display_swapchain)
#if defined(VK_KHR_draw_indirect_count)
extern PFN_vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountKHR;
extern PFN_vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountKHR;
#endif // defined(VK_KHR_draw_indirect_count)
#if defined(VK_KHR_dynamic_rendering)
extern PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR;
extern PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR;
#endif // defined(VK_KHR_dynamic_rendering)
#if defined(VK_KHR_external_fence_capabilities)
extern PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR vkGetPhysicalDeviceExternalFencePropertiesKHR;
#endif // defined(VK_KHR_external_fence_capabilities)
#if defined(VK_KHR_external_fence_fd)
extern PFN_vkGetFenceFdKHR vkGetFenceFdKHR;
extern PFN_vkImportFenceFdKHR vkImportFenceFdKHR;
#endif // defined(VK_KHR_external_fence_fd)
#if defined(VK_KHR_external_fence_win32)
extern PFN_vkGetFenceWin32HandleKHR vkGetFenceWin32HandleKHR;
extern PFN_vkImportFenceWin32HandleKHR vkImportFenceWin32HandleKHR;
#endif // defined(VK_KHR_external_fence_win32)
#if defined(VK_KHR_external_memory_capabilities)
extern PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR;
#endif // defined(VK_KHR_external_memory_capabilities)
#if defined(VK_KHR_external_memory_fd)
extern PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
extern PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR;
#endif // defined(VK_KHR_external_memory_fd)
#if defined(VK_KHR_external_memory_win32)
extern PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR;
extern PFN_vkGetMemoryWin32HandlePropertiesKHR vkGetMemoryWin32HandlePropertiesKHR;
#endif // defined(VK_KHR_external_memory_win32)
#if defined(VK_KHR_external_semaphore_capabilities)
extern PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR vkGetPhysicalDeviceExternalSemaphorePropertiesKHR;
#endif // defined(VK_KHR_external_semaphore_capabilities)
#if defined(VK_KHR_external_semaphore_fd)
extern PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
extern PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
#endif // defined(VK_KHR_external_semaphore_fd)
#if defined(VK_KHR_external_semaphore_win32)
extern PFN_vkGetSemaphoreWin32HandleKHR vkGetSemaphoreWin32HandleKHR;
extern PFN_vkImportSemaphoreWin32HandleKHR vkImportSemaphoreWin32HandleKHR;
#endif // defined(VK_KHR_external_semaphore_win32)
#if defined(VK_KHR_fragment_shading_rate)
extern PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR;
extern PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR vkGetPhysicalDeviceFragmentShadingRatesKHR;
#endif // defined(VK_KHR_fragment_shading_rate)
#if defined(VK_KHR_get_display_properties2)
extern PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR;
extern PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR;
extern PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR;
extern PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR;
#endif // defined(VK_KHR_get_display_properties2)
#if defined(VK_KHR_get_memory_requirements2)
extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
extern PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
extern PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
#endif // defined(VK_KHR_get_memory_requirements2)
#if defined(VK_KHR_get_physical_device_properties2)
extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
extern PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
extern PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR;
extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
#endif // defined(VK_KHR_get_physical_device_properties2)
#if defined(VK_KHR_get_surface_capabilities2)
extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
extern PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
#endif // defined(VK_KHR_get_surface_capabilities2)
#if defined(VK_KHR_maintenance1)
extern PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
#endif // defined(VK_KHR_maintenance1)
#if defined(VK_KHR_maintenance3)
extern PFN_vkGetDescriptorSetLayoutSupportKHR vkGetDescriptorSetLayoutSupportKHR;
#endif // defined(VK_KHR_maintenance3)
#if defined(VK_KHR_maintenance4)
extern PFN_vkGetDeviceBufferMemoryRequirementsKHR vkGetDeviceBufferMemoryRequirementsKHR;
extern PFN_vkGetDeviceImageMemoryRequirementsKHR vkGetDeviceImageMemoryRequirementsKHR;
extern PFN_vkGetDeviceImageSparseMemoryRequirementsKHR vkGetDeviceImageSparseMemoryRequirementsKHR;
#endif // defined(VK_KHR_maintenance4)
#if defined(VK_KHR_performance_query)
extern PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR;
extern PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR;
extern PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR;
extern PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR;
#endif // defined(VK_KHR_performance_query)
#if defined(VK_KHR_pipeline_executable_properties)
extern PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInternalRepresentationsKHR;
extern PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
extern PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
#endif // defined(VK_KHR_pipeline_executable_properties)
#if defined(VK_KHR_present_wait)
extern PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
#endif // defined(VK_KHR_present_wait)
#if defined(VK_KHR_push_descriptor)
extern PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
#endif // defined(VK_KHR_push_descriptor)
#if (defined(VK_KHR_ray_tracing_maintenance1) && defined(VK_KHR_ray_tracing_pipeline))
extern PFN_vkCmdTraceRaysIndirect2KHR vkCmdTraceRaysIndirect2KHR;
#endif // (defined(VK_KHR_ray_tracing_maintenance1) && defined(VK_KHR_ray_tracing_pipeline))
#if defined(VK_KHR_ray_tracing_pipeline)
extern PFN_vkCmdSetRayTracingPipelineStackSizeKHR vkCmdSetRayTracingPipelineStackSizeKHR;
extern PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR;
extern PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
extern PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
extern PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR vkGetRayTracingCaptureReplayShaderGroupHandlesKHR;
extern PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
extern PFN_vkGetRayTracingShaderGroupStackSizeKHR vkGetRayTracingShaderGroupStackSizeKHR;
#endif // defined(VK_KHR_ray_tracing_pipeline)
#if defined(VK_KHR_sampler_ycbcr_conversion)
extern PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
extern PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
#endif // defined(VK_KHR_sampler_ycbcr_conversion)
#if defined(VK_KHR_shared_presentable_image)
extern PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR;
#endif // defined(VK_KHR_shared_presentable_image)
#if defined(VK_KHR_surface)
extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
#endif // defined(VK_KHR_surface)
#if defined(VK_KHR_swapchain)
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
#endif // defined(VK_KHR_swapchain)
#if defined(VK_KHR_synchronization2)
extern PFN_vkCmdPipelineBarrier2KHR vkCmdPipelineBarrier2KHR;
extern PFN_vkCmdResetEvent2KHR vkCmdResetEvent2KHR;
extern PFN_vkCmdSetEvent2KHR vkCmdSetEvent2KHR;
extern PFN_vkCmdWaitEvents2KHR vkCmdWaitEvents2KHR;
extern PFN_vkCmdWriteTimestamp2KHR vkCmdWriteTimestamp2KHR;
extern PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
#endif // defined(VK_KHR_synchronization2)
#if (defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker))
extern PFN_vkCmdWriteBufferMarker2AMD vkCmdWriteBufferMarker2AMD;
#endif // (defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker))
#if (defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints))
extern PFN_vkGetQueueCheckpointData2NV vkGetQueueCheckpointData2NV;
#endif // (defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints))
#if defined(VK_KHR_timeline_semaphore)
extern PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
extern PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR;
extern PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR;
#endif // defined(VK_KHR_timeline_semaphore)
#if defined(VK_KHR_video_decode_queue)
extern PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR;
#endif // defined(VK_KHR_video_decode_queue)
#if defined(VK_KHR_video_encode_queue)
extern PFN_vkCmdEncodeVideoKHR vkCmdEncodeVideoKHR;
#endif // defined(VK_KHR_video_encode_queue)
#if defined(VK_KHR_video_queue)
extern PFN_vkBindVideoSessionMemoryKHR vkBindVideoSessionMemoryKHR;
extern PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR;
extern PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR;
extern PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR;
extern PFN_vkCreateVideoSessionKHR vkCreateVideoSessionKHR;
extern PFN_vkCreateVideoSessionParametersKHR vkCreateVideoSessionParametersKHR;
extern PFN_vkDestroyVideoSessionKHR vkDestroyVideoSessionKHR;
extern PFN_vkDestroyVideoSessionParametersKHR vkDestroyVideoSessionParametersKHR;
extern PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR vkGetPhysicalDeviceVideoCapabilitiesKHR;
extern PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR vkGetPhysicalDeviceVideoFormatPropertiesKHR;
extern PFN_vkGetVideoSessionMemoryRequirementsKHR vkGetVideoSessionMemoryRequirementsKHR;
extern PFN_vkUpdateVideoSessionParametersKHR vkUpdateVideoSessionParametersKHR;
#endif // defined(VK_KHR_video_queue)
#if defined(VK_KHR_wayland_surface)
extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
extern PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
#endif // defined(VK_KHR_wayland_surface)
#if defined(VK_KHR_win32_surface)
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
extern PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
#endif // defined(VK_KHR_win32_surface)
#if defined(VK_KHR_xcb_surface)
extern PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
#endif // defined(VK_KHR_xcb_surface)
#if defined(VK_KHR_xlib_surface)
extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
extern PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
#endif // defined(VK_KHR_xlib_surface)
#if defined(VK_MVK_ios_surface)
extern PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK;
#endif // defined(VK_MVK_ios_surface)
#if defined(VK_MVK_macos_surface)
extern PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
#endif // defined(VK_MVK_macos_surface)
#if defined(VK_NN_vi_surface)
extern PFN_vkCreateViSurfaceNN vkCreateViSurfaceNN;
#endif // defined(VK_NN_vi_surface)
#if defined(VK_NVX_binary_import)
extern PFN_vkCmdCuLaunchKernelNVX vkCmdCuLaunchKernelNVX;
extern PFN_vkCreateCuFunctionNVX vkCreateCuFunctionNVX;
extern PFN_vkCreateCuModuleNVX vkCreateCuModuleNVX;
extern PFN_vkDestroyCuFunctionNVX vkDestroyCuFunctionNVX;
extern PFN_vkDestroyCuModuleNVX vkDestroyCuModuleNVX;
#endif // defined(VK_NVX_binary_import)
#if defined(VK_NVX_image_view_handle)
extern PFN_vkGetImageViewAddressNVX vkGetImageViewAddressNVX;
extern PFN_vkGetImageViewHandleNVX vkGetImageViewHandleNVX;
#endif // defined(VK_NVX_image_view_handle)
#if defined(VK_NV_acquire_winrt_display)
extern PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV;
extern PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV;
#endif // defined(VK_NV_acquire_winrt_display)
#if defined(VK_NV_clip_space_w_scaling)
extern PFN_vkCmdSetViewportWScalingNV vkCmdSetViewportWScalingNV;
#endif // defined(VK_NV_clip_space_w_scaling)
#if defined(VK_NV_cooperative_matrix)
extern PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV vkGetPhysicalDeviceCooperativeMatrixPropertiesNV;
#endif // defined(VK_NV_cooperative_matrix)
#if defined(VK_NV_coverage_reduction_mode)
extern PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
#endif // defined(VK_NV_coverage_reduction_mode)
#if defined(VK_NV_device_diagnostic_checkpoints)
extern PFN_vkCmdSetCheckpointNV vkCmdSetCheckpointNV;
extern PFN_vkGetQueueCheckpointDataNV vkGetQueueCheckpointDataNV;
#endif // defined(VK_NV_device_diagnostic_checkpoints)
#if defined(VK_NV_device_generated_commands)
extern PFN_vkCmdBindPipelineShaderGroupNV vkCmdBindPipelineShaderGroupNV;
extern PFN_vkCmdExecuteGeneratedCommandsNV vkCmdExecuteGeneratedCommandsNV;
extern PFN_vkCmdPreprocessGeneratedCommandsNV vkCmdPreprocessGeneratedCommandsNV;
extern PFN_vkCreateIndirectCommandsLayoutNV vkCreateIndirectCommandsLayoutNV;
extern PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
extern PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
#endif // defined(VK_NV_device_generated_commands)
#if defined(VK_NV_external_memory_capabilities)
extern PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
#endif // defined(VK_NV_external_memory_capabilities)
#if defined(VK_NV_external_memory_rdma)
extern PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
#endif // defined(VK_NV_external_memory_rdma)
#if defined(VK_NV_external_memory_win32)
extern PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
#endif // defined(VK_NV_external_memory_win32)
#if defined(VK_NV_fragment_shading_rate_enums)
extern PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV;
#endif // defined(VK_NV_fragment_shading_rate_enums)
#if defined(VK_NV_mesh_shader)
extern PFN_vkCmdDrawMeshTasksIndirectCountNV vkCmdDrawMeshTasksIndirectCountNV;
extern PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV;
extern PFN_vkCmdDrawMeshTasksNV vkCmdDrawMeshTasksNV;
#endif // defined(VK_NV_mesh_shader)
#if defined(VK_NV_ray_tracing)
extern PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV;
extern PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV;
extern PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV;
extern PFN_vkCmdTraceRaysNV vkCmdTraceRaysNV;
extern PFN_vkCmdWriteAccelerationStructuresPropertiesNV vkCmdWriteAccelerationStructuresPropertiesNV;
extern PFN_vkCompileDeferredNV vkCompileDeferredNV;
extern PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV;
extern PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV;
extern PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV;
extern PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV;
extern PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV;
extern PFN_vkGetRayTracingShaderGroupHandlesNV vkGetRayTracingShaderGroupHandlesNV;
#endif // defined(VK_NV_ray_tracing)
#if defined(VK_NV_scissor_exclusive)
extern PFN_vkCmdSetExclusiveScissorNV vkCmdSetExclusiveScissorNV;
#endif // defined(VK_NV_scissor_exclusive)
#if defined(VK_NV_shading_rate_image)
extern PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV;
extern PFN_vkCmdSetCoarseSampleOrderNV vkCmdSetCoarseSampleOrderNV;
extern PFN_vkCmdSetViewportShadingRatePaletteNV vkCmdSetViewportShadingRatePaletteNV;
#endif // defined(VK_NV_shading_rate_image)
#if defined(VK_QNX_screen_surface)
extern PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX;
extern PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX;
#endif // defined(VK_QNX_screen_surface)
#if defined(VK_VALVE_descriptor_set_host_mapping)
extern PFN_vkGetDescriptorSetHostMappingVALVE vkGetDescriptorSetHostMappingVALVE;
extern PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE vkGetDescriptorSetLayoutHostMappingInfoVALVE;
#endif // defined(VK_VALVE_descriptor_set_host_mapping)
#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
extern PFN_vkGetDeviceGroupSurfacePresentModes2EXT vkGetDeviceGroupSurfacePresentModes2EXT;
#endif // (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
extern PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
#endif // (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
extern PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR;
extern PFN_vkGetDeviceGroupSurfacePresentModesKHR vkGetDeviceGroupSurfacePresentModesKHR;
extern PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR;
#endif // (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
extern PFN_vkAcquireNextImage2KHR vkAcquireNextImage2KHR;
#endif // (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
} // namespace bluevk
#if !defined(NDEBUG)
#include <utils/Log.h>
utils::io::ostream& operator<<(utils::io::ostream& out, const VkImageLayout& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAttachmentLoadOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAttachmentStoreOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkImageType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkImageTiling& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkImageViewType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCommandBufferLevel& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkComponentSwizzle& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDescriptorType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkQueryType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkBorderColor& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPipelineBindPoint& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPipelineCacheHeaderVersion& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPrimitiveTopology& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSharingMode& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkIndexType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFilter& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSamplerMipmapMode& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSamplerAddressMode& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCompareOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPolygonMode& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFrontFace& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkBlendFactor& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkBlendOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkStencilOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkLogicOp& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkInternalAllocationType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSystemAllocationScope& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPhysicalDeviceType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkVertexInputRate& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFormat& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkStructureType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSubpassContents& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkResult& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDynamicState& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDescriptorUpdateTemplateType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkObjectType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSemaphoreType& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPresentModeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkColorSpaceKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkTimeDomainEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDebugReportObjectTypeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDeviceMemoryReportEventTypeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkRasterizationOrderAMD& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkValidationCheckEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkValidationFeatureEnableEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkValidationFeatureDisableEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkIndirectCommandsTokenTypeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDisplayPowerStateEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDeviceEventTypeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDisplayEventTypeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkViewportCoordinateSwizzleNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDiscardRectangleModeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPointClippingBehavior& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSamplerReductionMode& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkTessellationDomainOrigin& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSamplerYcbcrModelConversion& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSamplerYcbcrRange& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkChromaLocation& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkBlendOverlapEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCoverageModulationModeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCoverageReductionModeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkValidationCacheHeaderVersionEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkShaderInfoTypeAMD& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkQueueGlobalPriorityKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkConservativeRasterizationModeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkVendorId& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkDriverId& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkShadingRatePaletteEntryNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCoarseSampleOrderTypeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkCopyAccelerationStructureModeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkBuildAccelerationStructureModeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAccelerationStructureTypeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkGeometryTypeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAccelerationStructureMemoryRequirementsTypeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAccelerationStructureBuildTypeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkRayTracingShaderGroupTypeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAccelerationStructureCompatibilityKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkShaderGroupShaderKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkMemoryOverallocationBehaviorAMD& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkScopeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkComponentTypeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceCounterScopeKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceCounterUnitKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceCounterStorageKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceConfigurationTypeINTEL& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkQueryPoolSamplingModeINTEL& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceOverrideTypeINTEL& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceParameterTypeINTEL& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPerformanceValueTypeINTEL& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkShaderFloatControlsIndependence& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkPipelineExecutableStatisticFormatKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkLineRasterizationModeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFragmentShadingRateCombinerOpKHR& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFragmentShadingRateNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkFragmentShadingRateTypeNV& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkSubpassMergeStatusEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkProvokingVertexModeEXT& value);
utils::io::ostream& operator<<(utils::io::ostream& out, const VkAccelerationStructureMotionInstanceTypeNV& value);
#endif
#endif // TNT_FILAMENT_BLUEVK_H

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

6552
macos/include/cgltf.h Normal file

File diff suppressed because it is too large Load Diff

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_FILAFLAT_CHUNK_CONTAINER_H
#define TNT_FILAFLAT_CHUNK_CONTAINER_H
#include <utils/compiler.h>
#include <filament/MaterialChunkType.h>
#include <utils/FixedCapacityVector.h>
#include <tsl/robin_map.h>
namespace filaflat {
using ShaderContent = utils::FixedCapacityVector<uint8_t>;
using BlobDictionary = utils::FixedCapacityVector<ShaderContent>;
class Unflattener;
// Allows to build a map of chunks in a Package and get direct individual access based on chunk ID.
class UTILS_PUBLIC ChunkContainer {
public:
using Type = filamat::ChunkType;
ChunkContainer(void const* data, size_t size) : mData(data), mSize(size) {}
~ChunkContainer() noexcept;
// Must be called before trying to access any of the chunk. Fails and return false ONLY if
// an incomplete chunk is found or if a chunk with bogus size is found.
bool parse() noexcept;
typedef struct {
const uint8_t* start;
size_t size;
} ChunkDesc;
typedef struct {
Type type;
ChunkDesc desc;
} Chunk;
size_t getChunkCount() const noexcept {
return mChunks.size();
}
Chunk getChunk(size_t index) const noexcept {
auto it = mChunks.begin();
std::advance(it, index);
return { it->first, it->second };
}
std::pair<uint8_t const*, uint8_t const*> getChunkRange(Type type) const noexcept {
ChunkDesc const* pChunkDesc;
bool success = hasChunk(type, &pChunkDesc);
if (success) {
return { pChunkDesc->start, pChunkDesc->start + pChunkDesc->size };
}
return { nullptr, nullptr };
}
bool hasChunk(Type type, ChunkDesc const** pChunkDesc = nullptr) const noexcept {
auto& chunks = mChunks;
auto pos = chunks.find(type);
if (pos != chunks.end()) {
if (pChunkDesc) {
*pChunkDesc = &pos.value();
}
return true;
}
return false;
}
void const* getData() const { return mData; }
size_t getSize() const { return mSize; }
private:
bool parseChunk(Unflattener& unflattener);
void const* mData;
size_t mSize;
tsl::robin_map<Type, ChunkContainer::ChunkDesc> mChunks;
};
} // namespace filaflat
#endif

View File

@@ -0,0 +1,32 @@
/*
* 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_FILAFLAT_DICTIONARY_READER_H
#define TNT_FILAFLAT_DICTIONARY_READER_H
#include <filaflat/ChunkContainer.h>
namespace filaflat {
struct DictionaryReader {
static bool unflatten(ChunkContainer const& container,
ChunkContainer::Type dictionaryTag,
BlobDictionary& dictionary);
};
} // namespace filaflat
#endif // TNT_FILAFLAT_DICTIONARY_READER_H

View File

@@ -0,0 +1,70 @@
/*
* 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_MATERIAL_CHUNK_H
#define TNT_FILAMAT_MATERIAL_CHUNK_H
#include <filament/MaterialChunkType.h>
#include <filaflat/ChunkContainer.h>
#include <filaflat/Unflattener.h>
#include <private/filament/Variant.h>
#include <tsl/robin_map.h>
namespace filaflat {
class MaterialChunk {
public:
using Variant = filament::Variant;
explicit MaterialChunk(ChunkContainer const& container);
~MaterialChunk() noexcept;
// call this once after container.parse() has been called
bool initialize(filamat::ChunkType materialTag);
// call this as many times as needed
// populates "shaderContent" with the requested shader, or returns false on failure.
bool getShader(ShaderContent& shaderContent, BlobDictionary const& dictionary,
uint8_t shaderModel, Variant variant, uint8_t stage);
// These methods are for debugging purposes only (matdbg)
// @{
static void decodeKey(uint32_t key, uint8_t* model, Variant::type_t* variant, uint8_t* stage);
const tsl::robin_map<uint32_t, uint32_t>& getOffsets() const { return mOffsets; }
// @}
private:
ChunkContainer const& mContainer;
filamat::ChunkType mMaterialTag = filamat::ChunkType::Unknown;
Unflattener mUnflattener;
const uint8_t* mBase = nullptr;
tsl::robin_map<uint32_t, uint32_t> mOffsets;
bool getTextShader(Unflattener unflattener,
BlobDictionary const& dictionary, ShaderContent& shaderContent,
uint8_t shaderModel, Variant variant, uint8_t stage);
bool getSpirvShader(
BlobDictionary const& dictionary, ShaderContent& shaderContent,
uint8_t shaderModel, Variant variant, uint8_t stage);
};
} // namespace filamat
#endif // TNT_FILAMAT_MATERIAL_CHUNK_H

View File

@@ -0,0 +1,163 @@
/*
* 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_FILAFLAT_UNFLATTENER_H
#define TNT_FILAFLAT_UNFLATTENER_H
#include <utils/compiler.h>
#include <utils/CString.h>
#include <private/filament/Variant.h>
#include <stdint.h>
namespace filaflat {
// Allow read operation from an Unflattenable. All READ operation MUST go through the Unflattener
// since it checks boundaries before readind. All read operations return values MUST be verified,
// never assume a read will succeed.
class UTILS_PUBLIC Unflattener {
public:
Unflattener() noexcept = default;
Unflattener(const uint8_t* src, const uint8_t* end)
: mSrc(src), mCursor(src), mEnd(end) {
assert_invariant(src && end);
}
Unflattener(Unflattener const& rhs) = default;
~Unflattener() noexcept = default;
bool hasData() const noexcept {
return mCursor < mEnd;
}
inline bool willOverflow(size_t size) const noexcept {
return (mCursor + size) > mEnd;
}
void skipAlignmentPadding() {
const uint8_t padSize = (8 - (intptr_t(mCursor) % 8)) % 8;
mCursor += padSize;
assert_invariant(0 == (intptr_t(mCursor) % 8));
}
bool read(bool* b) noexcept {
if (willOverflow(1)) {
return false;
}
*b = mCursor[0];
mCursor += 1;
return true;
}
bool read(uint8_t* i) noexcept {
if (willOverflow(1)) {
return false;
}
*i = mCursor[0];
mCursor += 1;
return true;
}
bool read(filament::Variant* v) noexcept {
return read(&v->key);
}
bool read(uint16_t* i) noexcept {
if (willOverflow(2)) {
return false;
}
*i = 0;
*i |= mCursor[0];
*i |= mCursor[1] << 8;
mCursor += 2;
return true;
}
bool read(uint32_t* i) noexcept {
if (willOverflow(4)) {
return false;
}
*i = 0;
*i |= mCursor[0];
*i |= mCursor[1] << 8;
*i |= mCursor[2] << 16;
*i |= mCursor[3] << 24;
mCursor += 4;
return true;
}
bool read(uint64_t* i) noexcept {
if (willOverflow(8)) {
return false;
}
*i = 0;
*i |= static_cast<int64_t>(mCursor[0]);
*i |= static_cast<int64_t>(mCursor[1]) << 8;
*i |= static_cast<int64_t>(mCursor[2]) << 16;
*i |= static_cast<int64_t>(mCursor[3]) << 24;
*i |= static_cast<int64_t>(mCursor[4]) << 32;
*i |= static_cast<int64_t>(mCursor[5]) << 40;
*i |= static_cast<int64_t>(mCursor[6]) << 48;
*i |= static_cast<int64_t>(mCursor[7]) << 56;
mCursor += 8;
return true;
}
bool read(utils::CString* s) noexcept;
bool read(const char** blob, size_t* size) noexcept;
bool read(const char** s) noexcept;
bool read(float* f) noexcept {
if (willOverflow(4)) {
return false;
}
uint32_t i;
i = 0;
i |= mCursor[0];
i |= mCursor[1] << 8;
i |= mCursor[2] << 16;
i |= mCursor[3] << 24;
*f = reinterpret_cast<float&>(i);
mCursor += 4;
return true;
}
const uint8_t* getCursor() const noexcept {
return mCursor;
}
void setCursor(const uint8_t* cursor) noexcept {
if (mSrc <= cursor && cursor < mEnd) {
mCursor = cursor;
} else {
mCursor = mEnd;
}
}
private:
const uint8_t* mSrc = nullptr;
const uint8_t* mCursor = nullptr;
const uint8_t* mEnd = nullptr;
};
} //namespace filaflat
#endif // TNT_FILAFLAT_UNFLATTENER_H

View File

@@ -0,0 +1,59 @@
/*
* 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 FILAGUI_IMGUIEXTENSIONS_H
#define FILAGUI_IMGUIEXTENSIONS_H
#include <utils/compiler.h>
struct ImVec2;
/**
* Namespace for custom widgets that follow the API conventions used by ImGui.
* For example, the prototype for ImGuiExt::DirectionWidget is similar to ImGui::DragFloat3.
*/
namespace ImGuiExt {
/*
* Draws an arrow widget for manipulating a unit vector (inspired by AntTweakBar).
*
* This adds a draggable 3D arrow widget to the current ImGui window, as well as a label and
* three spin boxes that can be dragged or double-clicked for manual entry.
*
* The widget allow users to enter arbitrary vectors, so clients should copy the UI value
* then normalize it. Clients should not directly normalize the UI value as this would cause
* surprises for users who attempt to type in individual components.
*/
UTILS_PUBLIC
bool DirectionWidget(const char* label, float v[3]);
/**
* Draws a plot with multiple series. The parameters are the same as for ImGui::ImPlotLines
* except for the following:
* - series_start: called when a new series starts rendering, this can be used to customize
* the series' style for instance
* - series_end: called when a series is done rendering
* - values_getter: the first parameter indicates which series is being rendered
*/
UTILS_PUBLIC
void PlotLinesSeries(const char* label, int series_count,
void (*series_start)(int series),
float (*values_getter)(int series, void* data, int idx),
void (*series_end)(int series),
void* data, int values_count, int values_offset, const char* overlay_text,
float scale_min, float scale_max, ImVec2 graph_size);
}
#endif // FILAGUI_IMGUIEXTENSIONS_H

View File

@@ -0,0 +1,102 @@
/*
* 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 FILAGUI_IMGUIHELPER_H_
#define FILAGUI_IMGUIHELPER_H_
#include <vector>
#include <functional>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
#include <filament/Texture.h>
#include <filament/TextureSampler.h>
#include <filament/VertexBuffer.h>
#include <filament/View.h>
#include <utils/Entity.h>
#include <utils/Path.h>
struct ImDrawData;
struct ImGuiIO;
struct ImGuiContext;
namespace filagui {
// Translates ImGui's draw commands into Filament primitives, textures, vertex buffers, etc.
// Creates a UI-specific Scene object and populates it with a Renderable. Does not handle
// event processing; clients can simply call ImGui::GetIO() directly and set the mouse state.
class UTILS_PUBLIC ImGuiHelper {
public:
// Using std::function instead of a vanilla C callback to make it easy for clients to pass in
// lambdas that have captures.
using Callback = std::function<void(filament::Engine*, filament::View*)>;
// The constructor creates its own Scene and places it in the given View.
ImGuiHelper(filament::Engine* engine, filament::View* view, const utils::Path& fontPath,
ImGuiContext* imGuiContext = nullptr);
~ImGuiHelper();
// Informs ImGui of the current display size, as well as a scaling factor when scissoring.
void setDisplaySize(int width, int height, float scaleX = 1.0f,
float scaleY = 1.0f, bool flipVertical = false);
// High-level utility method that takes a callback for creating all ImGui windows and widgets.
// Clients are responsible for rendering the View. This should be called on every frame,
// regardless of whether the Renderer wants to skip or not.
void render(float timeStepInSeconds, Callback imguiCommands);
// Low-level alternative to render() that consumes an ImGui command list and translates it into
// various Filament calls. This includes updating the vertex buffer, setting up material
// instances, and rebuilding the Renderable component that encompasses the entire UI. Since this
// makes Filament calls, it must be called from the main thread.
void processImGuiCommands(ImDrawData* commands, const ImGuiIO& io);
// Helper method called after resolving fontPath; public so fonts can be added by caller.
void createAtlasTexture(filament::Engine* engine);
// Returns the client-owned view, useful for drawing 2D overlays.
filament::View* getView() const { return mView; }
private:
void createBuffers(int numRequiredBuffers);
void populateVertexData(size_t bufferIndex, size_t vbSizeInBytes, void* vbData,
size_t ibSizeInBytes, void* ibData);
void createVertexBuffer(size_t bufferIndex, size_t capacity);
void createIndexBuffer(size_t bufferIndex, size_t capacity);
void syncThreads();
filament::Engine* mEngine;
filament::View* mView; // The view is owned by the client.
filament::Scene* mScene;
filament::Material* mMaterial = nullptr;
filament::Camera* mCamera = nullptr;
std::vector<filament::VertexBuffer*> mVertexBuffers;
std::vector<filament::IndexBuffer*> mIndexBuffers;
std::vector<filament::MaterialInstance*> mMaterialInstances;
utils::Entity mRenderable;
utils::Entity mCameraEntity;
filament::Texture* mTexture = nullptr;
bool mHasSynced = false;
ImGuiContext* mImGuiContext;
filament::TextureSampler mSampler;
bool mFlipVertical = false;
};
} // namespace filagui
#endif /* FILAGUI_IMGUIHELPER_H_ */

View File

@@ -0,0 +1,30 @@
/*
* 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 FILAGUI_IMGUIMATH_H_
#define FILAGUI_IMGUIMATH_H_
#include <imgui.h>
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) {
return { lhs.x+rhs.x, lhs.y+rhs.y };
}
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) {
return { lhs.x-rhs.x, lhs.y-rhs.y };
}
#endif /* FILAGUI_IMGUIMATH_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,240 @@
/*
* 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_BOX_H
#define TNT_FILAMENT_BOX_H
#include <utils/compiler.h>
#include <limits>
#include <math/mat4.h>
#include <math/vec3.h>
namespace filament {
/**
* An axis aligned 3D box represented by its center and half-extent.
*/
class UTILS_PUBLIC Box {
public:
/** Center of the 3D box */
math::float3 center = {};
/** Half extent from the center on all 3 axis */
math::float3 halfExtent = {};
/**
* Whether the box is empty, i.e.: it's volume is null.
* @return true if the volume of the box is null
*/
constexpr bool isEmpty() const noexcept {
return length2(halfExtent) == 0;
}
/**
* Computes the lowest coordinates corner of the box.
* @return center - halfExtent
*/
constexpr math::float3 getMin() const noexcept {
return center - halfExtent;
}
/**
* Computes the largest coordinates corner of the box.
* @return center + halfExtent
*/
constexpr math::float3 getMax() const noexcept {
return center + halfExtent;
}
/**
* Initializes the 3D box from its min / max coordinates on each axis
* @param min lowest coordinates corner of the box
* @param max largest coordinates corner of the box
* @return This bounding box
*/
Box& set(const math::float3& min, const math::float3& max) noexcept {
// float3 ctor needed for visual studio
center = (max + min) * math::float3(0.5f);
halfExtent = (max - min) * math::float3(0.5f);
return *this;
}
/**
* Computes the bounding box of the union of two boxes
* @param box The box to be combined with
* @return The bounding box of the union of *this and box
*/
Box& unionSelf(const Box& box) noexcept {
set(min(getMin(), box.getMin()), max(getMax(), box.getMax()));
return *this;
}
/**
* Translates the box *to* a given center position
* @param tr position to translate the box to
* @return A box centered in \p tr with the same extent than *this
*/
constexpr Box translateTo(const math::float3& tr) const noexcept {
return Box{ tr, halfExtent };
}
/**
* Computes the smallest bounding sphere of the box.
* @return The smallest sphere defined by its center (.xyz) and radius (.w) that contains *this
*/
math::float4 getBoundingSphere() const noexcept {
return { center, length(halfExtent) };
}
/**
* Transform a Box by a linear transform and a translation.
*
* @param m a 3x3 matrix, the linear transform
* @param t a float3, the translation
* @param box the box to transform
* @return the bounding box of the transformed box
*/
static Box transform(const math::mat3f& m, math::float3 const& t, const Box& box) noexcept {
return { m * box.center + t, abs(m) * box.halfExtent };
}
/**
* @deprecated Use transform() instead
* @see transform()
*/
friend Box rigidTransform(Box const& box, const math::mat4f& m) noexcept {
return transform(m.upperLeft(), m[3].xyz, box);
}
};
/**
* An axis aligned box represented by its min and max coordinates
*/
struct UTILS_PUBLIC Aabb {
/** min coordinates */
math::float3 min = std::numeric_limits<float>::max();
/** max coordinates */
math::float3 max = std::numeric_limits<float>::lowest();
/**
* Computes the center of the box.
* @return (max + min)/2
*/
math::float3 center() const noexcept {
// float3 ctor needed for visual studio
return (max + min) * math::float3(0.5f);
}
/**
* Computes the half-extent of the box.
* @return (max - min)/2
*/
math::float3 extent() const noexcept {
// float3 ctor needed for visual studio
return (max - min) * math::float3(0.5f);
}
/**
* Whether the box is empty, i.e.: it's volume is null or negative.
* @return true if min >= max, i.e: the volume of the box is null or negative
*/
bool isEmpty() const noexcept {
return any(greaterThanEqual(min, max));
}
struct Corners {
using value_type = math::float3;
value_type const* begin() const { return vertices; }
value_type const* end() const { return vertices + 8; }
value_type * begin() { return vertices; }
value_type * end() { return vertices + 8; }
value_type const* data() const { return vertices; }
value_type * data() { return vertices; }
size_t size() const { return 8; }
value_type vertices[8];
};
/**
* Returns the 8 corner vertices of the AABB.
*/
Corners getCorners() const {
return Aabb::Corners{ .vertices = {
{ min.x, min.y, min.z },
{ max.x, min.y, min.z },
{ min.x, max.y, min.z },
{ max.x, max.y, min.z },
{ min.x, min.y, max.z },
{ max.x, min.y, max.z },
{ min.x, max.y, max.z },
{ max.x, max.y, max.z },
}};
}
/**
* Returns whether the box contains a given point.
*
* @param p the point to test
* @return the maximum signed distance to the box. Negative if p is in the box
*/
float contains(math::float3 p) const noexcept {
float d = min.x - p.x;
d = std::max(d, min.y - p.y);
d = std::max(d, min.z - p.z);
d = std::max(d, p.x - max.x);
d = std::max(d, p.y - max.y);
d = std::max(d, p.z - max.z);
return d;
}
/**
* Applies an affine transformation to the AABB.
*
* @param m the 3x3 transformation to apply
* @param t the translation
* @return the transformed box
*/
static Aabb transform(const math::mat3f& m, math::float3 const& t, const Aabb& box) noexcept {
// Fast AABB transformation per Jim Arvo in Graphics Gems (1990).
Aabb result{ t, t };
for (size_t col = 0; col < 3; ++col) {
for (size_t row = 0; row < 3; ++row) {
const float a = m[col][row] * box.min[col];
const float b = m[col][row] * box.max[col];
result.min[row] += a < b ? a : b;
result.max[row] += a < b ? b : a;
}
}
return result;
}
/**
* @deprecated Use transform() instead
* @see transform()
*/
Aabb transform(const math::mat4f& m) const noexcept {
return transform(m.upperLeft(), m[3].xyz, *this);
}
};
} // namespace filament
#endif // TNT_FILAMENT_BOX_H

View File

@@ -0,0 +1,117 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BUFFEROBJECT_H
#define TNT_FILAMENT_BUFFEROBJECT_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/BufferDescriptor.h>
#include <utils/compiler.h>
namespace filament {
class FBufferObject;
class Engine;
/**
* A generic GPU buffer containing data.
*
* Usage of this BufferObject is optional. For simple use cases it is not necessary. It is useful
* only when you need to share data between multiple VertexBuffer instances. It also allows you to
* efficiently swap-out the buffers in VertexBuffer.
*
* NOTE: For now this is only used for vertex data, but in the future we may use it for other things
* (e.g. compute).
*
* @see VertexBuffer
*/
class UTILS_PUBLIC BufferObject : public FilamentAPI {
struct BuilderDetails;
public:
using BufferDescriptor = backend::BufferDescriptor;
using BindingType = backend::BufferObjectBinding;
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Size of the buffer in bytes.
* @param byteCount Maximum number of bytes the BufferObject can hold.
* @return A reference to this Builder for chaining calls.
*/
Builder& size(uint32_t byteCount) noexcept;
/**
* The binding type for this buffer object. (defaults to VERTEX)
* @param BindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX.
* @return A reference to this Builder for chaining calls.
*/
Builder& bindingType(BindingType bindingType) noexcept;
/**
* Creates the BufferObject and returns a pointer to it. After creation, the buffer
* object is uninitialized. Use BufferObject::setBuffer() to initialize it.
*
* @param engine Reference to the filament::Engine to associate this BufferObject with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*
* @see IndexBuffer::setBuffer
*/
BufferObject* build(Engine& engine);
private:
friend class FBufferObject;
};
/**
* Asynchronously copy-initializes a region of this BufferObject from the data provided.
*
* @param engine Reference to the filament::Engine associated with this BufferObject.
* @param buffer A BufferDescriptor representing the data used to initialize the BufferObject.
* @param byteOffset Offset in bytes into the BufferObject
*/
void setBuffer(Engine& engine, BufferDescriptor&& buffer, uint32_t byteOffset = 0);
/**
* Returns the size of this BufferObject in elements.
* @return The maximum capacity of the BufferObject.
*/
size_t getByteCount() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BUFFEROBJECT_H

View File

@@ -0,0 +1,526 @@
/*
* 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_CAMERA_H
#define TNT_FILAMENT_CAMERA_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <math/vec2.h>
#include <math/vec4.h>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
/**
* Camera represents the eye through which the scene is viewed.
*
* A Camera has a position and orientation and controls the projection and exposure parameters.
*
* Creation and destruction
* ========================
*
* In Filament, Camera is a component that must be associated with an entity. To do so,
* use Engine::createCamera(Entity). A Camera component is destroyed using
* Engine::destroyCameraComponent(Entity).
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
*
* utils::Entity myCameraEntity = utils::EntityManager::get().create();
* filament::Camera* myCamera = engine->createCamera(myCameraEntity);
* myCamera->setProjection(45, 16.0/9.0, 0.1, 1.0);
* myCamera->lookAt({0, 1.60, 1}, {0, 0, 0});
* engine->destroyCameraComponent(myCamera);
* ~~~~~~~~~~~
*
*
* Coordinate system
* =================
*
* The camera coordinate system defines the *view space*. The camera points towards its -z axis
* and is oriented such that its top side is in the direction of +y, and its right side in the
* direction of +x.
*
* @note
* Since the *near* and *far* planes are defined by the distance from the camera,
* their respective coordinates are -\p distance(near) and -\p distance(far).
*
* Clipping planes
* ===============
*
* The camera defines six *clipping planes* which together create a *clipping volume*. The
* geometry outside this volume is clipped.
*
* The clipping volume can either be a box or a frustum depending on which projection is used,
* respectively Projection.ORTHO or Projection.PERSPECTIVE. The six planes are specified either
* directly or indirectly using setProjection().
*
* The six planes are:
* - left
* - right
* - bottom
* - top
* - near
* - far
*
* @note
* To increase the depth-buffer precision, the *far* clipping plane is always assumed to be at
* infinity for rendering. That is, it is not used to clip geometry during rendering.
* However, it is used during the culling phase (objects entirely behind the *far*
* plane are culled).
*
*
* Choosing the *near* plane distance
* ==================================
*
* The *near* plane distance greatly affects the depth-buffer resolution.
*
* Example: Precision at 1m, 10m, 100m and 1Km for various near distances assuming a 32-bit float
* depth-buffer:
*
* near (m) | 1 m | 10 m | 100 m | 1 Km
* -----------:|:------:|:-------:|:--------:|:--------:
* 0.001 | 7.2e-5 | 0.0043 | 0.4624 | 48.58
* 0.01 | 6.9e-6 | 0.0001 | 0.0430 | 4.62
* 0.1 | 3.6e-7 | 7.0e-5 | 0.0072 | 0.43
* 1.0 | 0 | 3.8e-6 | 0.0007 | 0.07
*
* As can be seen in the table above, the depth-buffer precision drops rapidly with the
* distance to the camera.
*
* Make sure to pick the highest *near* plane distance possible.
*
* On Vulkan and Metal platforms (or OpenGL platforms supporting either EXT_clip_control or
* ARB_clip_control extensions), the depth-buffer precision is much less dependent on the *near*
* plane value:
*
* near (m) | 1 m | 10 m | 100 m | 1 Km
* -----------:|:------:|:-------:|:--------:|:--------:
* 0.001 | 1.2e-7 | 9.5e-7 | 7.6e-6 | 6.1e-5
* 0.01 | 1.2e-7 | 9.5e-7 | 7.6e-6 | 6.1e-5
* 0.1 | 5.9e-8 | 9.5e-7 | 1.5e-5 | 1.2e-4
* 1.0 | 0 | 9.5e-7 | 7.6e-6 | 1.8e-4
*
*
* Choosing the *far* plane distance
* =================================
*
* The far plane distance is always set internally to infinity for rendering, however it is used for
* culling and shadowing calculations. It is important to keep a reasonable ratio between
* the near and far plane distances. Typically a ratio in the range 1:100 to 1:100000 is
* commanded. Larger values may causes rendering artifacts or trigger assertions in debug builds.
*
*
* Exposure
* ========
*
* The Camera is also used to set the scene's exposure, just like with a real camera. The lights
* intensity and the Camera exposure interact to produce the final scene's brightness.
*
*
*
* \see Frustum, View
*/
class UTILS_PUBLIC Camera : public FilamentAPI {
public:
//! Denotes the projection type used by this camera. \see setProjection
enum class Projection : int {
PERSPECTIVE, //!< perspective projection, objects get smaller as they are farther
ORTHO //!< orthonormal projection, preserves distances
};
//! Denotes a field-of-view direction. \see setProjection
enum class Fov : int {
VERTICAL, //!< the field-of-view angle is defined on the vertical axis
HORIZONTAL //!< the field-of-view angle is defined on the horizontal axis
};
/** Sets the projection matrix from a frustum defined by six planes.
*
* @param projection type of #Projection to use.
*
* @param left distance in world units from the camera to the left plane,
* at the near plane.
* Precondition: \p left != \p right.
*
* @param right distance in world units from the camera to the right plane,
* at the near plane.
* Precondition: \p left != \p right.
*
* @param bottom distance in world units from the camera to the bottom plane,
* at the near plane.
* Precondition: \p bottom != \p top.
*
* @param top distance in world units from the camera to the top plane,
* at the near plane.
* Precondition: \p left != \p right.
*
* @param near distance in world units from the camera to the near plane. The near plane's
* position in view space is z = -\p near.
* Precondition: \p near > 0 for PROJECTION::PERSPECTIVE or
* \p near != far for PROJECTION::ORTHO
*
* @param far distance in world units from the camera to the far plane. The far plane's
* position in view space is z = -\p far.
* Precondition: \p far > near for PROJECTION::PERSPECTIVE or
* \p far != near for PROJECTION::ORTHO
*
* @see Projection, Frustum
*/
void setProjection(Projection projection,
double left, double right,
double bottom, double top,
double near, double far);
/** Sets the projection matrix from the field-of-view.
*
* @param fovInDegrees full field-of-view in degrees. 0 < \p fov < 180.
* @param aspect aspect ratio \f$ \frac{width}{height} \f$. \p aspect > 0.
* @param near distance in world units from the camera to the near plane. \p near > 0.
* @param far distance in world units from the camera to the far plane. \p far > \p near.
* @param direction direction of the \p fovInDegrees parameter.
*
* @see Fov.
*/
void setProjection(double fovInDegrees, double aspect, double near, double far,
Fov direction = Fov::VERTICAL);
/** Sets the projection matrix from the focal length.
*
* @param focalLengthInMillimeters lens's focal length in millimeters. \p focalLength > 0.
* @param aspect aspect ratio \f$ \frac{width}{height} \f$. \p aspect > 0.
* @param near distance in world units from the camera to the near plane. \p near > 0.
* @param far distance in world units from the camera to the far plane. \p far > \p near.
*/
void setLensProjection(double focalLengthInMillimeters,
double aspect, double near, double far);
/** Sets a custom projection matrix.
*
* The projection matrix must be of one of the following form:
* a 0 tx 0 a 0 0 tx
* 0 b ty 0 0 b 0 ty
* 0 0 tz c 0 0 c tz
* 0 0 -1 0 0 0 0 1
*
* The projection matrix must define an NDC system that must match the OpenGL convention,
* that is all 3 axis are mapped to [-1, 1].
*
* @param projection custom projection matrix used for rendering and culling
* @param near distance in world units from the camera to the near plane. \p near > 0.
* @param far distance in world units from the camera to the far plane. \p far > \p near.
*/
void setCustomProjection(math::mat4 const& projection, double near, double far) noexcept;
/** Sets the projection matrix.
*
* The projection matrices must be of one of the following form:
* a 0 tx 0 a 0 0 tx
* 0 b ty 0 0 b 0 ty
* 0 0 tz c 0 0 c tz
* 0 0 -1 0 0 0 0 1
*
* The projection matrices must define an NDC system that must match the OpenGL convention,
* that is all 3 axis are mapped to [-1, 1].
*
* @param projection custom projection matrix used for rendering
* @param projectionForCulling custom projection matrix used for culling
* @param near distance in world units from the camera to the near plane. \p near > 0.
* @param far distance in world units from the camera to the far plane. \p far > \p near.
*/
void setCustomProjection(math::mat4 const& projection, math::mat4 const& projectionForCulling,
double near, double far) noexcept;
/** Sets an additional matrix that scales the projection matrix.
*
* This is useful to adjust the aspect ratio of the camera independent from its projection.
* First, pass an aspect of 1.0 to setProjection. Then set the scaling with the desired aspect
* ratio:
*
* const double aspect = width / height;
*
* // with Fov::HORIZONTAL passed to setProjection:
* camera->setScaling(double4 {1.0, aspect});
*
* // with Fov::VERTICAL passed to setProjection:
* camera->setScaling(double4 {1.0 / aspect, 1.0});
*
*
* By default, this is an identity matrix.
*
* @param scaling diagonal of the 2x2 scaling matrix to be applied after the projection matrix.
*
* @see setProjection, setLensProjection, setCustomProjection
*/
void setScaling(math::double2 scaling) noexcept;
/**
* Sets an additional matrix that shifts the projection matrix.
* By default, this is an identity matrix.
*
* @param shift x and y translation added to the projection matrix, specified in NDC
* coordinates, that is, if the translation must be specified in pixels,
* shift must be scaled by 1.0 / { viewport.width, viewport.height }.
*
* @see setProjection, setLensProjection, setCustomProjection
*/
void setShift(math::double2 shift) noexcept;
/** Returns the scaling amount used to scale the projection matrix.
*
* @return the diagonal of the scaling matrix applied after the projection matrix.
*
* @see setScaling
*/
math::double4 getScaling() const noexcept;
/** Returns the shift amount used to translate the projection matrix.
*
* @return the 2D translation x and y offsets applied after the projection matrix.
*
* @see setShift
*/
math::double2 getShift() const noexcept;
/** Returns the projection matrix used for rendering.
*
* The projection matrix used for rendering always has its far plane set to infinity. This
* is why it may differ from the matrix set through setProjection() or setLensProjection().
*
* @return The projection matrix used for rendering
*
* @see setProjection, setLensProjection, setCustomProjection, getCullingProjectionMatrix
*/
math::mat4 getProjectionMatrix() const noexcept;
/** Returns the projection matrix used for culling (far plane is finite).
*
* @return The projection matrix set by setProjection or setLensProjection.
*
* @see setProjection, setLensProjection, getProjectionMatrix
*/
math::mat4 getCullingProjectionMatrix() const noexcept;
//! Returns the frustum's near plane
double getNear() const noexcept;
//! Returns the frustum's far plane used for culling
double getCullingFar() const noexcept;
/** Sets the camera's model matrix.
*
* Helper method to set the camera's entity transform component.
* It has the same effect as calling:
*
* ~~~~~~~~~~~{.cpp}
* engine.getTransformManager().setTransform(
* engine.getTransformManager().getInstance(camera->getEntity()), model);
* ~~~~~~~~~~~
*
* @param model The camera position and orientation provided as a rigid transform matrix.
*
* @note The Camera "looks" towards its -z axis
*
* @warning \p model must be a rigid transform
*/
void setModelMatrix(const math::mat4& model) noexcept;
void setModelMatrix(const math::mat4f& model) noexcept; //!< @overload
/** Sets the camera's model matrix
*
* @param eye The position of the camera in world space.
* @param center The point in world space the camera is looking at.
* @param up A unit vector denoting the camera's "up" direction.
*/
void lookAt(math::double3 const& eye,
math::double3 const& center,
math::double3 const& up = math::double3{0, 1, 0}) noexcept;
/** Returns the camera's model matrix
*
* Helper method to return the camera's entity transform component.
* It has the same effect as calling:
*
* ~~~~~~~~~~~{.cpp}
* engine.getTransformManager().getWorldTransform(
* engine.getTransformManager().getInstance(camera->getEntity()));
* ~~~~~~~~~~~
*
* @return The camera's pose in world space as a rigid transform. Parent transforms, if any,
* are taken into account.
*/
math::mat4 getModelMatrix() const noexcept;
//! Returns the camera's view matrix (inverse of the model matrix)
math::mat4 getViewMatrix() const noexcept;
//! Returns the camera's position in world space
math::double3 getPosition() const noexcept;
//! Returns the camera's normalized left vector
math::float3 getLeftVector() const noexcept;
//! Returns the camera's normalized up vector
math::float3 getUpVector() const noexcept;
//! Returns the camera's forward vector
math::float3 getForwardVector() const noexcept;
//! Returns the camera's field of view in degrees
float getFieldOfViewInDegrees(Fov direction) const noexcept;
//! Returns the camera's culling Frustum in world space
class Frustum getFrustum() const noexcept;
//! Returns the entity representing this camera
utils::Entity getEntity() const noexcept;
/** Sets this camera's exposure (default is f/16, 1/125s, 100 ISO)
*
* The exposure ultimately controls the scene's brightness, just like with a real camera.
* The default values provide adequate exposure for a camera placed outdoors on a sunny day
* with the sun at the zenith.
*
* @param aperture Aperture in f-stops, clamped between 0.5 and 64.
* A lower \p aperture value *increases* the exposure, leading to
* a brighter scene. Realistic values are between 0.95 and 32.
*
* @param shutterSpeed Shutter speed in seconds, clamped between 1/25,000 and 60.
* A lower shutter speed increases the exposure. Realistic values are
* between 1/8000 and 30.
*
* @param sensitivity Sensitivity in ISO, clamped between 10 and 204,800.
* A higher \p sensitivity increases the exposure. Realistic values are
* between 50 and 25600.
*
* @note
* With the default parameters, the scene must contain at least one Light of intensity
* similar to the sun (e.g.: a 100,000 lux directional light).
*
* @see LightManager, Exposure
*/
void setExposure(float aperture, float shutterSpeed, float sensitivity) noexcept;
/** Sets this camera's exposure directly. Calling this method will set the aperture
* to 1.0, the shutter speed to 1.2 and the sensitivity will be computed to match
* the requested exposure (for a desired exposure of 1.0, the sensitivity will be
* set to 100 ISO).
*
* This method is useful when trying to match the lighting of other engines or tools.
* Many engines/tools use unit-less light intensities, which can be matched by setting
* the exposure manually. This can be typically achieved by setting the exposure to
* 1.0.
*/
void setExposure(float exposure) noexcept {
setExposure(1.0f, 1.2f, 100.0f * (1.0f / exposure));
}
//! returns this camera's aperture in f-stops
float getAperture() const noexcept;
//! returns this camera's shutter speed in seconds
float getShutterSpeed() const noexcept;
//! returns this camera's sensitivity in ISO
float getSensitivity() const noexcept;
//! returns the focal length in meters [m] for a 35mm camera
double getFocalLength() const noexcept;
/**
* Sets the camera focus distance. This is used by the Depth-of-field PostProcessing effect.
* @param distance Distance from the camera to the plane of focus in world units.
* Must be positive and larger than the near clipping plane.
*/
void setFocusDistance(float distance) noexcept;
//! Returns the focus distance in world units
float getFocusDistance() const noexcept;
/**
* Returns the inverse of a projection matrix.
*
* \param p the projection matrix to inverse
* \returns the inverse of the projection matrix \p p
*
* \warning the projection matrix to invert must have one of the form below:
* - perspective projection
*
* \f$
* \left(
* \begin{array}{cccc}
* a & 0 & tx & 0 \\
* 0 & b & ty & 0 \\
* 0 & 0 & tz & c \\
* 0 & 0 & -1 & 0 \\
* \end{array}
* \right)
* \f$
*
* - orthographic projection
*
* \f$
* \left(
* \begin{array}{cccc}
* a & 0 & 0 & tx \\
* 0 & b & 0 & ty \\
* 0 & 0 & c & tz \\
* 0 & 0 & 0 & 1 \\
* \end{array}
* \right)
* \f$
*/
static math::mat4 inverseProjection(const math::mat4& p) noexcept;
/**
* Returns the inverse of a projection matrix.
* @see inverseProjection(const math::mat4&)
*/
static math::mat4f inverseProjection(const math::mat4f& p) noexcept;
/**
* Helper to compute the effective focal length taking into account the focus distance
*
* @param focalLength focal length in any unit (e.g. [m] or [mm])
* @param focusDistance focus distance in same unit as focalLength
* @return the effective focal length in same unit as focalLength
*/
static double computeEffectiveFocalLength(double focalLength, double focusDistance) noexcept;
/**
* Helper to compute the effective field-of-view taking into account the focus distance
*
* @param fovInDegrees full field of view in degrees
* @param focusDistance focus distance in meters [m]
* @return effective full field of view in degrees
*/
static double computeEffectiveFov(double fovInDegrees, double focusDistance) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_CAMERA_H

View File

@@ -0,0 +1,214 @@
/*
* 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_COLOR_H
#define TNT_FILAMENT_COLOR_H
#include <utils/compiler.h>
#include <math/vec3.h>
#include <math/vec4.h>
namespace filament {
//! RGB color in linear space
using LinearColor = math::float3;
//! RGB color in sRGB space
using sRGBColor = math::float3;
//! RGBA color in linear space, with alpha
using LinearColorA = math::float4;
//! RGBA color in sRGB space, with alpha
using sRGBColorA = math::float4;
//! types of RGB colors
enum class RgbType : uint8_t {
sRGB, //!< the color is defined in Rec.709-sRGB-D65 (sRGB) space
LINEAR, //!< the color is defined in Rec.709-Linear-D65 ("linear sRGB") space
};
//! types of RGBA colors
enum class RgbaType : uint8_t {
/**
* the color is defined in Rec.709-sRGB-D65 (sRGB) space and the RGB values
* have not been pre-multiplied by the alpha (for instance, a 50%
* transparent red is <1,0,0,0.5>)
*/
sRGB,
/**
* the color is defined in Rec.709-Linear-D65 ("linear sRGB") space and the
* RGB values have not been pre-multiplied by the alpha (for instance, a 50%
* transparent red is <1,0,0,0.5>)
*/
LINEAR,
/**
* the color is defined in Rec.709-sRGB-D65 (sRGB) space and the RGB values
* have been pre-multiplied by the alpha (for instance, a 50%
* transparent red is <0.5,0,0,0.5>)
*/
PREMULTIPLIED_sRGB,
/**
* the color is defined in Rec.709-Linear-D65 ("linear sRGB") space and the
* RGB values have been pre-multiplied by the alpha (for instance, a 50%
* transparent red is <0.5,0,0,0.5>)
*/
PREMULTIPLIED_LINEAR
};
//! type of color conversion to use when converting to/from sRGB and linear spaces
enum ColorConversion {
ACCURATE, //!< accurate conversion using the sRGB standard
FAST //!< fast conversion using a simple gamma 2.2 curve
};
/**
* Utilities to manipulate and convert colors
*/
class UTILS_PUBLIC Color {
public:
//! converts an RGB color to linear space, the conversion depends on the specified type
static LinearColor toLinear(RgbType type, math::float3 color);
//! converts an RGBA color to linear space, the conversion depends on the specified type
static LinearColorA toLinear(RgbaType type, math::float4 color);
//! converts an RGB color in sRGB space to an RGB color in linear space
template<ColorConversion = ACCURATE>
static LinearColor toLinear(sRGBColor const& color);
/**
* Converts an RGB color in Rec.709-Linear-D65 ("linear sRGB") space to an
* RGB color in Rec.709-sRGB-D65 (sRGB) space.
*/
template<ColorConversion = ACCURATE>
static sRGBColor toSRGB(LinearColor const& color);
/**
* Converts an RGBA color in Rec.709-sRGB-D65 (sRGB) space to an RGBA color in
* Rec.709-Linear-D65 ("linear sRGB") space the alpha component is left unmodified.
*/
template<ColorConversion = ACCURATE>
static LinearColorA toLinear(sRGBColorA const& color);
/**
* Converts an RGBA color in Rec.709-Linear-D65 ("linear sRGB") space to
* an RGBA color in Rec.709-sRGB-D65 (sRGB) space the alpha component is
* left unmodified.
*/
template<ColorConversion = ACCURATE>
static sRGBColorA toSRGB(LinearColorA const& color);
/**
* Converts a correlated color temperature to a linear RGB color in sRGB
* space the temperature must be expressed in kelvin and must be in the
* range 1,000K to 15,000K.
*/
static LinearColor cct(float K);
/**
* Converts a CIE standard illuminant series D to a linear RGB color in
* sRGB space the temperature must be expressed in kelvin and must be in
* the range 4,000K to 25,000K
*/
static LinearColor illuminantD(float K);
/**
* Computes the Beer-Lambert absorption coefficients from the specified
* transmittance color and distance. The computed absorption will guarantee
* the white light will become the specified color at the specified distance.
* The output of this function can be used as the absorption parameter of
* materials that use refraction.
*
* @param color the desired linear RGB color in sRGB space
* @param distance the distance at which white light should become the specified color
*
* @return absorption coefficients for the Beer-Lambert law
*/
static math::float3 absorptionAtDistance(LinearColor const& color, float distance);
private:
static math::float3 sRGBToLinear(math::float3 color) noexcept;
static math::float3 linearToSRGB(math::float3 color) noexcept;
};
// Use the default implementation from the header
template<>
inline LinearColor Color::toLinear<FAST>(sRGBColor const& color) {
return pow(color, 2.2f);
}
template<>
inline LinearColorA Color::toLinear<FAST>(sRGBColorA const& color) {
return LinearColorA{pow(color.rgb, 2.2f), color.a};
}
template<>
inline LinearColor Color::toLinear<ACCURATE>(sRGBColor const& color) {
return sRGBToLinear(color);
}
template<>
inline LinearColorA Color::toLinear<ACCURATE>(sRGBColorA const& color) {
return LinearColorA{sRGBToLinear(color.rgb), color.a};
}
// Use the default implementation from the header
template<>
inline sRGBColor Color::toSRGB<FAST>(LinearColor const& color) {
return pow(color, 1.0f / 2.2f);
}
template<>
inline sRGBColorA Color::toSRGB<FAST>(LinearColorA const& color) {
return sRGBColorA{pow(color.rgb, 1.0f / 2.2f), color.a};
}
template<>
inline sRGBColor Color::toSRGB<ACCURATE>(LinearColor const& color) {
return linearToSRGB(color);
}
template<>
inline sRGBColorA Color::toSRGB<ACCURATE>(LinearColorA const& color) {
return sRGBColorA{linearToSRGB(color.rgb), color.a};
}
inline LinearColor Color::toLinear(RgbType type, math::float3 color) {
return (type == RgbType::LINEAR) ? color : Color::toLinear<ACCURATE>(color);
}
// converts an RGBA color to linear space
// the conversion depends on the specified type
inline LinearColorA Color::toLinear(RgbaType type, math::float4 color) {
switch (type) {
case RgbaType::sRGB:
return Color::toLinear<ACCURATE>(color) * math::float4{color.a, color.a, color.a, 1.0f};
case RgbaType::LINEAR:
return color * math::float4{color.a, color.a, color.a, 1.0f};
case RgbaType::PREMULTIPLIED_sRGB:
return Color::toLinear<ACCURATE>(color);
case RgbaType::PREMULTIPLIED_LINEAR:
return color;
}
}
} // namespace filament
#endif // TNT_FILAMENT_COLOR_H

View File

@@ -0,0 +1,485 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_COLORGRADING_H
#define TNT_FILAMENT_COLORGRADING_H
#include <filament/FilamentAPI.h>
#include <filament/ToneMapper.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
namespace filament {
class Engine;
class FColorGrading;
namespace color {
class ColorSpace;
}
/**
* ColorGrading is used to transform (either to modify or correct) the colors of the HDR buffer
* rendered by Filament. Color grading transforms are applied after lighting, and after any lens
* effects (bloom for instance), and include tone mapping.
*
* Creation, usage and destruction
* ===============================
*
* A ColorGrading object is created using the ColorGrading::Builder and destroyed by calling
* Engine::destroy(const ColorGrading*). A ColorGrading object is meant to be set on a View.
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
*
* filament::ColorGrading* colorGrading = filament::ColorGrading::Builder()
* .toneMapping(filament::ColorGrading::ToneMapping::ACES)
* .build(*engine);
*
* myView->setColorGrading(colorGrading);
*
* engine->destroy(colorGrading);
* ~~~~~~~~~~~
*
* Performance
* ===========
*
* Creating a new ColorGrading object may be more expensive than other Filament objects as a
* 3D LUT may need to be generated. The generation of a 3D LUT, if necessary, may happen on
* the CPU.
*
* Ordering
* ========
*
* The various transforms held by ColorGrading are applied in the following order:
* - Exposure
* - Night adaptation
* - White balance
* - Channel mixer
* - Shadows/mid-tones/highlights
* - Slope/offset/power (CDL)
* - Contrast
* - Vibrance
* - Saturation
* - Curves
* - Tone mapping
* - Luminance scaling
* - Gamut mapping
*
* Defaults
* ========
*
* Here are the default color grading options:
* - Exposure: 0.0
* - Night adaptation: 0.0
* - White balance: temperature 0, and tint 0
* - Channel mixer: red {1,0,0}, green {0,1,0}, blue {0,0,1}
* - Shadows/mid-tones/highlights: shadows {1,1,1,0}, mid-tones {1,1,1,0}, highlights {1,1,1,0},
* ranges {0,0.333,0.550,1}
* - Slope/offset/power: slope 1.0, offset 0.0, and power 1.0
* - Contrast: 1.0
* - Vibrance: 1.0
* - Saturation: 1.0
* - Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1}
* - Tone mapping: ACESLegacyToneMapper
* - Luminance scaling: false
* - Gamut mapping: false
* - Output color space: Rec709-sRGB-D65
*
* @see View
*/
class UTILS_PUBLIC ColorGrading : public FilamentAPI {
struct BuilderDetails;
public:
enum class QualityLevel : uint8_t {
LOW,
MEDIUM,
HIGH,
ULTRA
};
enum class LutFormat : uint8_t {
INTEGER, //!< 10 bits per component
FLOAT, //!< 16 bits per component (10 bits mantissa precision)
};
/**
* List of available tone-mapping operators.
*
* @deprecated Use Builder::toneMapper(ToneMapper*) instead
*/
enum class UTILS_DEPRECATED ToneMapping : uint8_t {
LINEAR = 0, //!< Linear tone mapping (i.e. no tone mapping)
ACES_LEGACY = 1, //!< ACES tone mapping, with a brightness modifier to match Filament's legacy tone mapper
ACES = 2, //!< ACES tone mapping
FILMIC = 3, //!< Filmic tone mapping, modelled after ACES but applied in sRGB space
DISPLAY_RANGE = 4, //!< Tone mapping used to validate/debug scene exposure
};
//! Use Builder to construct a ColorGrading object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Sets the quality level of the color grading. When color grading is implemented using
* a 3D LUT, the quality level may impact the resolution and bit depth of the backing
* 3D texture. For instance, a low quality level will use a 16x16x16 10 bit LUT, a medium
* quality level will use a 32x32x32 10 bit LUT, a high quality will use a 32x32x32 16 bit
* LUT, and a ultra quality will use a 64x64x64 16 bit LUT.
* This overrides the values set by format() and dimensions().
*
* The default quality is medium.
*
* @param qualityLevel The desired quality of the color grading process
*
* @return This Builder, for chaining calls
*/
Builder& quality(QualityLevel qualityLevel) noexcept;
/**
* When color grading is implemented using a 3D LUT, this sets the texture format of
* of the LUT. This overrides the value set by quality().
*
* The default is INTEGER
*
* @param format The desired format of the 3D LUT.
*
* @return This Builder, for chaining calls
*/
Builder& format(LutFormat format) noexcept;
/**
* When color grading is implemented using a 3D LUT, this sets the dimension of the LUT.
* This overrides the value set by quality().
*
* The default is 32
*
* @param dim The desired dimension of the LUT. Between 16 and 64.
*
* @return This Builder, for chaining calls
*/
Builder& dimensions(uint8_t dim) noexcept;
/**
* Selects the tone mapping operator to apply to the HDR color buffer as the last
* operation of the color grading post-processing step.
*
* The default tone mapping operator is ACESLegacyToneMapper.
*
* The specified tone mapper must have a lifecycle that exceeds the lifetime of
* this builder. Since the build(Engine&) method is synchronous, it is safe to
* delete the tone mapper object after that finishes executing.
*
* @param toneMapper The tone mapping operator to apply to the HDR color buffer
*
* @return This Builder, for chaining calls
*/
Builder& toneMapper(const ToneMapper* toneMapper) noexcept;
/**
* Selects the tone mapping operator to apply to the HDR color buffer as the last
* operation of the color grading post-processing step.
*
* The default tone mapping operator is ACES_LEGACY.
*
* @param toneMapping The tone mapping operator to apply to the HDR color buffer
*
* @return This Builder, for chaining calls
*
* @deprecated Use toneMapper(ToneMapper*) instead
*/
UTILS_DEPRECATED
Builder& toneMapping(ToneMapping toneMapping) noexcept;
/**
* Enables or disables the luminance scaling component (LICH) from the exposure value
* invariant luminance system (EVILS). When this setting is enabled, pixels with high
* chromatic values will roll-off to white to offer a more natural rendering. This step
* also helps avoid undesirable hue skews caused by out of gamut colors clipped
* to the destination color gamut.
*
* When luminance scaling is enabled, tone mapping is performed on the luminance of each
* pixel instead of per-channel.
*
* @param luminanceScaling Enables or disables luminance scaling post-tone mapping
*
* @return This Builder, for chaining calls
*/
Builder& luminanceScaling(bool luminanceScaling) noexcept;
/**
* Enables or disables gamut mapping to the destination color space's gamut. When gamut
* mapping is turned off, out-of-gamut colors are clipped to the destination's gamut,
* which may produce hue skews (blue skewing to purple, green to yellow, etc.). When
* gamut mapping is enabled, out-of-gamut colors are brought back in gamut by trying to
* preserve the perceived chroma and lightness of the original values.
*
* @param gamutMapping Enables or disables gamut mapping
*
* @return This Builder, for chaining calls
*/
Builder& gamutMapping(bool gamutMapping) noexcept;
/**
* Adjusts the exposure of this image. The exposure is specified in stops:
* each stop brightens (positive values) or darkens (negative values) the image by
* a factor of 2. This means that an exposure of 3 will brighten the image 8 times
* more than an exposure of 0 (2^3 = 8 and 2^0 = 1). Contrary to the camera's exposure,
* this setting is applied after all post-processing (bloom, etc.) are applied.
*
* @param exposure Value in EV stops. Can be negative, 0, or positive.
*
* @return This Builder, for chaining calls
*/
Builder& exposure(float exposure) noexcept;
/**
* Controls the amount of night adaptation to replicate a more natural representation of
* low-light conditions as perceived by the human vision system. In low-light conditions,
* peak luminance sensitivity of the eye shifts toward the blue end of the color spectrum:
* darker tones appear brighter, reducing contrast, and colors are blue shifted (the darker
* the more intense the effect).
*
* @param adaptation Amount of adaptation, between 0 (no adaptation) and 1 (full adaptation).
*
* @return This Builder, for chaining calls
*/
Builder& nightAdaptation(float adaptation) noexcept;
/**
* Adjusts the while balance of the image. This can be used to remove color casts
* and correct the appearance of the white point in the scene, or to alter the
* overall chromaticity of the image for artistic reasons (to make the image appear
* cooler or warmer for instance).
*
* The while balance adjustment is defined with two values:
* - Temperature, to modify the color temperature. This value will modify the colors
* on a blue/yellow axis. Lower values apply a cool color temperature, and higher
* values apply a warm color temperature. The lowest value, -1.0f, is equivalent to
* a temperature of 50,000K. The highest value, 1.0f, is equivalent to a temperature
* of 2,000K.
* - Tint, to modify the colors on a green/magenta axis. The lowest value, -1.0f, will
* apply a strong green cast, and the highest value, 1.0f, will apply a strong magenta
* cast.
*
* Both values are expected to be in the range [-1.0..+1.0]. Values outside of that
* range will be clipped to that range.
*
* @param temperature Modification on the blue/yellow axis, as a value between -1.0 and +1.0.
* @param tint Modification on the green/magenta axis, as a value between -1.0 and +1.0.
*
* @return This Builder, for chaining calls
*/
Builder& whiteBalance(float temperature, float tint) noexcept;
/**
* The channel mixer adjustment modifies each output color channel using the specified
* mix of the source color channels.
*
* By default each output color channel is set to use 100% of the corresponding source
* channel and 0% of the other channels. For instance, the output red channel is set to
* {1.0, 0.0, 1.0} or 100% red, 0% green and 0% blue.
*
* Each output channel can add or subtract data from the source channel by using values
* in the range [-2.0..+2.0]. Values outside of that range will be clipped to that range.
*
* Using the channel mixer adjustment you can for instance create a monochrome output
* by setting all 3 output channels to the same mix. For instance: {0.4, 0.4, 0.2} for
* all 3 output channels(40% red, 40% green and 20% blue).
*
* More complex mixes can be used to create more complex effects. For instance, here is
* a mix that creates a sepia tone effect:
* - outRed = {0.255, 0.858, 0.087}
* - outGreen = {0.213, 0.715, 0.072}
* - outBlue = {0.170, 0.572, 0.058}
*
* @param outRed The mix of source RGB for the output red channel, between -2.0 and +2.0
* @param outGreen The mix of source RGB for the output green channel, between -2.0 and +2.0
* @param outBlue The mix of source RGB for the output blue channel, between -2.0 and +2.0
*
* @return This Builder, for chaining calls
*/
Builder& channelMixer(
math::float3 outRed, math::float3 outGreen, math::float3 outBlue) noexcept;
/**
* Adjusts the colors separately in 3 distinct tonal ranges or zones: shadows, mid-tones,
* and highlights.
*
* The tonal zones are by the ranges parameter: the x and y components define the beginning
* and end of the transition from shadows to mid-tones, and the z and w components define
* the beginning and end of the transition from mid-tones to highlights.
*
* A smooth transition is applied between the zones which means for instance that the
* correction color of the shadows range will partially apply to the mid-tones, and the
* other way around. This ensure smooth visual transitions in the final image.
*
* Each correction color is defined as a linear RGB color and a weight. The weight is a
* value (which may be positive or negative) that is added to the linear RGB color before
* mixing. This can be used to darken or brighten the selected tonal range.
*
* Shadows/mid-tones/highlights adjustment are performed linear space.
*
* @param shadows Linear RGB color (.rgb) and weight (.w) to apply to the shadows
* @param midtones Linear RGB color (.rgb) and weight (.w) to apply to the mid-tones
* @param highlights Linear RGB color (.rgb) and weight (.w) to apply to the highlights
* @param ranges Range of the shadows (x and y), and range of the highlights (z and w)
*
* @return This Builder, for chaining calls
*/
Builder& shadowsMidtonesHighlights(
math::float4 shadows, math::float4 midtones, math::float4 highlights,
math::float4 ranges) noexcept;
/**
* Applies a slope, offset, and power, as defined by the ASC CDL (American Society of
* Cinematographers Color Decision List) to the image. The CDL can be used to adjust the
* colors of different tonal ranges in the image.
*
* The ASC CDL is similar to the lift/gamma/gain controls found in many color grading tools.
* Lift is equivalent to a combination of offset and slope, gain is equivalent to slope,
* and gamma is equivalent to power.
*
* The slope and power values must be strictly positive. Values less than or equal to 0 will
* be clamped to a small positive value, offset can be any positive or negative value.
*
* Version 1.2 of the ASC CDL adds saturation control, which is here provided as a separate
* API. See the saturation() method for more information.
*
* Slope/offset/power adjustments are performed in log space.
*
* @param slope Multiplier of the input color, must be a strictly positive number
* @param offset Added to the input color, can be a negative or positive number, including 0
* @param power Power exponent of the input color, must be a strictly positive number
*
* @return This Builder, for chaining calls
*/
Builder& slopeOffsetPower(math::float3 slope, math::float3 offset, math::float3 power) noexcept;
/**
* Adjusts the contrast of the image. Lower values decrease the contrast of the image
* (the tonal range is narrowed), and higher values increase the contrast of the image
* (the tonal range is widened). A value of 1.0 has no effect.
*
* The contrast is defined as a value in the range [0.0...2.0]. Values outside of that
* range will be clipped to that range.
*
* Contrast adjustment is performed in log space.
*
* @param contrast Contrast expansion, between 0.0 and 2.0. 1.0 leaves contrast unaffected
*
* @return This Builder, for chaining calls
*/
Builder& contrast(float contrast) noexcept;
/**
* Adjusts the saturation of the image based on the input color's saturation level.
* Colors with a high level of saturation are less affected than colors with low saturation
* levels.
*
* Lower vibrance values decrease intensity of the colors present in the image, and
* higher values increase the intensity of the colors in the image. A value of 1.0 has
* no effect.
*
* The vibrance is defined as a value in the range [0.0...2.0]. Values outside of that
* range will be clipped to that range.
*
* Vibrance adjustment is performed in linear space.
*
* @param vibrance Vibrance, between 0.0 and 2.0. 1.0 leaves vibrance unaffected
*
* @return This Builder, for chaining calls
*/
Builder& vibrance(float vibrance) noexcept;
/**
* Adjusts the saturation of the image. Lower values decrease intensity of the colors
* present in the image, and higher values increase the intensity of the colors in the
* image. A value of 1.0 has no effect.
*
* The saturation is defined as a value in the range [0.0...2.0]. Values outside of that
* range will be clipped to that range.
*
* Saturation adjustment is performed in linear space.
*
* @param saturation Saturation, between 0.0 and 2.0. 1.0 leaves saturation unaffected
*
* @return This Builder, for chaining calls
*/
Builder& saturation(float saturation) noexcept;
/**
* Applies a curve to each RGB channel of the image. Each curve is defined by 3 values:
* a gamma value applied to the shadows only, a mid-point indicating where shadows stop
* and highlights start, and a scale factor for the highlights.
*
* The gamma and mid-point must be strictly positive values. If they are not, they will be
* clamped to a small positive value. The scale can be any negative of positive value.
*
* Curves are applied in linear space.
*
* @param shadowGamma Power value to apply to the shadows, must be strictly positive
* @param midPoint Mid-point defining where shadows stop and highlights start, must be strictly positive
* @param highlightScale Scale factor for the highlights, can be any negative or positive value
*
* @return This Builder, for chaining calls
*/
Builder& curves(math::float3 shadowGamma, math::float3 midPoint, math::float3 highlightScale) noexcept;
/**
* Sets the output color space for this ColorGrading object. After all color grading steps
* have been applied, the final color will be converted in the desired color space.
*
* NOTE: Currently the output color space must be one of Rec709-sRGB-D65 or
* Rec709-Linear-D65. Only the transfer function is taken into account.
*
* @param colorSpace The output color space.
*
* @return This Builder, for chaining calls
*/
Builder& outputColorSpace(const color::ColorSpace& colorSpace) noexcept;
/**
* Creates the ColorGrading object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this ColorGrading with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*/
ColorGrading* build(Engine& engine);
private:
friend class FColorGrading;
};
};
} // namespace filament
#endif // TNT_FILAMENT_COLORGRADING_H

View File

@@ -0,0 +1,256 @@
/*
* 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_COLOR_SPACE_H
#define TNT_FILAMENT_COLOR_SPACE_H
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament::color {
using namespace math;
/**
* Holds the chromaticities of a color space's primaries as xy coordinates
* in xyY (Y is assumed to be 1).
*/
struct Primaries {
float2 r;
float2 g;
float2 b;
bool operator==(const Primaries& rhs) const noexcept {
return r == rhs.r && b == rhs.b && g == rhs.g;
}
};
//! Reference white for a color space, defined as the xy coordinates in the xyY space.
using WhitePoint = float2;
/**
* <p>Defines the parameters for the ICC parametric curve type 4, as
* defined in ICC.1:2004-10, section 10.15.</p>
*
* <p>The EOTF is of the form:</p>
*
* \(\begin{equation}
* Y = \begin{cases}c X + f & X \lt d \\\
* \left( a X + b \right) ^{g} + e & X \ge d \end{cases}
* \end{equation}\)
*
* <p>The corresponding OETF is simply the inverse function.</p>
*
* <p>The parameters defined by this class form a valid transfer
* function only if all the following conditions are met:</p>
* <ul>
* <li>No parameter is a NaN</li>
* <li>\(d\) is in the range \([0..1]\)</li>
* <li>The function is not constant</li>
* <li>The function is positive and increasing</li>
* </ul>
*/
struct TransferFunction {
/**
* <p>Defines the parameters for the ICC parametric curve type 3, as
* defined in ICC.1:2004-10, section 10.15.</p>
*
* <p>The EOTF is of the form:</p>
*
* \(\begin{equation}
* Y = \begin{cases}c X & X \lt d \\\
* \left( a X + b \right) ^{g} & X \ge d \end{cases}
* \end{equation}\)
*
* <p>This constructor is equivalent to setting \(e\) and \(f\) to 0.</p>
*
* @param a The value of \(a\) in the equation of the EOTF described above
* @param b The value of \(b\) in the equation of the EOTF described above
* @param c The value of \(c\) in the equation of the EOTF described above
* @param d The value of \(d\) in the equation of the EOTF described above
* @param g The value of \(g\) in the equation of the EOTF described above
*/
constexpr TransferFunction(
double a,
double b,
double c,
double d,
double e,
double f,
double g
) : a(a),
b(b),
c(c),
d(d),
e(e),
f(f),
g(g) {
}
constexpr TransferFunction(
double a,
double b,
double c,
double d,
double g
) : TransferFunction(a, b, c, d, 0.0, 0.0, g) {
}
bool operator==(const TransferFunction& rhs) const noexcept {
return
a == rhs.a &&
b == rhs.b &&
c == rhs.c &&
d == rhs.d &&
e == rhs.e &&
f == rhs.f &&
g == rhs.g;
}
double a;
double b;
double c;
double d;
double e;
double f;
double g;
};
/**
* <p>A color space in Filament is always an RGB color space. A specific RGB color space
* is defined by the following properties:</p>
* <ul>
* <li>Three chromaticities of the red, green and blue primaries, which
* define the gamut of the color space.</li>
* <li>A white point chromaticity that defines the stimulus to which
* color space values are normalized (also just called "white").</li>
* <li>An opto-electronic transfer function, also called opto-electronic
* conversion function or often, and approximately, gamma function.</li>
* <li>An electro-optical transfer function, also called electo-optical
* conversion function or often, and approximately, gamma function.</li>
* </ul>
*
* <h3>Primaries and white point chromaticities</h3>
* <p>In this implementation, the chromaticity of the primaries and the white
* point of an RGB color space is defined in the CIE xyY color space. This
* color space separates the chromaticity of a color, the x and y components,
* and its luminance, the Y component. Since the primaries and the white
* point have full brightness, the Y component is assumed to be 1 and only
* the x and y components are needed to encode them.</p>
*
* <h3>Transfer functions</h3>
* <p>A transfer function is a color component conversion function, defined as
* a single variable, monotonic mathematical function. It is applied to each
* individual component of a color. They are used to perform the mapping
* between linear tristimulus values and non-linear electronic signal value.</p>
* <p>The <em>opto-electronic transfer function</em> (OETF or OECF) encodes
* tristimulus values in a scene to a non-linear electronic signal value.</p>
*/
class ColorSpace {
public:
constexpr ColorSpace(
const Primaries primaries,
const TransferFunction transferFunction,
const WhitePoint whitePoint
) : mPrimaries(primaries),
mTransferFunction(transferFunction),
mWhitePoint(whitePoint) {
}
bool operator==(const ColorSpace& rhs) const noexcept {
return mPrimaries == rhs.mPrimaries &&
mTransferFunction == rhs.mTransferFunction &&
mWhitePoint == rhs.mWhitePoint;
}
constexpr const Primaries& getPrimaries() const { return mPrimaries; }
constexpr const TransferFunction& getTransferFunction() const { return mTransferFunction; }
constexpr const WhitePoint& getWhitePoint() const { return mWhitePoint; }
private:
Primaries mPrimaries;
TransferFunction mTransferFunction;
WhitePoint mWhitePoint;
};
/**
* Intermediate class used when building a color space using the "-" syntax:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* // Declares a "linear sRGB" color space.
* ColorSpace myColorSpace = Rec709-Linear-D65;
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
class PartialColorSpace {
public:
constexpr ColorSpace operator-(const WhitePoint& whitePoint) const {
return { mPrimaries, mTransferFunction, whitePoint };
}
private:
constexpr PartialColorSpace(
const Primaries primaries,
const TransferFunction transferFunction
) : mPrimaries(primaries),
mTransferFunction(transferFunction) {
}
Primaries mPrimaries;
TransferFunction mTransferFunction;
friend class Gamut;
};
/**
* Defines the chromaticities of the primaries for a color space. The chromaticities
* are expressed as three pairs of xy coordinates (in xyY) for the red, green, and blue
* chromaticities.
*/
class Gamut {
public:
constexpr explicit Gamut(const Primaries primaries) : mPrimaries(primaries) {
}
constexpr Gamut(float2 r, float2 g, float2 b) : Gamut(Primaries{ r, g, b }) {
}
constexpr PartialColorSpace operator-(const TransferFunction& transferFunction) const {
return { mPrimaries, transferFunction };
}
constexpr const Primaries& getPrimaries() const { return mPrimaries; }
private:
Primaries mPrimaries;
};
//! Rec.709 color gamut, used in the sRGB and DisplayP3 color spaces.
constexpr Gamut Rec709 = {{ 0.640f, 0.330f },
{ 0.300f, 0.600f },
{ 0.150f, 0.060f }};
//! Linear transfer function.
constexpr TransferFunction Linear = { 1.0, 0.0, 0.0, 0.0, 1.0 };
//! sRGB transfer function.
constexpr TransferFunction sRGB = { 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 0.04045, 2.4 };
//! Standard CIE 1931 2° illuminant D65. This illuminant has a color temperature of 6504K.
constexpr WhitePoint D65 = { 0.31271f, 0.32902f };
} // namespace filament::color
#endif // TNT_FILAMENT_COLOR_SPACE_H

View File

@@ -0,0 +1,137 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_DEBUGREGISTRY_H
#define TNT_FILAMENT_DEBUGREGISTRY_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
/**
* A registry of runtime properties used exclusively for debugging
*
* Filament exposes a few properties that can be queried and set, which control certain debugging
* features of the engine. These properties can be set at runtime at anytime.
*
*/
class UTILS_PUBLIC DebugRegistry : public FilamentAPI {
public:
/**
* Type of a property
*/
enum Type {
BOOL, INT, FLOAT, FLOAT2, FLOAT3, FLOAT4
};
/**
* Information about a property
*/
struct Property {
const char* name; //!< property name
Type type; //!< property type
};
/**
* Queries whether a property exists
* @param name The name of the property to query
* @return true if the property exists, false otherwise
*/
bool hasProperty(const char* name) const noexcept;
/**
* Queries the address of a property's data from its name
* @param name Name of the property we want the data address of
* @return Address of the data of the \p name property
* @{
*/
void* getPropertyAddress(const char* name) noexcept;
template<typename T>
inline T* getPropertyAddress(const char* name) noexcept {
return static_cast<T*>(getPropertyAddress(name));
}
template<typename T>
inline bool getPropertyAddress(const char* name, T** p) noexcept {
*p = getPropertyAddress<T>(name);
return *p != nullptr;
}
/** @}*/
/**
* Set the value of a property
* @param name Name of the property to set the value of
* @param v Value to set
* @return true if the operation was successful, false otherwise.
* @{
*/
bool setProperty(const char* name, bool v) noexcept;
bool setProperty(const char* name, int v) noexcept;
bool setProperty(const char* name, float v) noexcept;
bool setProperty(const char* name, math::float2 v) noexcept;
bool setProperty(const char* name, math::float3 v) noexcept;
bool setProperty(const char* name, math::float4 v) noexcept;
/** @}*/
/**
* Get the value of a property
* @param name Name of the property to get the value of
* @param v A pointer to a variable which will hold the result
* @return true if the call was successful and \p v was updated
* @{
*/
bool getProperty(const char* name, bool* v) const noexcept;
bool getProperty(const char* name, int* v) const noexcept;
bool getProperty(const char* name, float* v) const noexcept;
bool getProperty(const char* name, math::float2* v) const noexcept;
bool getProperty(const char* name, math::float3* v) const noexcept;
bool getProperty(const char* name, math::float4* v) const noexcept;
/** @}*/
struct DataSource {
void const* data;
size_t count;
};
DataSource getDataSource(const char* name) const noexcept;
struct FrameHistory {
using duration_ms = float;
duration_ms target{};
duration_ms targetWithHeadroom{};
duration_ms frameTime{};
duration_ms frameTimeDenoised{};
float scale = 1.0f;
float pid_e = 0.0f;
float pid_i = 0.0f;
float pid_d = 0.0f;
};
};
} // namespace filament
#endif /* TNT_FILAMENT_DEBUGREGISTRY_H */

View File

@@ -0,0 +1,829 @@
/*
* 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_ENGINE_H
#define TNT_FILAMENT_ENGINE_H
#include <filament/FilamentAPI.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
namespace utils {
class Entity;
class EntityManager;
class JobSystem;
} // namespace utils
namespace filament {
class BufferObject;
class Camera;
class ColorGrading;
class DebugRegistry;
class Fence;
class IndexBuffer;
class SkinningBuffer;
class IndirectLight;
class Material;
class MaterialInstance;
class MorphTargetBuffer;
class Renderer;
class RenderTarget;
class Scene;
class Skybox;
class Stream;
class SwapChain;
class Texture;
class VertexBuffer;
class View;
class InstanceBuffer;
class LightManager;
class RenderableManager;
class TransformManager;
#ifndef FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB
# define FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB 3
#endif
#ifndef FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB
# define FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB 2
#endif
#ifndef FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB
# define FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB 1
#endif
#ifndef FILAMENT_COMMAND_BUFFER_SIZE_IN_MB
# define FILAMENT_COMMAND_BUFFER_SIZE_IN_MB (FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB * 3)
#endif
/**
* Engine is filament's main entry-point.
*
* An Engine instance main function is to keep track of all resources created by the user and
* manage the rendering thread as well as the hardware renderer.
*
* To use filament, an Engine instance must be created first:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Engine essentially represents (or is associated to) a hardware context
* (e.g. an OpenGL ES context).
*
* Rendering typically happens in an operating system's window (which can be full screen), such
* window is managed by a filament.Renderer.
*
* A typical filament render loop looks like this:
*
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Engine.h>
* #include <filament/Renderer.h>
* #include <filament/Scene.h>
* #include <filament/View.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
* SwapChain* swapChain = engine->createSwapChain(nativeWindow);
* Renderer* renderer = engine->createRenderer();
* Scene* scene = engine->createScene();
* View* view = engine->createView();
*
* view->setScene(scene);
*
* do {
* // typically we wait for VSYNC and user input events
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
* } while (!quit);
*
* engine->destroy(view);
* engine->destroy(scene);
* engine->destroy(renderer);
* engine->destroy(swapChain);
* Engine::destroy(&engine); // clears engine*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Resource Tracking
* =================
*
* Each Engine instance keeps track of all objects created by the user, such as vertex and index
* buffers, lights, cameras, etc...
* The user is expected to free those resources, however, leaked resources are freed when the
* engine instance is destroyed and a warning is emitted in the console.
*
* Thread safety
* =============
*
* An Engine instance is not thread-safe. The implementation makes no attempt to synchronize
* calls to an Engine instance methods.
* If multi-threading is needed, synchronization must be external.
*
* Multi-threading
* ===============
*
* When created, the Engine instance starts a render thread as well as multiple worker threads,
* these threads have an elevated priority appropriate for rendering, based on the platform's
* best practices. The number of worker threads depends on the platform and is automatically
* chosen for best performance.
*
* On platforms with asymmetric cores (e.g. ARM's Big.Little), Engine makes some educated guesses
* as to which cores to use for the render thread and worker threads. For example, it'll try to
* keep an OpenGL ES thread on a Big core.
*
* Swap Chains
* ===========
*
* A swap chain represents an Operating System's *native* renderable surface. Typically it's a window
* or a view. Because a SwapChain is initialized from a native object, it is given to filament
* as a `void*`, which must be of the proper type for each platform filament is running on.
*
* @see SwapChain
*
*
* @see Renderer
*/
class UTILS_PUBLIC Engine {
struct BuilderDetails;
public:
using Platform = backend::Platform;
using Backend = backend::Backend;
using DriverConfig = backend::Platform::DriverConfig;
/**
* Config is used to define the memory footprint used by the engine, such as the
* command buffer size. Config can be used to customize engine requirements based
* on the applications needs.
*
* .perRenderPassArenaSizeMB (default: 3 MiB)
* +--------------------------+
* | |
* | .perFrameCommandsSizeMB |
* | (default 2 MiB) |
* | |
* +--------------------------+
* | (froxel, etc...) |
* +--------------------------+
*
*
* .commandBufferSizeMB (default 3MiB)
* +--------------------------+
* | .minCommandBufferSizeMB |
* +--------------------------+
* | .minCommandBufferSizeMB |
* +--------------------------+
* | .minCommandBufferSizeMB |
* +--------------------------+
* : :
* : :
*
*/
struct Config {
/**
* Size in MiB of the low-level command buffer arena.
*
* Each new command buffer is allocated from here. If this buffer is too small the program
* might terminate or rendering errors might occur.
*
* This is typically set to minCommandBufferSizeMB * 3, so that up to 3 frames can be
* batched-up at once.
*
* This value affects the application's memory usage.
*/
uint32_t commandBufferSizeMB = FILAMENT_COMMAND_BUFFER_SIZE_IN_MB;
/**
* Size in MiB of the per-frame data arena.
*
* This is the main arena used for allocations when preparing a frame.
* e.g.: Froxel data and high-level commands are allocated from this arena.
*
* If this size is too small, the program will abort on debug builds and have undefined
* behavior otherwise.
*
* This value affects the application's memory usage.
*/
uint32_t perRenderPassArenaSizeMB = FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB;
/**
* Size in MiB of the backend's handle arena.
*
* Backends will fallback to slower heap-based allocations when running out of space and
* log this condition.
*
* If 0, then the default value for the given platform is used
*
* This value affects the application's memory usage.
*/
uint32_t driverHandleArenaSizeMB = 0;
/**
* Minimum size in MiB of a low-level command buffer.
*
* This is how much space is guaranteed to be available for low-level commands when a new
* buffer is allocated. If this is too small, the engine might have to stall to wait for
* more space to become available, this situation is logged.
*
* This value does not affect the application's memory usage.
*/
uint32_t minCommandBufferSizeMB = FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB;
/**
* Size in MiB of the per-frame high level command buffer.
*
* This buffer is related to the number of draw calls achievable within a frame, if it is
* too small, the program will abort on debug builds and have undefined behavior otherwise.
*
* It is allocated from the 'per-render-pass arena' above. Make sure that at least 1 MiB is
* left in the per-render-pass arena when deciding the size of this buffer.
*
* This value does not affect the application's memory usage.
*/
uint32_t perFrameCommandsSizeMB = FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB;
};
#if UTILS_HAS_THREADING
using CreateCallback = void(void* user, void* token);
#endif
/**
* Engine::Builder is used to create a new filament Engine.
*/
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
friend class FEngine;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* @param backend Which driver backend to use
* @return A reference to this Builder for chaining calls.
*/
Builder& backend(Backend backend) noexcept;
/**
* @param platform A pointer to an object that implements Platform. If this is
* provided, then this object is used to create the hardware context
* and expose platform features to it.
*
* If not provided (or nullptr is used), an appropriate Platform
* is created automatically.
*
* All methods of this interface are called from filament's
* render thread, which is different from the main thread.
*
* The lifetime of \p platform must exceed the lifetime of
* the Engine object.
*
* @return A reference to this Builder for chaining calls.
*/
Builder& platform(Platform* platform) noexcept;
/**
* @param config A pointer to optional parameters to specify memory size
* configuration options. If nullptr, then defaults used.
*
* @return A reference to this Builder for chaining calls.
*/
Builder& config(const Config* config) noexcept;
/**
* @param sharedContext A platform-dependant context used as a shared context
* when creating filament's internal context.
*
* @return A reference to this Builder for chaining calls.
*/
Builder& sharedContext(void* sharedContext) noexcept;
#if UTILS_HAS_THREADING
/**
* Creates the filament Engine asynchronously.
*
* @param callback Callback called once the engine is initialized and it is safe to
* call Engine::getEngine().
*/
void build(utils::Invocable<void(void* token)>&& callback) const;
#endif
/**
* Creates an instance of Engine.
*
* @return A pointer to the newly created Engine, or nullptr if the Engine couldn't be
* created.
* nullptr if the GPU driver couldn't be initialized, for instance if it doesn't
* support the right version of OpenGL or OpenGL ES.
*
* @exception utils::PostConditionPanic can be thrown if there isn't enough memory to
* allocate the command buffer. If exceptions are disabled, this condition if
* fatal and this function will abort.
*/
Engine* build() const;
};
/**
* Backward compatibility helper to create an Engine.
* @see Builder
*/
static inline Engine* create(Backend backend = Backend::DEFAULT,
Platform* platform = nullptr, void* sharedContext = nullptr,
const Config* config = nullptr) {
return Engine::Builder()
.backend(backend)
.platform(platform)
.sharedContext(sharedContext)
.config(config)
.build();
}
#if UTILS_HAS_THREADING
/**
* Backward compatibility helper to create an Engine asynchronously.
* @see Builder
*/
static inline void createAsync(CreateCallback callback, void* user,
Backend backend = Backend::DEFAULT,
Platform* platform = nullptr, void* sharedContext = nullptr,
const Config* config = nullptr) {
Engine::Builder()
.backend(backend)
.platform(platform)
.sharedContext(sharedContext)
.config(config)
.build([callback, user](void* token) {
callback(user, token);
});
}
/**
* Retrieve an Engine* from createAsync(). This must be called from the same thread than
* Engine::createAsync() was called from.
*
* @param token An opaque token given in the createAsync() callback function.
*
* @return A pointer to the newly created Engine, or nullptr if the Engine couldn't be created.
*
* @exception utils::PostConditionPanic can be thrown if there isn't enough memory to
* allocate the command buffer. If exceptions are disabled, this condition if fatal and
* this function will abort.
*/
static Engine* getEngine(void* token);
#endif
/**
* Destroy the Engine instance and all associated resources.
*
* Engine.destroy() should be called last and after all other resources have been destroyed,
* it ensures all filament resources are freed.
*
* Destroy performs the following tasks:
* 1. Destroy all internal software and hardware resources.
* 2. Free all user allocated resources that are not already destroyed and logs a warning.
* This indicates a "leak" in the user's code.
* 3. Terminate the rendering engine's thread.
*
* @param engine A pointer to the filament.Engine* to be destroyed.
* \p engine is cleared upon return.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
* Engine::destroy(&engine); // clears engine*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* \remark
* This method is thread-safe.
*/
static void destroy(Engine** engine);
/**
* Destroy the Engine instance and all associated resources.
*
* Engine.destroy() should be called last and after all other resources have been destroyed,
* it ensures all filament resources are freed.
*
* Destroy performs the following tasks:
* 1. Destroy all internal software and hardware resources.
* 2. Free all user allocated resources that are not already destroyed and logs a warning.
* This indicates a "leak" in the user's code.
* 3. Terminate the rendering engine's thread.
*
* @param engine A pointer to the filament.Engine to be destroyed.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
* Engine::destroy(engine);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* \remark
* This method is thread-safe.
*/
static void destroy(Engine* engine);
using FeatureLevel = backend::FeatureLevel;
/**
* Query the feature level supported by the selected backend.
*
* A specific feature level needs to be set before the corresponding features can be used.
*
* @return FeatureLevel supported the selected backend.
* @see setActiveFeatureLevel
*/
FeatureLevel getSupportedFeatureLevel() const noexcept;
/**
* Activate all features of a given feature level. By default FeatureLevel::FEATURE_LEVEL_1 is
* active. The selected feature level must not be higher than the value returned by
* getActiveFeatureLevel() and it's not possible lower the active feature level.
*
* @param featureLevel the feature level to activate. If featureLevel is lower than
* getActiveFeatureLevel(), the current (higher) feature level is kept.
* If featureLevel is higher than getSupportedFeatureLevel(), an exception
* is thrown, or the program is terminated if exceptions are disabled.
*
* @return the active feature level.
*
* @see getSupportedFeatureLevel
* @see getActiveFeatureLevel
*/
FeatureLevel setActiveFeatureLevel(FeatureLevel featureLevel);
/**
* Returns the currently active feature level.
* @return currently active feature level
* @see getSupportedFeatureLevel
* @see setActiveFeatureLevel
*/
FeatureLevel getActiveFeatureLevel() const noexcept;
/**
* Queries the maximum number of GPU instances that Filament creates when automatic instancing
* is enabled. This value is also the limit for the number of transforms that can be stored in
* an InstanceBuffer. This value may depend on the device and platform, but will remain constant
* during the lifetime of this Engine.
*
* This value does not apply when using the instances(size_t) method on
* RenderableManager::Builder.
*
* @return the number of max automatic instances
* @see setAutomaticInstancingEnabled
* @see RenderableManager::Builder::instances(size_t)
* @see RenderableManager::Builder::instances(size_t, InstanceBuffer*)
*/
size_t getMaxAutomaticInstances() const noexcept;
/**
* @return EntityManager used by filament
*/
utils::EntityManager& getEntityManager() noexcept;
/**
* @return RenderableManager reference
*/
RenderableManager& getRenderableManager() noexcept;
/**
* @return LightManager reference
*/
LightManager& getLightManager() noexcept;
/**
* @return TransformManager reference
*/
TransformManager& getTransformManager() noexcept;
/**
* Helper to enable accurate translations.
* If you need this Engine to handle a very large world space, one way to achieve this
* automatically is to enable accurate translations in the TransformManager. This helper
* provides a convenient way of doing that.
* This is typically called once just after creating the Engine.
*/
void enableAccurateTranslations() noexcept;
/**
* Enables or disables automatic instancing of render primitives. Instancing of render
* primitives can greatly reduce CPU overhead but requires the instanced primitives to be
* identical (i.e. use the same geometry) and use the same MaterialInstance. If it is known
* that the scene doesn't contain any identical primitives, automatic instancing can have some
* overhead and it is then best to disable it.
*
* Disabled by default.
*
* @param enable true to enable, false to disable automatic instancing.
*
* @see RenderableManager
* @see MaterialInstance
*/
void setAutomaticInstancingEnabled(bool enable) noexcept;
/**
* @return true if automatic instancing is enabled, false otherwise.
* @see setAutomaticInstancingEnabled
*/
bool isAutomaticInstancingEnabled() const noexcept;
/**
* Creates a SwapChain from the given Operating System's native window handle.
*
* @param nativeWindow An opaque native window handle. e.g.: on Android this is an
* `ANativeWindow*`.
* @param flags One or more configuration flags as defined in `SwapChain`.
*
* @return A pointer to the newly created SwapChain or nullptr if it couldn't be created.
*
* @see Renderer.beginFrame()
*/
SwapChain* createSwapChain(void* nativeWindow, uint64_t flags = 0) noexcept;
/**
* Creates a headless SwapChain.
*
* @param width Width of the drawing buffer in pixels.
* @param height Height of the drawing buffer in pixels.
* @param flags One or more configuration flags as defined in `SwapChain`.
*
* @return A pointer to the newly created SwapChain or nullptr if it couldn't be created.
*
* @see Renderer.beginFrame()
*/
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags = 0) noexcept;
/**
* Creates a renderer associated to this engine.
*
* A Renderer is intended to map to a *window* on screen.
*
* @return A pointer to the newly created Renderer or nullptr if it couldn't be created.
*/
Renderer* createRenderer() noexcept;
/**
* Creates a View.
*
* @return A pointer to the newly created View or nullptr if it couldn't be created.
*/
View* createView() noexcept;
/**
* Creates a Scene.
*
* @return A pointer to the newly created Scene or nullptr if it couldn't be created.
*/
Scene* createScene() noexcept;
/**
* Creates a Camera component.
*
* @param entity Entity to add the camera component to.
* @return A pointer to the newly created Camera or nullptr if it couldn't be created.
*/
Camera* createCamera(utils::Entity entity) noexcept;
/**
* Returns the Camera component of the given entity.
*
* @param entity An entity.
* @return A pointer to the Camera component for this entity or nullptr if the entity didn't
* have a Camera component. The pointer is valid until destroyCameraComponent()
* is called or the entity itself is destroyed.
*/
Camera* getCameraComponent(utils::Entity entity) noexcept;
/**
* Destroys the Camera component associated with the given entity.
*
* @param entity An entity.
*/
void destroyCameraComponent(utils::Entity entity) noexcept;
/**
* Creates a Fence.
*
* @return A pointer to the newly created Fence or nullptr if it couldn't be created.
*/
Fence* createFence() noexcept;
bool destroy(const BufferObject* p); //!< Destroys a BufferObject object.
bool destroy(const VertexBuffer* p); //!< Destroys an VertexBuffer object.
bool destroy(const Fence* p); //!< Destroys a Fence object.
bool destroy(const IndexBuffer* p); //!< Destroys an IndexBuffer object.
bool destroy(const SkinningBuffer* p); //!< Destroys a SkinningBuffer object.
bool destroy(const MorphTargetBuffer* p); //!< Destroys a MorphTargetBuffer object.
bool destroy(const IndirectLight* p); //!< Destroys an IndirectLight object.
/**
* Destroys a Material object
* @param p the material object to destroy
* @attention All MaterialInstance of the specified material must be destroyed before
* destroying it.
* @exception utils::PreConditionPanic is thrown if some MaterialInstances remain.
* no-op if exceptions are disabled and some MaterialInstances remain.
*/
bool destroy(const Material* p);
bool destroy(const MaterialInstance* p); //!< Destroys a MaterialInstance object.
bool destroy(const Renderer* p); //!< Destroys a Renderer object.
bool destroy(const Scene* p); //!< Destroys a Scene object.
bool destroy(const Skybox* p); //!< Destroys a SkyBox object.
bool destroy(const ColorGrading* p); //!< Destroys a ColorGrading object.
bool destroy(const SwapChain* p); //!< Destroys a SwapChain object.
bool destroy(const Stream* p); //!< Destroys a Stream object.
bool destroy(const Texture* p); //!< Destroys a Texture object.
bool destroy(const RenderTarget* p); //!< Destroys a RenderTarget object.
bool destroy(const View* p); //!< Destroys a View object.
bool destroy(const InstanceBuffer* p); //!< Destroys an InstanceBuffer object.
void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity
bool isValid(const BufferObject* p); //!< Tells whether a BufferObject object is valid
bool isValid(const VertexBuffer* p); //!< Tells whether an VertexBuffer object is valid
bool isValid(const Fence* p); //!< Tells whether a Fence object is valid
bool isValid(const IndexBuffer* p); //!< Tells whether an IndexBuffer object is valid
bool isValid(const SkinningBuffer* p); //!< Tells whether a SkinningBuffer object is valid
bool isValid(const MorphTargetBuffer* p); //!< Tells whether a MorphTargetBuffer object is valid
bool isValid(const IndirectLight* p); //!< Tells whether an IndirectLight object is valid
bool isValid(const Material* p); //!< Tells whether an IndirectLight object is valid
bool isValid(const Renderer* p); //!< Tells whether a Renderer object is valid
bool isValid(const Scene* p); //!< Tells whether a Scene object is valid
bool isValid(const Skybox* p); //!< Tells whether a SkyBox object is valid
bool isValid(const ColorGrading* p); //!< Tells whether a ColorGrading object is valid
bool isValid(const SwapChain* p); //!< Tells whether a SwapChain object is valid
bool isValid(const Stream* p); //!< Tells whether a Stream object is valid
bool isValid(const Texture* p); //!< Tells whether a Texture object is valid
bool isValid(const RenderTarget* p); //!< Tells whether a RenderTarget object is valid
bool isValid(const View* p); //!< Tells whether a View object is valid
bool isValid(const InstanceBuffer* p); //!< Tells whether an InstanceBuffer object is valid
/**
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
* all commands to this point are executed. Note that does guarantee that the
* hardware is actually finished.
*
* <p>This is typically used right after destroying the <code>SwapChain</code>,
* in cases where a guarantee about the <code>SwapChain</code> destruction is needed in a
* timely fashion, such as when responding to Android's
* <code>android.view.SurfaceHolder.Callback.surfaceDestroyed</code></p>
*/
void flushAndWait();
/**
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) but does not wait
* for commands to be either executed or the hardware finished.
*
* <p>This is typically used after creating a lot of objects to start draining the command
* queue which has a limited size.</p>
*/
void flush();
/**
* Drains the user callback message queue and immediately execute all pending callbacks.
*
* <p> Typically this should be called once per frame right after the application's vsync tick,
* and typically just before computing parameters (e.g. object positions) for the next frame.
* This is useful because otherwise callbacks will be executed by filament at a later time,
* which may increase latency in certain applications.</p>
*/
void pumpMessageQueues();
/**
* Returns the default Material.
*
* The default material is 80% white and uses the Material.Shading.LIT shading.
*
* @return A pointer to the default Material instance (a singleton).
*/
const Material* getDefaultMaterial() const noexcept;
/**
* Returns the resolved backend.
*/
Backend getBackend() const noexcept;
/**
* Returns the Platform object that belongs to this Engine.
*
* When Engine::create is called with no platform argument, Filament creates an appropriate
* Platform subclass automatically. The specific subclass created depends on the backend and
* OS. For example, when the OpenGL backend is used, the Platform object will be a descendant of
* OpenGLPlatform.
*
* dynamic_cast should be used to cast the returned Platform object into a specific subclass.
* Note that RTTI must be available to use dynamic_cast.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Platform* platform = engine->getPlatform();
* // static_cast also works, but more dangerous.
* SpecificPlatform* specificPlatform = dynamic_cast<SpecificPlatform*>(platform);
* specificPlatform->platformSpecificMethod();
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* When a custom Platform is passed to Engine::create, Filament will use it instead, and this
* method will return it.
*
* @return A pointer to the Platform object that was provided to Engine::create, or the
* Filament-created one.
*/
Platform* getPlatform() const noexcept;
/**
* Allocate a small amount of memory directly in the command stream. The allocated memory is
* guaranteed to be preserved until the current command buffer is executed
*
* @param size size to allocate in bytes. This should be small (e.g. < 1 KB)
* @param alignment alignment requested
* @return a pointer to the allocated buffer or nullptr if no memory was available.
*
* @note there is no need to destroy this buffer, it will be freed automatically when
* the current command buffer is executed.
*/
void* streamAlloc(size_t size, size_t alignment = alignof(double)) noexcept;
/**
* Invokes one iteration of the render loop, used only on single-threaded platforms.
*
* This should be called every time the windowing system needs to paint (e.g. at 60 Hz).
*/
void execute();
/**
* Retrieves the job system that the Engine has ownership over.
*
* @return JobSystem used by filament
*/
utils::JobSystem& getJobSystem() noexcept;
#if defined(__EMSCRIPTEN__)
/**
* WebGL only: Tells the driver to reset any internal state tracking if necessary.
*
* This is only useful when integrating an external renderer into Filament on platforms
* like WebGL, where share contexts do not exist. Filament keeps track of the GL
* state it has set (like which texture is bound), and does not re-set that state if
* it does not think it needs to. However, if an external renderer has set different
* state in the mean time, Filament will use that new state unknowingly.
*
* If you are in this situation, call this function - ideally only once per frame,
* immediately after calling Engine::execute().
*/
void resetBackendState() noexcept;
#endif
DebugRegistry& getDebugRegistry() noexcept;
protected:
//! \privatesection
Engine() noexcept = default;
~Engine() = default;
public:
//! \privatesection
Engine(Engine const&) = delete;
Engine(Engine&&) = delete;
Engine& operator=(Engine const&) = delete;
Engine& operator=(Engine&&) = delete;
};
} // namespace filament
#endif // TNT_FILAMENT_ENGINE_H

View File

@@ -0,0 +1,129 @@
/*
* 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_EXPOSURE_H
#define TNT_FILAMENT_EXPOSURE_H
#include <utils/compiler.h>
namespace filament {
class Camera;
/**
* A series of utilities to compute exposure, exposure value at ISO 100 (EV100),
* luminance and illuminance using a physically-based camera model.
*/
namespace Exposure {
/**
* Returns the exposure value (EV at ISO 100) of the specified camera.
*/
UTILS_PUBLIC
float ev100(const Camera& camera) noexcept;
/**
* Returns the exposure value (EV at ISO 100) of the specified exposure parameters.
*/
UTILS_PUBLIC
float ev100(float aperture, float shutterSpeed, float sensitivity) noexcept;
/**
* Returns the exposure value (EV at ISO 100) for the given average luminance (in @f$ \frac{cd}{m^2} @f$).
*/
UTILS_PUBLIC
float ev100FromLuminance(float luminance) noexcept;
/**
* Returns the exposure value (EV at ISO 100) for the given illuminance (in lux).
*/
UTILS_PUBLIC
float ev100FromIlluminance(float illuminance) noexcept;
/**
* Returns the photometric exposure for the specified camera.
*/
UTILS_PUBLIC
float exposure(const Camera& camera) noexcept;
/**
* Returns the photometric exposure for the specified exposure parameters.
* This function is equivalent to calling `exposure(ev100(aperture, shutterSpeed, sensitivity))`
* but is slightly faster and offers higher precision.
*/
UTILS_PUBLIC
float exposure(float aperture, float shutterSpeed, float sensitivity) noexcept;
/**
* Returns the photometric exposure for the given EV100.
*/
UTILS_PUBLIC
float exposure(float ev100) noexcept;
/**
* Returns the incident luminance in @f$ \frac{cd}{m^2} @f$ for the specified camera acting as a spot meter.
*/
UTILS_PUBLIC
float luminance(const Camera& camera) noexcept;
/**
* Returns the incident luminance in @f$ \frac{cd}{m^2} @f$ for the specified exposure parameters of
* a camera acting as a spot meter.
* This function is equivalent to calling `luminance(ev100(aperture, shutterSpeed, sensitivity))`
* but is slightly faster and offers higher precision.
*/
UTILS_PUBLIC
float luminance(float aperture, float shutterSpeed, float sensitivity) noexcept;
/**
* Converts the specified EV100 to luminance in @f$ \frac{cd}{m^2} @f$.
* EV100 is not a measure of luminance, but an EV100 can be used to denote a
* luminance for which a camera would use said EV100 to obtain the nominally
* correct exposure
*/
UTILS_PUBLIC
float luminance(float ev100) noexcept;
/**
* Returns the illuminance in lux for the specified camera acting as an incident light meter.
*/
UTILS_PUBLIC
float illuminance(const Camera& camera) noexcept;
/**
* Returns the illuminance in lux for the specified exposure parameters of
* a camera acting as an incident light meter.
* This function is equivalent to calling `illuminance(ev100(aperture, shutterSpeed, sensitivity))`
* but is slightly faster and offers higher precision.
*/
UTILS_PUBLIC
float illuminance(float aperture, float shutterSpeed, float sensitivity) noexcept;
/**
* Converts the specified EV100 to illuminance in lux.
* EV100 is not a measure of illuminance, but an EV100 can be used to denote an
* illuminance for which a camera would use said EV100 to obtain the nominally
* correct exposure.
*/
UTILS_PUBLIC
float illuminance(float ev100) noexcept;
} // namespace exposure
} // namespace filament
#endif // TNT_FILAMENT_EXPOSURE_H

View File

@@ -0,0 +1,86 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_FENCE_H
#define TNT_FILAMENT_FENCE_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
namespace filament {
/**
* Fence is used to synchronize rendering operations together, with the CPU or with compute.
*
* \note
* Currently Fence only provide client-side synchronization.
*
*/
class UTILS_PUBLIC Fence : public FilamentAPI {
public:
//! Special \p timeout value to disable wait()'s timeout.
static constexpr uint64_t FENCE_WAIT_FOR_EVER = backend::FENCE_WAIT_FOR_EVER;
//! Error codes for Fence::wait()
using FenceStatus = backend::FenceStatus;
/** Mode controls the behavior of the command stream when calling wait()
*
* @attention
* It would be unwise to call `wait(..., Mode::DONT_FLUSH)` from the same thread
* the Fence was created, as it would most certainly create a dead-lock.
*/
enum class Mode : uint8_t {
FLUSH, //!< The command stream is flushed
DONT_FLUSH //!< The command stream is not flushed
};
/**
* Client-side wait on the Fence.
*
* Blocks the current thread until the Fence signals.
*
* @param mode Whether the command stream is flushed before waiting or not.
* @param timeout Wait time out. Using a \p timeout of 0 is a way to query the state of the fence.
* A \p timeout value of FENCE_WAIT_FOR_EVER is used to disable the timeout.
* @return FenceStatus::CONDITION_SATISFIED on success,
* FenceStatus::TIMEOUT_EXPIRED if the time out expired or
* FenceStatus::ERROR in other cases.
* @see #Mode
*/
FenceStatus wait(Mode mode = Mode::FLUSH, uint64_t timeout = FENCE_WAIT_FOR_EVER);
/**
* Client-side wait on a Fence and destroy the Fence.
*
* @param fence Fence object to wait on.
*
* @param mode Whether the command stream is flushed before waiting or not.
*
* @return FenceStatus::CONDITION_SATISFIED on success,
* FenceStatus::ERROR otherwise.
*/
static FenceStatus waitAndDestroy(Fence* fence, Mode mode = Mode::FLUSH);
};
} // namespace filament
#endif // TNT_FILAMENT_FENCE_H

View File

@@ -0,0 +1,61 @@
/*
* 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_FILAMENTAPI_H
#define TNT_FILAMENT_FILAMENTAPI_H
#include <utils/compiler.h>
#include <utils/PrivateImplementation.h>
#include <stddef.h>
namespace filament {
/**
* \privatesection
* FilamentAPI is used to define an API in filament.
* It ensures the class defining the API can't be created, destroyed
* or copied by the caller.
*/
class UTILS_PUBLIC FilamentAPI {
protected:
// disallow creation on the stack
FilamentAPI() noexcept = default;
~FilamentAPI() = default;
public:
// disallow copy and assignment
FilamentAPI(FilamentAPI const&) = delete;
FilamentAPI(FilamentAPI&&) = delete;
FilamentAPI& operator=(FilamentAPI const&) = delete;
FilamentAPI& operator=(FilamentAPI&&) = delete;
// allow placement-new allocation, don't use "noexcept", to avoid compiler null check
static void *operator new (size_t, void* p) { return p; }
// prevent heap allocation
static void *operator new (size_t) = delete;
static void *operator new[] (size_t) = delete;
static void operator delete (void*) = delete;
static void operator delete[](void*) = delete;
};
template<typename T>
using BuilderBase = utils::PrivateImplementation<T>;
} // namespace filament
#endif // TNT_FILAMENT_FILAMENTAPI_H

View File

@@ -0,0 +1,127 @@
/*
* 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_FRUSTUM_H
#define TNT_FILAMENT_FRUSTUM_H
#include <utils/compiler.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include <utils/unwindows.h> // Because we define NEAR and FAR in the Plane enum.
namespace filament {
class Box;
class Culler;
/**
* A frustum defined by six planes
*/
class UTILS_PUBLIC Frustum {
public:
enum class Plane : uint8_t {
LEFT,
RIGHT,
BOTTOM,
TOP,
FAR,
NEAR
};
Frustum() = default;
Frustum(const Frustum& rhs) = default;
Frustum(Frustum&& rhs) noexcept = default;
Frustum& operator=(const Frustum& rhs) = default;
Frustum& operator=(Frustum&& rhs) noexcept = default;
/**
* Creates a frustum from a projection matrix in GL convention
* (usually the projection * view matrix)
* @param pv a 4x4 projection matrix in GL convention
*/
explicit Frustum(const math::mat4f& pv);
/**
* Sets the frustum from the given projection matrix
* @param pv a 4x4 projection matrix
*/
void setProjection(const math::mat4f& pv);
/**
* Returns the plane equation parameters with normalized normals
* @param plane Identifier of the plane to retrieve the equation of
* @return A plane equation encoded a float4 R such as R.x*x + R.y*y + R.z*z + R.w = 0
*/
math::float4 getNormalizedPlane(Plane plane) const noexcept;
/**
* Returns a copy of all six frustum planes in left, right, bottom, top, far, near order
* @param planes six plane equations encoded as in getNormalizedPlane() in
* left, right, bottom, top, far, near order
*/
void getNormalizedPlanes(math::float4 planes[6]) const noexcept;
/**
* Returns all six frustum planes in left, right, bottom, top, far, near order
* @return six plane equations encoded as in getNormalizedPlane() in
* left, right, bottom, top, far, near order
*/
math::float4 const* getNormalizedPlanes() const noexcept { return mPlanes; }
/**
* Returns whether a box intersects the frustum (i.e. is visible)
* @param box The box to test against the frustum
* @return true if the box may intersects the frustum, false otherwise. In some situations
* a box that doesn't intersect the frustum might be reported as though it does. However,
* a box that does intersect the frustum is always reported correctly (true).
*/
bool intersects(const Box& box) const noexcept;
/**
* Returns whether a sphere intersects the frustum (i.e. is visible)
* @param sphere A sphere encoded as a center + radius.
* @return true if the sphere may intersects the frustum, false otherwise. In some situations
* a sphere that doesn't intersect the frustum might be reported as though it does. However,
* a sphere that does intersect the frustum is always reported correctly (true).
*/
bool intersects(const math::float4& sphere) const noexcept;
/**
* Returns whether the frustum contains a given point.
* @param p the point to test
* @return the maximum signed distance to the frustum. Negative if p is inside.
*/
float contains(math::float3 p) const noexcept;
private:
friend class Culler;
math::float4 mPlanes[6];
};
} // namespace filament
#if !defined(NDEBUG)
namespace utils::io {
class ostream;
} // namespace utils::io
utils::io::ostream& operator<<(utils::io::ostream& out, filament::Frustum const& frustum);
#endif
#endif // TNT_FILAMENT_FRUSTUM_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.
*/
//! \file
#ifndef TNT_FILAMENT_INDEXBUFFER_H
#define TNT_FILAMENT_INDEXBUFFER_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/BufferDescriptor.h>
#include <utils/compiler.h>
#include <stddef.h>
namespace filament {
class FIndexBuffer;
class Engine;
/**
* A buffer containing vertex indices into a VertexBuffer. Indices can be 16 or 32 bit.
* The buffer itself is a GPU resource, therefore mutating the data can be relatively slow.
* Typically these buffers are constant.
*
* It is possible, and even encouraged, to use a single index buffer for several Renderables.
*
* @see VertexBuffer, RenderableManager
*/
class UTILS_PUBLIC IndexBuffer : public FilamentAPI {
struct BuilderDetails;
public:
using BufferDescriptor = backend::BufferDescriptor;
/**
* Type of the index buffer
*/
enum class IndexType : uint8_t {
USHORT = uint8_t(backend::ElementType::USHORT), //!< 16-bit indices
UINT = uint8_t(backend::ElementType::UINT), //!< 32-bit indices
};
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Size of the index buffer in elements.
* @param indexCount Number of indices the IndexBuffer can hold.
* @return A reference to this Builder for chaining calls.
*/
Builder& indexCount(uint32_t indexCount) noexcept;
/**
* Type of the index buffer, 16-bit or 32-bit.
* @param indexType Type of indices stored in the IndexBuffer.
* @return A reference to this Builder for chaining calls.
*/
Builder& bufferType(IndexType indexType) noexcept;
/**
* Creates the IndexBuffer object and returns a pointer to it. After creation, the index
* buffer is uninitialized. Use IndexBuffer::setBuffer() to initialize the IndexBuffer.
*
* @param engine Reference to the filament::Engine to associate this IndexBuffer with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*
* @see IndexBuffer::setBuffer
*/
IndexBuffer* build(Engine& engine);
private:
friend class FIndexBuffer;
};
/**
* Asynchronously copy-initializes a region of this IndexBuffer from the data provided.
*
* @param engine Reference to the filament::Engine to associate this IndexBuffer with.
* @param buffer A BufferDescriptor representing the data used to initialize the IndexBuffer.
* BufferDescriptor points to raw, untyped data that will be interpreted as
* either 16-bit or 32-bits indices based on the Type of this IndexBuffer.
* @param byteOffset Offset in *bytes* into the IndexBuffer
*/
void setBuffer(Engine& engine, BufferDescriptor&& buffer, uint32_t byteOffset = 0);
/**
* Returns the size of this IndexBuffer in elements.
* @return The number of indices the IndexBuffer holds.
*/
size_t getIndexCount() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_INDEXBUFFER_H

View File

@@ -0,0 +1,349 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_INDIRECTLIGHT_H
#define TNT_FILAMENT_INDIRECTLIGHT_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
namespace filament {
class Engine;
class Texture;
class FIndirectLight;
/**
* IndirectLight is used to simulate environment lighting, a form of global illumination.
*
* Environment lighting has a two components:
* 1. irradiance
* 2. reflections (specular component)
*
* Environments are usually captured as high-resolution HDR equirectangular images and processed
* by the **cmgen** tool to generate the data needed by IndirectLight.
*
* @note
* Currently IndirectLight is intended to be used for "distant probes", that is, to represent
* global illumination from a distant (i.e. at infinity) environment, such as the sky or distant
* mountains. Only a single IndirectLight can be used in a Scene. This limitation will be lifted
* in the future.
*
* Creation and destruction
* ========================
*
* An IndirectLight object is created using the IndirectLight::Builder and destroyed by calling
* Engine::destroy(const IndirectLight*).
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
*
* filament::IndirectLight* environment = filament::IndirectLight::Builder()
* .reflections(cubemap)
* .build(*engine);
*
* engine->destroy(environment);
* ~~~~~~~~~~~
*
*
* Irradiance
* ==========
*
* The irradiance represents the light that comes from the environment and shines an
* object's surface.
*
* The irradiance is calculated automatically from the Reflections (see below), and generally
* doesn't need to be provided explicitly. However, it can be provided separately from the
* Reflections as
* [spherical harmonics](https://en.wikipedia.org/wiki/Spherical_harmonics) (SH) of 1, 2 or
* 3 bands, respectively 1, 4 or 9 coefficients.
*
* @note
* Use the **cmgen** tool to generate the `SH` for a given environment.
*
* Reflections
* ===========
*
* The reflections on object surfaces (specular component) is calculated from a specially
* filtered cubemap pyramid generated by the **cmgen** tool.
*
*
* @see Scene, Light, Texture, Skybox
*/
class UTILS_PUBLIC IndirectLight : public FilamentAPI {
struct BuilderDetails;
public:
//! Use Builder to construct an IndirectLight object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Set the reflections cubemap mipmap chain.
*
* @param cubemap A mip-mapped cubemap generated by **cmgen**. Each cubemap level
* encodes a the irradiance for a roughness level.
*
* @return This Builder, for chaining calls.
*
*/
Builder& reflections(Texture const* cubemap) noexcept;
/**
* Sets the irradiance as Spherical Harmonics.
*
* The irradiance must be pre-convolved by \f$ \langle n \cdot l \rangle \f$ and
* pre-multiplied by the Lambertian diffuse BRDF \f$ \frac{1}{\pi} \f$ and
* specified as Spherical Harmonics coefficients.
*
* Additionally, these Spherical Harmonics coefficients must be pre-scaled by the
* reconstruction factors \f$ A_{l}^{m} \f$ below.
*
* The final coefficients can be generated using the `cmgen` tool.
*
* The index in the \p sh array is given by:
*
* `index(l, m) = l * (l + 1) + m`
*
* \f$ sh[index(l,m)] = L_{l}^{m} \frac{1}{\pi} A_{l}^{m} \hat{C_{l}} \f$
*
* index | l | m | \f$ A_{l}^{m} \f$ | \f$ \hat{C_{l}} \f$ | \f$ \frac{1}{\pi} A_{l}^{m}\hat{C_{l}} \f$ |
* :-----:|:---:|:---:|:------------------:|:---------------------:|:--------------------------------------------:
* 0 | 0 | 0 | 0.282095 | 3.1415926 | 0.282095
* 1 | 1 | -1 | -0.488602 | 2.0943951 | -0.325735
* 2 | ^ | 0 | 0.488602 | ^ | 0.325735
* 3 | ^ | 1 | -0.488602 | ^ | -0.325735
* 4 | 2 | -2 | 1.092548 | 0.785398 | 0.273137
* 5 | ^ | -1 | -1.092548 | ^ | -0.273137
* 6 | ^ | 0 | 0.315392 | ^ | 0.078848
* 7 | ^ | 1 | -1.092548 | ^ | -0.273137
* 8 | ^ | 2 | 0.546274 | ^ | 0.136569
*
*
* Only 1, 2 or 3 bands are allowed.
*
* @param bands Number of spherical harmonics bands. Must be 1, 2 or 3.
* @param sh Array containing the spherical harmonics coefficients.
* The size of the array must be \f$ bands^{2} \f$.
* (i.e. 1, 4 or 9 coefficients respectively).
*
* @return This Builder, for chaining calls.
*
* @note
* Because the coefficients are pre-scaled, `sh[0]` is the environment's
* average irradiance.
*/
Builder& irradiance(uint8_t bands, math::float3 const* sh) noexcept;
/**
* Sets the irradiance from the radiance expressed as Spherical Harmonics.
*
* The radiance must be specified as Spherical Harmonics coefficients \f$ L_{l}^{m} \f$
*
* The index in the \p sh array is given by:
*
* `index(l, m) = l * (l + 1) + m`
*
* \f$ sh[index(l,m)] = L_{l}^{m} \f$
*
* index | l | m
* :-----:|:---:|:---:
* 0 | 0 | 0
* 1 | 1 | -1
* 2 | ^ | 0
* 3 | ^ | 1
* 4 | 2 | -2
* 5 | ^ | -1
* 6 | ^ | 0
* 7 | ^ | 1
* 8 | ^ | 2
*
* @param bands Number of spherical harmonics bands. Must be 1, 2 or 3.
* @param sh Array containing the spherical harmonics coefficients.
* The size of the array must be \f$ bands^{2} \f$.
* (i.e. 1, 4 or 9 coefficients respectively).
*
* @return This Builder, for chaining calls.
*/
Builder& radiance(uint8_t bands, math::float3 const* sh) noexcept;
/**
* Sets the irradiance as a cubemap.
*
* The irradiance can alternatively be specified as a cubemap instead of Spherical
* Harmonics coefficients. It may or may not be more efficient, depending on your
* hardware (essentially, it's trading ALU for bandwidth).
*
* @param cubemap Cubemap representing the Irradiance pre-convolved by
* \f$ \langle n \cdot l \rangle \f$.
*
* @return This Builder, for chaining calls.
*
* @note
* This irradiance cubemap can be generated with the **cmgen** tool.
*
* @see irradiance(uint8_t bands, math::float3 const* sh)
*/
Builder& irradiance(Texture const* cubemap) noexcept;
/**
* (optional) Environment intensity.
*
* Because the environment is encoded usually relative to some reference, the
* range can be adjusted with this method.
*
* @param envIntensity Scale factor applied to the environment and irradiance such that
* the result is in lux, or lumen/m^2 (default = 30000)
*
* @return This Builder, for chaining calls.
*/
Builder& intensity(float envIntensity) noexcept;
/**
* Specifies the rigid-body transformation to apply to the IBL.
*
* @param rotation 3x3 rotation matrix. Must be a rigid-body transform.
*
* @return This Builder, for chaining calls.
*/
Builder& rotation(math::mat3f const& rotation) noexcept;
/**
* Creates the IndirectLight object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this IndirectLight with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
IndirectLight* build(Engine& engine);
private:
friend class FIndirectLight;
};
/**
* Sets the environment's intensity.
*
* Because the environment is encoded usually relative to some reference, the
* range can be adjusted with this method.
*
* @param intensity Scale factor applied to the environment and irradiance such that
* the result is in lux, or <i>lumen/m^2</i> (default = 30000)
*/
void setIntensity(float intensity) noexcept;
/**
* Returns the environment's intensity in <i>lux</i>, or <i>lumen/m^2</i>.
*/
float getIntensity() const noexcept;
/**
* Sets the rigid-body transformation to apply to the IBL.
*
* @param rotation 3x3 rotation matrix. Must be a rigid-body transform.
*/
void setRotation(math::mat3f const& rotation) noexcept;
/**
* Returns the rigid-body transformation applied to the IBL.
*/
const math::mat3f& getRotation() const noexcept;
/**
* Returns the associated reflection map, or null if it does not exist.
*/
Texture const* getReflectionsTexture() const noexcept;
/**
* Returns the associated irradiance map, or null if it does not exist.
*/
Texture const* getIrradianceTexture() const noexcept;
/**
* Helper to estimate the direction of the dominant light in the environment represented by
* spherical harmonics.
*
* This assumes that there is only a single dominant light (such as the sun in outdoors
* environments), if it's not the case the direction returned will be an average of the
* various lights based on their intensity.
*
* If there are no clear dominant light, as is often the case with low dynamic range (LDR)
* environments, this method may return a wrong or unexpected direction.
*
* The dominant light direction can be used to set a directional light's direction,
* for instance to produce shadows that match the environment.
*
* @param sh 3-band spherical harmonics
*
* @return A unit vector representing the direction of the dominant light
*
* @see LightManager::Builder::direction()
* @see getColorEstimate()
*/
static math::float3 getDirectionEstimate(const math::float3 sh[9]) noexcept;
/**
* Helper to estimate the color and relative intensity of the environment represented by
* spherical harmonics in a given direction.
*
* This can be used to set the color and intensity of a directional light. In this case
* make sure to multiply this relative intensity by the the intensity of this indirect light.
*
* @param sh 3-band spherical harmonics
* @param direction a unit vector representing the direction of the light to estimate the
* color of. Typically this the value returned by getDirectionEstimate().
*
* @return A vector of 4 floats where the first 3 components represent the linear color and
* the 4th component represents the intensity of the dominant light
*
* @see LightManager::Builder::color()
* @see LightManager::Builder::intensity()
* @see getDirectionEstimate, getIntensity, setIntensity
*/
static math::float4 getColorEstimate(const math::float3 sh[9], math::float3 direction) noexcept;
/** @deprecated use static versions instead */
UTILS_DEPRECATED
math::float3 getDirectionEstimate() const noexcept;
/** @deprecated use static versions instead */
UTILS_DEPRECATED
math::float4 getColorEstimate(math::float3 direction) const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_INDIRECTLIGHT_H

View File

@@ -0,0 +1,98 @@
/*
* 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_FILAMENT_INSTANCEBUFFER_H
#define TNT_FILAMENT_INSTANCEBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/Engine.h>
#include <math/mathfwd.h>
namespace filament {
/**
* InstanceBuffer holds draw (GPU) instance transforms. These can be provided to a renderable to
* "offset" each draw instance.
*
* @see RenderableManager::Builder::instances(size_t, InstanceBuffer*)
*/
class UTILS_PUBLIC InstanceBuffer : public FilamentAPI {
struct BuilderDetails;
public:
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
/**
* @param instanceCount the number of instances this InstanceBuffer will support, must be
* >= 1 and <= \c Engine::getMaxAutomaticInstances()
* @see Engine::getMaxAutomaticInstances
*/
Builder(size_t instanceCount) noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Provide an initial local transform for each instance. Each local transform is relative to
* the transform of the associated renderable. This forms a parent-child relationship
* between the renderable and its instances, so adjusting the renderable's transform will
- * affect all instances.
*
* The array of math::mat4f must have length instanceCount, provided when constructing this
* Builder.
*
* @param localTransforms an array of math::mat4f with length instanceCount, must remain
* valid until after build() is called
*/
Builder& localTransforms(math::mat4f const* localTransforms) noexcept;
/**
* Creates the InstanceBuffer object and returns a pointer to it.
*/
InstanceBuffer* build(Engine& engine);
private:
friend class FInstanceBuffer;
};
/**
* Returns the instance count specified when building this InstanceBuffer.
*/
size_t getInstanceCount() const noexcept;
/**
* Sets the local transform for each instance. Each local transform is relative to the transform
* of the associated renderable. This forms a parent-child relationship between the renderable
* and its instances, so adjusting the renderable's transform will affect all instances.
*
* @param localTransforms an array of math::mat4f with length count, need not outlive this call
* @param count the number of local transforms
* @param offset index of the first instance to set local transforms
*/
void setLocalTransforms(math::mat4f const* localTransforms, size_t count, size_t offset = 0);
};
} // namespace filament
#endif //TNT_FILAMENT_INSTANCEBUFFER_H

View File

@@ -0,0 +1,964 @@
/*
* 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_LIGHTMANAGER_H
#define TNT_FILAMENT_LIGHTMANAGER_H
#include <filament/FilamentAPI.h>
#include <filament/Color.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <utils/EntityInstance.h>
#include <math/mathfwd.h>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
class Engine;
class FEngine;
class FLightManager;
/**
* LightManager allows to create a light source in the scene, such as a sun or street lights.
*
* At least one light must be added to a scene in order to see anything
* (unless the Material.Shading.UNLIT is used).
*
*
* Creation and destruction
* ========================
*
* A Light component is created using the LightManager::Builder and destroyed by calling
* LightManager::destroy(utils::Entity).
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
* utils::Entity sun = utils::EntityManager.get().create();
*
* filament::LightManager::Builder(Type::SUN)
* .castShadows(true)
* .build(*engine, sun);
*
* engine->getLightManager().destroy(sun);
* ~~~~~~~~~~~
*
*
* Light types
* ===========
*
* Lights come in three flavors:
* - directional lights
* - point lights
* - spot lights
*
*
* Directional lights
* ------------------
*
* Directional lights have a direction, but don't have a position. All light rays are
* parallel and come from infinitely far away and from everywhere. Typically a directional light
* is used to simulate the sun.
*
* Directional lights and spot lights are able to cast shadows.
*
* To create a directional light use Type.DIRECTIONAL or Type.SUN, both are similar, but the later
* also draws a sun's disk in the sky and its reflection on glossy objects.
*
* @warning Currently, only a single directional light is supported. If several directional lights
* are added to the scene, the dominant one will be used.
*
* @see Builder.direction(), Builder.sunAngularRadius()
*
* Point lights
* ------------
*
* Unlike directional lights, point lights have a position but emit light in all directions.
* The intensity of the light diminishes with the inverse square of the distance to the light.
* Builder.falloff() controls distance beyond which the light has no more influence.
*
* A scene can have multiple point lights.
*
* @see Builder.position(), Builder.falloff()
*
* Spot lights
* -----------
*
* Spot lights are similar to point lights but the light it emits is limited to a cone defined by
* Builder.spotLightCone() and the light's direction.
*
* A spot light is therefore defined by a position, a direction and inner and outer cones. The
* spot light's influence is limited to inside the outer cone. The inner cone defines the light's
* falloff attenuation.
*
* A physically correct spot light is a little difficult to use because changing the outer angle
* of the cone changes the illumination levels, as the same amount of light is spread over a
* changing volume. The coupling of illumination and the outer cone means that an artist cannot
* tweak the influence cone of a spot light without also changing the perceived illumination.
* It therefore makes sense to provide artists with a parameter to disable this coupling. This
* is the difference between Type.FOCUSED_SPOT and Type.SPOT.
*
* @see Builder.position(), Builder.direction(), Builder.falloff(), Builder.spotLightCone()
*
* Performance considerations
* ==========================
*
* Generally, adding lights to the scene hurts performance, however filament is designed to be
* able to handle hundreds of lights in a scene under certain conditions. Here are some tips
* to keep performances high.
*
* 1. Prefer spot lights to point lights and use the smallest outer cone angle possible.
*
* 2. Use the smallest possible falloff distance for point and spot lights.
* Performance is very sensitive to overlapping lights. The falloff distance essentially
* defines a sphere of influence for the light, so try to position point and spot lights
* such that they don't overlap too much.
*
* On the other hand, a scene can contain hundreds of non overlapping lights without
* incurring a significant overhead.
*
*/
class UTILS_PUBLIC LightManager : public FilamentAPI {
struct BuilderDetails;
public:
using Instance = utils::EntityInstance<LightManager>;
/**
* Returns the number of component in the LightManager, not that component are not
* guaranteed to be active. Use the EntityManager::isAlive() before use if needed.
*
* @return number of component in the LightManager
*/
size_t getComponentCount() const noexcept;
/**
* Returns the list of Entity for all components. Use getComponentCount() to know the size
* of the list.
* @return a pointer to Entity
*/
utils::Entity const* getEntities() const noexcept;
/**
* Returns whether a particular Entity is associated with a component of this LightManager
* @param e An Entity.
* @return true if this Entity has a component associated with this manager.
*/
bool hasComponent(utils::Entity e) const noexcept;
/**
* Gets an Instance representing the Light component associated with the given Entity.
* @param e An Entity.
* @return An Instance object, which represents the Light component associated with the Entity e.
* @note Use Instance::isValid() to make sure the component exists.
* @see hasComponent()
*/
Instance getInstance(utils::Entity e) const noexcept;
// destroys this component from the given entity
void destroy(utils::Entity e) noexcept;
//! Denotes the type of the light being created.
enum class Type : uint8_t {
SUN, //!< Directional light that also draws a sun's disk in the sky.
DIRECTIONAL, //!< Directional light, emits light in a given direction.
POINT, //!< Point light, emits light from a position, in all directions.
FOCUSED_SPOT, //!< Physically correct spot light.
SPOT, //!< Spot light with coupling of outer cone and illumination disabled.
};
/**
* Control the quality / performance of the shadow map associated to this light
*/
struct ShadowOptions {
/** Size of the shadow map in texels. Must be a power-of-two and larger or equal to 8. */
uint32_t mapSize = 1024;
/**
* Number of shadow cascades to use for this light. Must be between 1 and 4 (inclusive).
* A value greater than 1 turns on cascaded shadow mapping (CSM).
* Only applicable to Type.SUN or Type.DIRECTIONAL lights.
*
* When using shadow cascades, cascadeSplitPositions must also be set.
*
* @see ShadowOptions::cascadeSplitPositions
*/
uint8_t shadowCascades = 1;
/**
* The split positions for shadow cascades.
*
* Cascaded shadow mapping (CSM) partitions the camera frustum into cascades. These values
* determine the planes along the camera's Z axis to split the frustum. The camera near
* plane is represented by 0.0f and the far plane represented by 1.0f.
*
* For example, if using 4 cascades, these values would set a uniform split scheme:
* { 0.25f, 0.50f, 0.75f }
*
* For N cascades, N - 1 split positions will be read from this array.
*
* Filament provides utility methods inside LightManager::ShadowCascades to help set these
* values. For example, to use a uniform split scheme:
*
* ~~~~~~~~~~~{.cpp}
* LightManager::ShadowCascades::computeUniformSplits(options.splitPositions, 4);
* ~~~~~~~~~~~
*
* @see ShadowCascades::computeUniformSplits
* @see ShadowCascades::computeLogSplits
* @see ShadowCascades::computePracticalSplits
*/
float cascadeSplitPositions[3] = { 0.125f, 0.25f, 0.50f };
/** Constant bias in world units (e.g. meters) by which shadows are moved away from the
* light. 1mm by default.
* This is ignored when the View's ShadowType is set to VSM.
*/
float constantBias = 0.001f;
/** Amount by which the maximum sampling error is scaled. The resulting value is used
* to move the shadow away from the fragment normal. Should be 1.0.
* This is ignored when the View's ShadowType is set to VSM.
*/
float normalBias = 1.0f;
/** Distance from the camera after which shadows are clipped. This is used to clip
* shadows that are too far and wouldn't contribute to the scene much, improving
* performance and quality. This value is always positive.
* Use 0.0f to use the camera far distance.
*/
float shadowFar = 0.0f;
/** Optimize the quality of shadows from this distance from the camera. Shadows will
* be rendered in front of this distance, but the quality may not be optimal.
* This value is always positive. Use 0.0f to use the camera near distance.
* The default of 1m works well with many scenes. The quality of shadows may drop
* rapidly when this value decreases.
*/
float shadowNearHint = 1.0f;
/** Optimize the quality of shadows in front of this distance from the camera. Shadows
* will be rendered behind this distance, but the quality may not be optimal.
* This value is always positive. Use std::numerical_limits<float>::infinity() to
* use the camera far distance.
*/
float shadowFarHint = 100.0f;
/**
* Controls whether the shadow map should be optimized for resolution or stability.
* When set to true, all resolution enhancing features that can affect stability are
* disabling, resulting in significantly lower resolution shadows, albeit stable ones.
*
* Setting this flag to true always disables LiSPSM (see below).
*
* @see lispsm
*/
bool stable = false;
/**
* LiSPSM, or light-space perspective shadow-mapping is a technique allowing to better
* optimize the use of the shadow-map texture. When enabled the effective resolution of
* shadows is greatly improved and yields result similar to using cascades without the
* extra cost. LiSPSM comes with some drawbacks however, in particular it is incompatible
* with blurring because it effectively affects the blur kernel size.
*
* Blurring is only an issue when using ShadowType::VSM with a large blur or with
* ShadowType::PCSS however.
*
* If these blurring artifacts become problematic, this flag can be used to disable LiSPSM.
*
* @see stable
*/
bool lispsm = true;
/**
* Constant bias in depth-resolution units by which shadows are moved away from the
* light. The default value of 0.5 is used to round depth values up.
* Generally this value shouldn't be changed or at least be small and positive.
* This is ignored when the View's ShadowType is set to VSM.
*/
float polygonOffsetConstant = 0.5f;
/**
* Bias based on the change in depth in depth-resolution units by which shadows are moved
* away from the light. The default value of 2.0 works well with SHADOW_SAMPLING_PCF_LOW.
* Generally this value is between 0.5 and the size in texel of the PCF filter.
* Setting this value correctly is essential for LISPSM shadow-maps.
* This is ignored when the View's ShadowType is set to VSM.
*/
float polygonOffsetSlope = 2.0f;
/**
* Whether screen-space contact shadows are used. This applies regardless of whether a
* Renderable is a shadow caster.
* Screen-space contact shadows are typically useful in large scenes.
* (off by default)
*/
bool screenSpaceContactShadows = false;
/**
* Number of ray-marching steps for screen-space contact shadows (8 by default).
*
* CAUTION: this parameter is ignored for all lights except the directional/sun light,
* all other lights use the same value set for the directional/sun light.
*
*/
uint8_t stepCount = 8;
/**
* Maximum shadow-occluder distance for screen-space contact shadows (world units).
* (30 cm by default)
*
* CAUTION: this parameter is ignored for all lights except the directional/sun light,
* all other lights use the same value set for the directional/sun light.
*
*/
float maxShadowDistance = 0.3f;
/**
* Options available when the View's ShadowType is set to VSM.
*
* @warning This API is still experimental and subject to change.
* @see View::setShadowType
*/
struct Vsm {
/**
* When elvsm is set to true, "Exponential Layered VSM without Layers" are used. It is
* an improvement to the default EVSM which suffers important light leaks. Enabling
* ELVSM for a single shadowmap doubles the memory usage of all shadow maps.
* ELVSM is mostly useful when large blurs are used.
*/
bool elvsm = false;
/**
* Blur width for the VSM blur. Zero do disable.
* The maximum value is 125.
*/
float blurWidth = 0.0f;
} vsm;
/**
* Light bulb radius used for soft shadows. Currently this is only used when DPCF or PCSS is
* enabled. (2cm by default).
*/
float shadowBulbRadius = 0.02f;
};
struct ShadowCascades {
/**
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a uniform
* split scheme.
*
* @param splitPositions a float array of at least size (cascades - 1) to write the split
* positions into
* @param cascades the number of shadow cascades, at most 4
*/
static void computeUniformSplits(float* splitPositions, uint8_t cascades);
/**
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a logarithmic
* split scheme.
*
* @param splitPositions a float array of at least size (cascades - 1) to write the split
* positions into
* @param cascades the number of shadow cascades, at most 4
* @param near the camera near plane
* @param far the camera far plane
*/
static void computeLogSplits(float* splitPositions, uint8_t cascades,
float near, float far);
/**
* Utility method to compute ShadowOptions::cascadeSplitPositions according to a practical
* split scheme.
*
* The practical split scheme uses uses a lambda value to interpolate between the logarithmic
* and uniform split schemes. Start with a lambda value of 0.5f and adjust for your scene.
*
* See: Zhang et al 2006, "Parallel-split shadow maps for large-scale virtual environments"
*
* @param splitPositions a float array of at least size (cascades - 1) to write the split
* positions into
* @param cascades the number of shadow cascades, at most 4
* @param near the camera near plane
* @param far the camera far plane
* @param lambda a float in the range [0, 1] that interpolates between log and
* uniform split schemes
*/
static void computePracticalSplits(float* splitPositions, uint8_t cascades,
float near, float far, float lambda);
};
//! Use Builder to construct a Light object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
/**
* Creates a light builder and set the light's #Type.
*
* @param type #Type of Light object to create.
*/
explicit Builder(Type type) noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Enables or disables a light channel. Light channel 0 is enabled by default.
*
* @param channel Light channel to enable or disable, between 0 and 7.
* @param enable Whether to enable or disable the light channel.
* @return This Builder, for chaining calls.
*/
Builder& lightChannel(unsigned int channel, bool enable = true) noexcept;
/**
* Whether this Light casts shadows (disabled by default)
*
* @param enable Enables or disables casting shadows from this Light.
*
* @return This Builder, for chaining calls.
*/
Builder& castShadows(bool enable) noexcept;
/**
* Sets the shadow-map options for this light.
*
* @return This Builder, for chaining calls.
*/
Builder& shadowOptions(const ShadowOptions& options) noexcept;
/**
* Whether this light casts light (enabled by default)
*
* @param enable Enables or disables lighting from this Light.
*
* @return This Builder, for chaining calls.
*
* @note
* In some situations it can be useful to have a light in the scene that doesn't
* actually emit light, but does cast shadows.
*/
Builder& castLight(bool enable) noexcept;
/**
* Sets the initial position of the light in world space.
*
* @param position Light's position in world space. The default is at the origin.
*
* @return This Builder, for chaining calls.
*
* @note
* The Light's position is ignored for directional lights (Type.DIRECTIONAL or Type.SUN)
*/
Builder& position(const math::float3& position) noexcept;
/**
* Sets the initial direction of a light in world space.
*
* @param direction Light's direction in world space. Should be a unit vector.
* The default is {0,-1,0}.
*
* @return This Builder, for chaining calls.
*
* @note
* The Light's direction is ignored for Type.POINT lights.
*/
Builder& direction(const math::float3& direction) noexcept;
/**
* Sets the initial color of a light.
*
* @param color Color of the light specified in the linear sRGB color-space.
* The default is white {1,1,1}.
*
* @return This Builder, for chaining calls.
*/
Builder& color(const LinearColor& color) noexcept;
/**
* Sets the initial intensity of a light.
* @param intensity This parameter depends on the Light.Type:
* - For directional lights, it specifies the illuminance in *lux*
* (or *lumen/m^2*).
* - For point lights and spot lights, it specifies the luminous power
* in *lumen*.
*
* @return This Builder, for chaining calls.
*
* For example, the sun's illuminance is about 100,000 lux.
*
* This method overrides any prior calls to intensity or intensityCandela.
*
*/
Builder& intensity(float intensity) noexcept;
/**
* Sets the initial intensity of a spot or point light in candela.
*
* @param intensity Luminous intensity in *candela*.
*
* @return This Builder, for chaining calls.
*
* @note
* This method is equivalent to calling intensity(float intensity) for directional lights
* (Type.DIRECTIONAL or Type.SUN).
*
* This method overrides any prior calls to intensity or intensityCandela.
*/
Builder& intensityCandela(float intensity) noexcept;
/**
* Sets the initial intensity of a light in watts.
*
* @param watts Energy consumed by a lightbulb. It is related to the energy produced
* and ultimately the brightness by the \p efficiency parameter.
* This value is often available on the packaging of commercial
* lightbulbs.
*
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
*
* Lightbulb type | Efficiency
* ----------------:|-----------:
* Incandescent | 2.2%
* Halogen | 7.0%
* LED | 8.7%
* Fluorescent | 10.7%
*
* @return This Builder, for chaining calls.
*
*
* @note
* This call is equivalent to `Builder::intensity(efficiency * 683 * watts);`
*
* This method overrides any prior calls to intensity or intensityCandela.
*/
Builder& intensity(float watts, float efficiency) noexcept;
/**
* Set the falloff distance for point lights and spot lights.
*
* At the falloff distance, the light has no more effect on objects.
*
* The falloff distance essentially defines a *sphere of influence* around the light, and
* therefore has an impact on performance. Larger falloffs might reduce performance
* significantly, especially when many lights are used.
*
* Try to avoid having a large number of light's spheres of influence overlap.
*
* @param radius Falloff distance in world units. Default is 1 meter.
*
* @return This Builder, for chaining calls.
*
* @note
* The Light's falloff is ignored for directional lights (Type.DIRECTIONAL or Type.SUN)
*/
Builder& falloff(float radius) noexcept;
/**
* Defines a spot light'st angular falloff attenuation.
*
* A spot light is defined by a position, a direction and two cones, \p inner and \p outer.
* These two cones are used to define the angular falloff attenuation of the spot light
* and are defined by the angle from the center axis to where the falloff begins (i.e.
* cones are defined by their half-angle).
*
* Both inner and outer are silently clamped to a minimum value of 0.5 degrees
* (~0.00873 radians) to avoid floating-point precision issues during rendering.
*
* @param inner inner cone angle in *radians* between 0.00873 and \p outer
* @param outer outer cone angle in *radians* between 0.00873 inner and @f$ \pi/2 @f$
* @return This Builder, for chaining calls.
*
* @note
* The spot light cone is ignored for directional and point lights.
*
* @see Type.SPOT, Type.FOCUSED_SPOT
*/
Builder& spotLightCone(float inner, float outer) noexcept;
/**
* Defines the angular radius of the sun, in degrees, between 0.25° and 20.0°
*
* The Sun as seen from Earth has an angular size of 0.526° to 0.545°
*
* @param angularRadius sun's radius in degree. Default is 0.545°.
*
* @return This Builder, for chaining calls.
*/
Builder& sunAngularRadius(float angularRadius) noexcept;
/**
* Defines the halo radius of the sun. The radius of the halo is defined as a
* multiplier of the sun angular radius.
*
* @param haloSize radius multiplier. Default is 10.0.
*
* @return This Builder, for chaining calls.
*/
Builder& sunHaloSize(float haloSize) noexcept;
/**
* Defines the halo falloff of the sun. The falloff is a dimensionless number
* used as an exponent.
*
* @param haloFalloff halo falloff. Default is 80.0.
*
* @return This Builder, for chaining calls.
*/
Builder& sunHaloFalloff(float haloFalloff) noexcept;
enum Result { Error = -1, Success = 0 };
/**
* Adds the Light component to an entity.
*
* @param engine Reference to the filament::Engine to associate this light with.
* @param entity Entity to add the light component to.
* @return Success if the component was created successfully, Error otherwise.
*
* If exceptions are disabled and an error occurs, this function is a no-op.
* Success can be checked by looking at the return value.
*
* If this component already exists on the given entity, it is first destroyed as if
* destroy(utils::Entity e) was called.
*
* @warning
* Currently, only 2048 lights can be created on a given Engine.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Result build(Engine& engine, utils::Entity entity);
private:
friend class FEngine;
friend class FLightManager;
};
static constexpr float EFFICIENCY_INCANDESCENT = 0.0220f; //!< Typical efficiency of an incandescent light bulb (2.2%)
static constexpr float EFFICIENCY_HALOGEN = 0.0707f; //!< Typical efficiency of an halogen light bulb (7.0%)
static constexpr float EFFICIENCY_FLUORESCENT = 0.0878f; //!< Typical efficiency of a fluorescent light bulb (8.7%)
static constexpr float EFFICIENCY_LED = 0.1171f; //!< Typical efficiency of a LED light bulb (11.7%)
Type getType(Instance i) const noexcept;
/**
* Helper function that returns if a light is a directional light
*
* @param i Instance of the component obtained from getInstance().
* @return true is this light is a type of directional light
*/
inline bool isDirectional(Instance i) const noexcept {
Type type = getType(i);
return type == Type::DIRECTIONAL || type == Type::SUN;
}
/**
* Helper function that returns if a light is a point light
*
* @param i Instance of the component obtained from getInstance().
* @return true is this light is a type of point light
*/
inline bool isPointLight(Instance i) const noexcept {
return getType(i) == Type::POINT;
}
/**
* Helper function that returns if a light is a spot light
*
* @param i Instance of the component obtained from getInstance().
* @return true is this light is a type of spot light
*/
inline bool isSpotLight(Instance i) const noexcept {
Type type = getType(i);
return type == Type::SPOT || type == Type::FOCUSED_SPOT;
}
/**
* Enables or disables a light channel. Light channel 0 is enabled by default.
* @param channel light channel to enable or disable, between 0 and 7.
* @param enable whether to enable (true) or disable (false) the specified light channel.
*/
void setLightChannel(Instance i, unsigned int channel, bool enable = true) noexcept;
/**
* Returns whether a light channel is enabled on a specified light.
* @param i Instance of the component obtained from getInstance().
* @param channel Light channel to query
* @return true if the light channel is enabled, false otherwise
*/
bool getLightChannel(Instance i, unsigned int channel) const noexcept;
/**
* Dynamically updates the light's position.
*
* @param i Instance of the component obtained from getInstance().
* @param position Light's position in world space. The default is at the origin.
*
* @see Builder.position()
*/
void setPosition(Instance i, const math::float3& position) noexcept;
//! returns the light's position in world space
const math::float3& getPosition(Instance i) const noexcept;
/**
* Dynamically updates the light's direction
*
* @param i Instance of the component obtained from getInstance().
* @param direction Light's direction in world space. Should be a unit vector.
* The default is {0,-1,0}.
*
* @see Builder.direction()
*/
void setDirection(Instance i, const math::float3& direction) noexcept;
//! returns the light's direction in world space
const math::float3& getDirection(Instance i) const noexcept;
/**
* Dynamically updates the light's hue as linear sRGB
*
* @param i Instance of the component obtained from getInstance().
* @param color Color of the light specified in the linear sRGB color-space.
* The default is white {1,1,1}.
*
* @see Builder.color(), getInstance()
*/
void setColor(Instance i, const LinearColor& color) noexcept;
/**
* @param i Instance of the component obtained from getInstance().
* @return the light's color in linear sRGB
*/
const math::float3& getColor(Instance i) const noexcept;
/**
* Dynamically updates the light's intensity. The intensity can be negative.
*
* @param i Instance of the component obtained from getInstance().
* @param intensity This parameter depends on the Light.Type:
* - For directional lights, it specifies the illuminance in *lux*
* (or *lumen/m^2*).
* - For point lights and spot lights, it specifies the luminous power
* in *lumen*.
*
* @see Builder.intensity()
*/
void setIntensity(Instance i, float intensity) noexcept;
/**
* Dynamically updates the light's intensity. The intensity can be negative.
*
* @param i Instance of the component obtained from getInstance().
* @param watts Energy consumed by a lightbulb. It is related to the energy produced
* and ultimately the brightness by the \p efficiency parameter.
* This value is often available on the packaging of commercial
* lightbulbs.
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
*
* Lightbulb type | Efficiency
* ----------------:|-----------:
* Incandescent | 2.2%
* Halogen | 7.0%
* LED | 8.7%
* Fluorescent | 10.7%
*
* @see Builder.intensity(float watts, float efficiency)
*/
void setIntensity(Instance i, float watts, float efficiency) noexcept {
setIntensity(i, watts * 683.0f * efficiency);
}
/**
* Dynamically updates the light's intensity in candela. The intensity can be negative.
*
* @param i Instance of the component obtained from getInstance().
* @param intensity Luminous intensity in *candela*.
*
* @note
* This method is equivalent to calling setIntensity(float intensity) for directional lights
* (Type.DIRECTIONAL or Type.SUN).
*
* @see Builder.intensityCandela(float intensity)
*/
void setIntensityCandela(Instance i, float intensity) noexcept;
/**
* returns the light's luminous intensity in candela.
*
* @param i Instance of the component obtained from getInstance().
*
* @note for Type.FOCUSED_SPOT lights, the returned value depends on the \p outer cone angle.
*
* @return luminous intensity in candela.
*/
float getIntensity(Instance i) const noexcept;
/**
* Set the falloff distance for point lights and spot lights.
*
* @param i Instance of the component obtained from getInstance().
* @param radius falloff distance in world units. Default is 1 meter.
*
* @see Builder.falloff()
*/
void setFalloff(Instance i, float radius) noexcept;
/**
* returns the falloff distance of this light.
* @param i Instance of the component obtained from getInstance().
* @return the falloff distance of this light.
*/
float getFalloff(Instance i) const noexcept;
/**
* Dynamically updates a spot light's cone as angles
*
* @param i Instance of the component obtained from getInstance().
* @param inner inner cone angle in *radians* between 0.00873 and outer
* @param outer outer cone angle in *radians* between 0.00873 and pi/2
*
* @see Builder.spotLightCone()
*/
void setSpotLightCone(Instance i, float inner, float outer) noexcept;
/**
* returns the outer cone angle in *radians* between inner and pi/2.
* @param i Instance of the component obtained from getInstance().
* @return the outer cone angle of this light.
*/
float getSpotLightOuterCone(Instance i) const noexcept;
/**
* returns the inner cone angle in *radians* between 0 and pi/2.
*
* The value is recomputed from the initial values, thus is not precisely
* the same as the one passed to setSpotLightCone() or Builder.spotLightCone().
*
* @param i Instance of the component obtained from getInstance().
* @return the inner cone angle of this light.
*/
float getSpotLightInnerCone(Instance i) const noexcept;
/**
* Dynamically updates the angular radius of a Type.SUN light
*
* The Sun as seen from Earth has an angular size of 0.526° to 0.545°
*
* @param i Instance of the component obtained from getInstance().
* @param angularRadius sun's radius in degrees. Default is 0.545°.
*/
void setSunAngularRadius(Instance i, float angularRadius) noexcept;
/**
* returns the angular radius if the sun in degrees.
* @param i Instance of the component obtained from getInstance().
* @return the angular radius if the sun in degrees.
*/
float getSunAngularRadius(Instance i) const noexcept;
/**
* Dynamically updates the halo radius of a Type.SUN light. The radius
* of the halo is defined as a multiplier of the sun angular radius.
*
* @param i Instance of the component obtained from getInstance().
* @param haloSize radius multiplier. Default is 10.0.
*/
void setSunHaloSize(Instance i, float haloSize) noexcept;
/**
* returns the halo size of a Type.SUN light as a multiplier of the
* sun angular radius.
* @param i Instance of the component obtained from getInstance().
* @return the halo size
*/
float getSunHaloSize(Instance i) const noexcept;
/**
* Dynamically updates the halo falloff of a Type.SUN light. The falloff
* is a dimensionless number used as an exponent.
*
* @param i Instance of the component obtained from getInstance().
* @param haloFalloff halo falloff. Default is 80.0.
*/
void setSunHaloFalloff(Instance i, float haloFalloff) noexcept;
/**
* returns the halo falloff of a Type.SUN light as a dimensionless value.
* @param i Instance of the component obtained from getInstance().
* @return the halo falloff
*/
float getSunHaloFalloff(Instance i) const noexcept;
/**
* returns the shadow-map options for a given light
* @param i Instance of the component obtained from getInstance().
* @return A ShadowOption structure
*/
ShadowOptions const& getShadowOptions(Instance i) const noexcept;
/**
* sets the shadow-map options for a given light
* @param i Instance of the component obtained from getInstance().
* @param options A ShadowOption structure
*/
void setShadowOptions(Instance i, ShadowOptions const& options) noexcept;
/**
* Whether this Light casts shadows (disabled by default)
*
* @param i Instance of the component obtained from getInstance().
* @param shadowCaster Enables or disables casting shadows from this Light.
*
* @warning
* - Only a Type.DIRECTIONAL, Type.SUN, Type.SPOT, or Type.FOCUSED_SPOT light can cast shadows
*/
void setShadowCaster(Instance i, bool shadowCaster) noexcept;
/**
* returns whether this light casts shadows.
* @param i Instance of the component obtained from getInstance().
*/
bool isShadowCaster(Instance i) const noexcept;
/**
* Helper to process all components with a given function
* @tparam F a void(Entity entity, Instance instance)
* @param func a function of type F
*/
template<typename F>
void forEachComponent(F func) noexcept {
utils::Entity const* const pEntity = getEntities();
for (size_t i = 0, c = getComponentCount(); i < c; i++) {
// Instance 0 is the invalid instance
func(pEntity[i], Instance(i + 1));
}
}
};
} // namespace filament
#endif // TNT_FILAMENT_LIGHTMANAGER_H

View File

@@ -0,0 +1,374 @@
/*
* 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_MATERIAL_H
#define TNT_FILAMENT_MATERIAL_H
#include <filament/Color.h>
#include <filament/FilamentAPI.h>
#include <filament/MaterialEnums.h>
#include <filament/MaterialInstance.h>
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <math/mathfwd.h>
#include <stdint.h>
namespace utils {
class CString;
} // namespace utils
namespace filament {
class Texture;
class TextureSampler;
class FEngine;
class FMaterial;
class Engine;
class UTILS_PUBLIC Material : public FilamentAPI {
struct BuilderDetails;
public:
using BlendingMode = BlendingMode;
using Shading = Shading;
using Interpolation = Interpolation;
using VertexDomain = VertexDomain;
using TransparencyMode = TransparencyMode;
using ParameterType = backend::UniformType;
using Precision = backend::Precision;
using SamplerType = backend::SamplerType;
using SamplerFormat = backend::SamplerFormat;
using CullingMode = backend::CullingMode;
using ShaderModel = backend::ShaderModel;
using SubpassType = backend::SubpassType;
/**
* Holds information about a material parameter.
*/
struct ParameterInfo {
//! Name of the parameter.
const char* name;
//! Whether the parameter is a sampler (texture).
bool isSampler;
//! Whether the parameter is a subpass type.
bool isSubpass;
union {
//! Type of the parameter if the parameter is not a sampler.
ParameterType type;
//! Type of the parameter if the parameter is a sampler.
SamplerType samplerType;
//! Type of the parameter if the parameter is a subpass.
SubpassType subpassType;
};
//! Size of the parameter when the parameter is an array.
uint32_t count;
//! Requested precision of the parameter.
Precision precision;
};
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Specifies the material data. The material data is a binary blob produced by
* libfilamat or by matc.
*
* @param payload Pointer to the material data, must stay valid until build() is called.
* @param size Size of the material data pointed to by "payload" in bytes.
*/
Builder& package(const void* payload, size_t size);
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;
/**
* Specialize a constant parameter specified in the material definition with a concrete
* value for this material. Once build() is called, this constant cannot be changed.
* Will throw an exception if the name does not match a constant specified in the
* material definition or if the type provided does not match.
*
* @tparam T The type of constant parameter, either int32_t, float, or bool.
* @param name The name of the constant parameter specified in the material definition, such
* as "myConstant".
* @param nameLength Length in `char` of the name parameter.
* @param value The value to use for the constant parameter, must match the type specified
* in the material definition.
*/
template<typename T, typename = is_supported_constant_parameter_t<T>>
Builder& constant(const char* name, size_t nameLength, T value);
/** inline helper to provide the constant name as a null-terminated C string */
template<typename T, typename = is_supported_constant_parameter_t<T>>
inline Builder& constant(const char* name, T value) {
return constant(name, strlen(name), value);
}
/**
* Creates the Material object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this Material with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Material* build(Engine& engine);
private:
friend class FMaterial;
};
using CompilerPriorityQueue = backend:: CompilerPriorityQueue;
/**
* Asynchronously ensures that a subset of this Material's variants are compiled. After issuing
* several Material::compile() calls in a row, it is recommended to call Engine::flush()
* such that the backend can start the compilation work as soon as possible.
* The provided callback is guaranteed to be called on the main thread after all specified
* variants of the material are compiled. This can take hundreds of milliseconds.
*
* If all the material's variants are already compiled, the callback will be scheduled as
* soon as possible, but this might take a few dozen millisecond, corresponding to how
* many previous frames are enqueued in the backend. This also varies by backend. Therefore,
* it is recommended to only call this method once per material shortly after creation.
*
* If the same variant is scheduled for compilation multiple times, the first scheduling
* takes precedence; later scheduling are ignored.
*
* caveat: A consequence is that if a variant is scheduled on the low priority queue and later
* scheduled again on the high priority queue, the later scheduling is ignored.
* Therefore, the second callback could be called before the variant is compiled.
* However, the first callback, if specified, will trigger as expected.
*
* The callback is guaranteed to be called. If the engine is destroyed while some material
* variants are still compiling or in the queue, these will be discarded and the corresponding
* callback will be called. In that case however the Material pointer passed to the callback
* is guaranteed to be invalid (either because it's been destroyed by the user already, or,
* because it's been cleaned-up by the Engine).
*
* @param priority Which priority queue to use, LOW or HIGH.
* @param variants Variants to include to the compile command.
* @param handler Handler to dispatch the callback or nullptr for the default handler
* @param callback callback called on the main thread when the compilation is done on
* by backend.
*/
void compile(CompilerPriorityQueue priority,
UserVariantFilterMask variants,
backend::CallbackHandler* handler = nullptr,
utils::Invocable<void(Material*)>&& callback = {}) noexcept;
inline void compile(CompilerPriorityQueue priority,
UserVariantFilterBit variants,
backend::CallbackHandler* handler = nullptr,
utils::Invocable<void(Material*)>&& callback = {}) noexcept {
compile(priority, UserVariantFilterMask(variants), handler,
std::forward<utils::Invocable<void(Material*)>>(callback));
}
inline void compile(CompilerPriorityQueue priority,
backend::CallbackHandler* handler = nullptr,
utils::Invocable<void(Material*)>&& callback = {}) noexcept {
compile(priority, UserVariantFilterBit::ALL, handler,
std::forward<utils::Invocable<void(Material*)>>(callback));
}
/**
* Creates a new instance of this material. Material instances should be freed using
* Engine::destroy(const MaterialInstance*).
*
* @param name Optional name to associate with the given material instance. If this is null,
* then the instance inherits the material's name.
*
* @return A pointer to the new instance.
*/
MaterialInstance* createInstance(const char* name = nullptr) const noexcept;
//! Returns the name of this material as a null-terminated string.
const char* getName() const noexcept;
//! Returns the shading model of this material.
Shading getShading() const noexcept;
//! Returns the interpolation mode of this material. This affects how variables are interpolated.
Interpolation getInterpolation() const noexcept;
//! Returns the blending mode of this material.
BlendingMode getBlendingMode() const noexcept;
//! Returns the vertex domain of this material.
VertexDomain getVertexDomain() const noexcept;
//! Returns the material domain of this material.
//! The material domain determines how the material is used.
MaterialDomain getMaterialDomain() const noexcept;
//! Returns the default culling mode of this material.
CullingMode getCullingMode() const noexcept;
//! Returns the transparency mode of this material.
//! This value only makes sense when the blending mode is transparent or fade.
TransparencyMode getTransparencyMode() const noexcept;
//! Indicates whether instances of this material will, by default, write to the color buffer.
bool isColorWriteEnabled() const noexcept;
//! Indicates whether instances of this material will, by default, write to the depth buffer.
bool isDepthWriteEnabled() const noexcept;
//! Indicates whether instances of this material will, by default, use depth testing.
bool isDepthCullingEnabled() const noexcept;
//! Indicates whether this material is double-sided.
bool isDoubleSided() const noexcept;
//! Indicates whether this material uses alpha to coverage.
bool isAlphaToCoverageEnabled() const noexcept;
//! Returns the alpha mask threshold used when the blending mode is set to masked.
float getMaskThreshold() const noexcept;
//! Indicates whether this material uses the shadowing factor as a color multiplier.
//! This values only makes sense when the shading mode is unlit.
bool hasShadowMultiplier() const noexcept;
//! Indicates whether this material has specular anti-aliasing enabled
bool hasSpecularAntiAliasing() const noexcept;
//! Returns the screen-space variance for specular-antialiasing, this value is between 0 and 1.
float getSpecularAntiAliasingVariance() const noexcept;
//! Returns the clamping threshold for specular-antialiasing, this value is between 0 and 1.
float getSpecularAntiAliasingThreshold() const noexcept;
//! Returns the list of vertex attributes required by this material.
AttributeBitset getRequiredAttributes() const noexcept;
//! Returns the refraction mode used by this material.
RefractionMode getRefractionMode() const noexcept;
//! Return the refraction type used by this material.
RefractionType getRefractionType() const noexcept;
//! Returns the reflection mode used by this material.
ReflectionMode getReflectionMode() const noexcept;
/**
* Returns the number of parameters declared by this material.
* The returned value can be 0.
*/
size_t getParameterCount() const noexcept;
/**
* Gets information about this material's parameters.
*
* @param parameters A pointer to a list of ParameterInfo.
* The list must be at least "count" large
* @param count The number of parameters to retrieve. Must be >= 0 and can be > count.
*
* @return The number of parameters written to the parameters pointer.
*/
size_t getParameters(ParameterInfo* parameters, size_t count) const noexcept;
//! Indicates whether a parameter of the given name exists on this material.
bool hasParameter(const char* name) const noexcept;
//! Indicates whether an existing parameter is a sampler or not.
bool isSampler(const char* name) const noexcept;
/**
* Sets the value of the given parameter on this material's default instance.
*
* @param name The name of the material parameter
* @param value The value of the material parameter
*
* @see getDefaultInstance()
*/
template <typename T>
void setDefaultParameter(const char* name, T value) noexcept {
getDefaultInstance()->setParameter(name, value);
}
/**
* Sets a texture and sampler parameters on this material's default instance.
*
* @param name The name of the material texture parameter
* @param texture The texture to set as parameter
* @param sampler The sampler to be used with this texture
*
* @see getDefaultInstance()
*/
void setDefaultParameter(const char* name, Texture const* texture,
TextureSampler const& sampler) noexcept {
getDefaultInstance()->setParameter(name, texture, sampler);
}
/**
* Sets the color of the given parameter on this material's default instance.
*
* @param name The name of the material color parameter
* @param type Whether the color is specified in the linear or sRGB space
* @param color The color as a floating point red, green, blue tuple
*
* @see getDefaultInstance()
*/
void setDefaultParameter(const char* name, RgbType type, math::float3 color) noexcept {
getDefaultInstance()->setParameter(name, type, color);
}
/**
* Sets the color of the given parameter on this material's default instance.
*
* @param name The name of the material color parameter
* @param type Whether the color is specified in the linear or sRGB space
* @param color The color as a floating point red, green, blue, alpha tuple
*
* @see getDefaultInstance()
*/
void setDefaultParameter(const char* name, RgbaType type, math::float4 color) noexcept {
getDefaultInstance()->setParameter(name, type, color);
}
//! Returns this material's default instance.
MaterialInstance* getDefaultInstance() noexcept;
//! Returns this material's default instance.
MaterialInstance const* getDefaultInstance() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_MATERIAL_H

View File

@@ -0,0 +1,97 @@
/*
* 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_MATERIAL_CHUNK_TYPES_H
#define TNT_FILAMAT_MATERIAL_CHUNK_TYPES_H
#include <stdint.h>
#include <utils/compiler.h>
namespace filamat {
// Pack an eight character string into a 64 bit integer.
constexpr inline uint64_t charTo64bitNum(const char str[9]) noexcept {
return
( (static_cast<uint64_t >(str[0]) << 56))
| ((static_cast<uint64_t >(str[1]) << 48) & 0x00FF000000000000U)
| ((static_cast<uint64_t >(str[2]) << 40) & 0x0000FF0000000000U)
| ((static_cast<uint64_t >(str[3]) << 32) & 0x000000FF00000000U)
| ((static_cast<uint64_t >(str[4]) << 24) & 0x00000000FF000000U)
| ((static_cast<uint64_t >(str[5]) << 16) & 0x0000000000FF0000U)
| ((static_cast<uint64_t >(str[6]) << 8) & 0x000000000000FF00U)
| ( static_cast<uint64_t >(str[7]) & 0x00000000000000FFU);
}
enum UTILS_PUBLIC ChunkType : uint64_t {
Unknown = charTo64bitNum("UNKNOWN "),
MaterialUib = charTo64bitNum("MAT_UIB "),
MaterialSib = charTo64bitNum("MAT_SIB "),
MaterialSubpass = charTo64bitNum("MAT_SUB "),
MaterialGlsl = charTo64bitNum("MAT_GLSL"),
MaterialSpirv = charTo64bitNum("MAT_SPIR"),
MaterialMetal = charTo64bitNum("MAT_METL"),
MaterialShaderModels = charTo64bitNum("MAT_SMDL"),
MaterialSamplerBindings = charTo64bitNum("MAT_SAMP"),
MaterialUniformBindings = charTo64bitNum("MAT_UNIF"),
MaterialBindingUniformInfo = charTo64bitNum("MAT_UFRM"),
MaterialAttributeInfo = charTo64bitNum("MAT_ATTR"),
MaterialProperties = charTo64bitNum("MAT_PROP"),
MaterialConstants = charTo64bitNum("MAT_CONS"),
MaterialName = charTo64bitNum("MAT_NAME"),
MaterialVersion = charTo64bitNum("MAT_VERS"),
MaterialCacheId = charTo64bitNum("MAT_UUID"),
MaterialFeatureLevel = charTo64bitNum("MAT_FEAT"),
MaterialShading = charTo64bitNum("MAT_SHAD"),
MaterialBlendingMode = charTo64bitNum("MAT_BLEN"),
MaterialTransparencyMode = charTo64bitNum("MAT_TRMD"),
MaterialMaskThreshold = charTo64bitNum("MAT_THRS"),
MaterialShadowMultiplier = charTo64bitNum("MAT_SHML"),
MaterialSpecularAntiAliasing = charTo64bitNum("MAT_SPAA"),
MaterialSpecularAntiAliasingVariance = charTo64bitNum("MAT_SVAR"),
MaterialSpecularAntiAliasingThreshold = charTo64bitNum("MAT_STHR"),
MaterialClearCoatIorChange = charTo64bitNum("MAT_CIOR"),
MaterialDomain = charTo64bitNum("MAT_DOMN"),
MaterialRefraction = charTo64bitNum("MAT_REFM"),
MaterialRefractionType = charTo64bitNum("MAT_REFT"),
MaterialReflectionMode = charTo64bitNum("MAT_REFL"),
MaterialRequiredAttributes = charTo64bitNum("MAT_REQA"),
MaterialDoubleSidedSet = charTo64bitNum("MAT_DOSS"),
MaterialDoubleSided = charTo64bitNum("MAT_DOSI"),
MaterialColorWrite = charTo64bitNum("MAT_CWRIT"),
MaterialDepthWriteSet = charTo64bitNum("MAT_DEWS"),
MaterialDepthWrite = charTo64bitNum("MAT_DWRIT"),
MaterialDepthTest = charTo64bitNum("MAT_DTEST"),
MaterialInstanced = charTo64bitNum("MAT_INSTA"),
MaterialCullingMode = charTo64bitNum("MAT_CUMO"),
MaterialAlphaToCoverageSet = charTo64bitNum("MAT_A2CS"),
MaterialAlphaToCoverage = charTo64bitNum("MAT_A2CO"),
MaterialHasCustomDepthShader =charTo64bitNum("MAT_CSDP"),
MaterialVertexDomain = charTo64bitNum("MAT_VEDO"),
MaterialInterpolation = charTo64bitNum("MAT_INTR"),
DictionaryText = charTo64bitNum("DIC_TEXT"),
DictionarySpirv = charTo64bitNum("DIC_SPIR"),
};
} // namespace filamat
#endif // TNT_FILAMAT_MATERIAL_CHUNK_TYPES_H

View File

@@ -0,0 +1,254 @@
/*
* 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_MATERIAL_ENUM_H
#define TNT_FILAMENT_MATERIAL_ENUM_H
#include <utils/bitset.h>
#include <utils/BitmaskEnum.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
// update this when a new version of filament wouldn't work with older materials
static constexpr size_t MATERIAL_VERSION = 41;
/**
* Supported shading models
*/
enum class Shading : uint8_t {
UNLIT, //!< no lighting applied, emissive possible
LIT, //!< default, standard lighting
SUBSURFACE, //!< subsurface lighting model
CLOTH, //!< cloth lighting model
SPECULAR_GLOSSINESS, //!< legacy lighting model
};
/**
* Attribute interpolation types in the fragment shader
*/
enum class Interpolation : uint8_t {
SMOOTH, //!< default, smooth interpolation
FLAT //!< flat interpolation
};
/**
* Shader quality, affect some global quality parameters
*/
enum class ShaderQuality : int8_t {
DEFAULT = -1, // LOW on mobile, HIGH on desktop
LOW = 0, // enable optimizations that can slightly affect correctness
NORMAL = 1, // normal quality, correctness honored
HIGH = 2 // higher quality (e.g. better upscaling, etc...)
};
/**
* Supported blending modes
*/
enum class BlendingMode : uint8_t {
//! material is opaque
OPAQUE,
//! material is transparent and color is alpha-pre-multiplied, affects diffuse lighting only
TRANSPARENT,
//! material is additive (e.g.: hologram)
ADD,
//! material is masked (i.e. alpha tested)
MASKED,
/**
* material is transparent and color is alpha-pre-multiplied, affects specular lighting
* when adding more entries, change the size of FRenderer::CommandKey::blending
*/
FADE,
//! material darkens what's behind it
MULTIPLY,
//! material brightens what's behind it
SCREEN,
};
/**
* How transparent objects are handled
*/
enum class TransparencyMode : uint8_t {
//! the transparent object is drawn honoring the raster state
DEFAULT,
/**
* the transparent object is first drawn in the depth buffer,
* then in the color buffer, honoring the culling mode, but ignoring the depth test function
*/
TWO_PASSES_ONE_SIDE,
/**
* the transparent object is drawn twice in the color buffer,
* first with back faces only, then with front faces; the culling
* mode is ignored. Can be combined with two-sided lighting
*/
TWO_PASSES_TWO_SIDES
};
/**
* Supported types of vertex domains.
*/
enum class VertexDomain : uint8_t {
OBJECT, //!< vertices are in object space, default
WORLD, //!< vertices are in world space
VIEW, //!< vertices are in view space
DEVICE //!< vertices are in normalized device space
// when adding more entries, make sure to update VERTEX_DOMAIN_COUNT
};
/**
* Vertex attribute types
*/
enum VertexAttribute : uint8_t {
// Update hasIntegerTarget() in VertexBuffer when adding an attribute that will
// be read as integers in the shaders
POSITION = 0, //!< XYZ position (float3)
TANGENTS = 1, //!< tangent, bitangent and normal, encoded as a quaternion (float4)
COLOR = 2, //!< vertex color (float4)
UV0 = 3, //!< texture coordinates (float2)
UV1 = 4, //!< texture coordinates (float2)
BONE_INDICES = 5, //!< indices of 4 bones, as unsigned integers (uvec4)
BONE_WEIGHTS = 6, //!< weights of the 4 bones (normalized float4)
// -- we have 1 unused slot here --
CUSTOM0 = 8,
CUSTOM1 = 9,
CUSTOM2 = 10,
CUSTOM3 = 11,
CUSTOM4 = 12,
CUSTOM5 = 13,
CUSTOM6 = 14,
CUSTOM7 = 15,
// Aliases for legacy vertex morphing.
// See RenderableManager::Builder::morphing().
MORPH_POSITION_0 = CUSTOM0,
MORPH_POSITION_1 = CUSTOM1,
MORPH_POSITION_2 = CUSTOM2,
MORPH_POSITION_3 = CUSTOM3,
MORPH_TANGENTS_0 = CUSTOM4,
MORPH_TANGENTS_1 = CUSTOM5,
MORPH_TANGENTS_2 = CUSTOM6,
MORPH_TANGENTS_3 = CUSTOM7,
// this is limited by driver::MAX_VERTEX_ATTRIBUTE_COUNT
};
static constexpr size_t MAX_LEGACY_MORPH_TARGETS = 4;
static constexpr size_t MAX_MORPH_TARGETS = 256; // this is limited by filament::CONFIG_MAX_MORPH_TARGET_COUNT
static constexpr size_t MAX_CUSTOM_ATTRIBUTES = 8;
/**
* Material domains
*/
enum class MaterialDomain : uint8_t {
SURFACE = 0, //!< shaders applied to renderables
POST_PROCESS = 1, //!< shaders applied to rendered buffers
COMPUTE = 2, //!< compute shader
};
/**
* Specular occlusion
*/
enum class SpecularAmbientOcclusion : uint8_t {
NONE = 0, //!< no specular occlusion
SIMPLE = 1, //!< simple specular occlusion
BENT_NORMALS = 2, //!< more accurate specular occlusion, requires bent normals
};
/**
* Refraction
*/
enum class RefractionMode : uint8_t {
NONE = 0, //!< no refraction
CUBEMAP = 1, //!< refracted rays go to the ibl cubemap
SCREEN_SPACE = 2, //!< refracted rays go to screen space
};
/**
* Refraction type
*/
enum class RefractionType : uint8_t {
SOLID = 0, //!< refraction through solid objects (e.g. a sphere)
THIN = 1, //!< refraction through thin objects (e.g. window)
};
/**
* Reflection mode
*/
enum class ReflectionMode : uint8_t {
DEFAULT = 0, //! reflections sample from the scene's IBL only
SCREEN_SPACE = 1, //! reflections sample from screen space, and fallback to the scene's IBL
};
// can't really use std::underlying_type<AttributeIndex>::type because the driver takes a uint32_t
using AttributeBitset = utils::bitset32;
static constexpr size_t MATERIAL_PROPERTIES_COUNT = 26;
enum class Property : uint8_t {
BASE_COLOR, //!< float4, all shading models
ROUGHNESS, //!< float, lit shading models only
METALLIC, //!< float, all shading models, except unlit and cloth
REFLECTANCE, //!< float, all shading models, except unlit and cloth
AMBIENT_OCCLUSION, //!< float, lit shading models only, except subsurface and cloth
CLEAR_COAT, //!< float, lit shading models only, except subsurface and cloth
CLEAR_COAT_ROUGHNESS, //!< float, lit shading models only, except subsurface and cloth
CLEAR_COAT_NORMAL, //!< float, lit shading models only, except subsurface and cloth
ANISOTROPY, //!< float, lit shading models only, except subsurface and cloth
ANISOTROPY_DIRECTION, //!< float3, lit shading models only, except subsurface and cloth
THICKNESS, //!< float, subsurface shading model only
SUBSURFACE_POWER, //!< float, subsurface shading model only
SUBSURFACE_COLOR, //!< float3, subsurface and cloth shading models only
SHEEN_COLOR, //!< float3, lit shading models only, except subsurface
SHEEN_ROUGHNESS, //!< float3, lit shading models only, except subsurface and cloth
SPECULAR_COLOR, //!< float3, specular-glossiness shading model only
GLOSSINESS, //!< float, specular-glossiness shading model only
EMISSIVE, //!< float4, all shading models
NORMAL, //!< float3, all shading models only, except unlit
POST_LIGHTING_COLOR, //!< float4, all shading models
CLIP_SPACE_TRANSFORM, //!< mat4, vertex shader only
ABSORPTION, //!< float3, how much light is absorbed by the material
TRANSMISSION, //!< float, how much light is refracted through the material
IOR, //!< float, material's index of refraction
MICRO_THICKNESS, //!< float, thickness of the thin layer
BENT_NORMAL, //!< float3, all shading models only, except unlit
// when adding new Properties, make sure to update MATERIAL_PROPERTIES_COUNT
};
using UserVariantFilterMask = uint32_t;
enum class UserVariantFilterBit : UserVariantFilterMask {
DIRECTIONAL_LIGHTING = 0x01,
DYNAMIC_LIGHTING = 0x02,
SHADOW_RECEIVER = 0x04,
SKINNING = 0x08,
FOG = 0x10,
VSM = 0x20,
SSR = 0x40,
ALL = 0x7F,
};
} // namespace filament
template<> struct utils::EnableBitMaskOperators<filament::UserVariantFilterBit>
: public std::true_type {};
#endif

View File

@@ -0,0 +1,486 @@
/*
* 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_MATERIALINSTANCE_H
#define TNT_FILAMENT_MATERIALINSTANCE_H
#include <filament/FilamentAPI.h>
#include <filament/Color.h>
#include <filament/MaterialEnums.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
namespace filament {
class Material;
class Texture;
class TextureSampler;
class UniformBuffer;
class BufferInterfaceBlock;
class UTILS_PUBLIC MaterialInstance : public FilamentAPI {
template<size_t N>
using StringLiteralHelper = const char[N];
struct StringLiteral {
const char* data;
size_t size;
template<size_t N>
StringLiteral(StringLiteralHelper<N> const& s) noexcept // NOLINT(google-explicit-constructor)
: data(s), size(N - 1) {
}
};
public:
using CullingMode = filament::backend::CullingMode;
using TransparencyMode = filament::TransparencyMode;
using DepthFunc = filament::backend::SamplerCompareFunc;
using StencilCompareFunc = filament::backend::SamplerCompareFunc;
using StencilOperation = filament::backend::StencilOperation;
using StencilFace = filament::backend::StencilFace;
template<typename T>
using is_supported_parameter_t = typename std::enable_if<
std::is_same<float, T>::value ||
std::is_same<int32_t, T>::value ||
std::is_same<uint32_t, T>::value ||
std::is_same<math::int2, T>::value ||
std::is_same<math::int3, T>::value ||
std::is_same<math::int4, T>::value ||
std::is_same<math::uint2, T>::value ||
std::is_same<math::uint3, T>::value ||
std::is_same<math::uint4, T>::value ||
std::is_same<math::float2, T>::value ||
std::is_same<math::float3, T>::value ||
std::is_same<math::float4, T>::value ||
std::is_same<math::mat4f, T>::value ||
// these types are slower as they need a layout conversion
std::is_same<bool, T>::value ||
std::is_same<math::bool2, T>::value ||
std::is_same<math::bool3, T>::value ||
std::is_same<math::bool4, T>::value ||
std::is_same<math::mat3f, T>::value
>::type;
/**
* Creates a new MaterialInstance using another MaterialInstance as a template for initialization.
* The new MaterialInstance is an instance of the same Material of the template instance and
* must be destroyed just like any other MaterialInstance.
*
* @param other A MaterialInstance to use as a template for initializing a new instance
* @param name A name for the new MaterialInstance or nullptr to use the template's name
* @return A new MaterialInstance
*/
static MaterialInstance* duplicate(MaterialInstance const* other, const char* name = nullptr) noexcept;
/**
* @return the Material associated with this instance
*/
Material const* getMaterial() const noexcept;
/**
* @return the name associated with this instance
*/
const char* getName() const noexcept;
/**
* Set a uniform by name
*
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
* @param nameLength Length in `char` of the name parameter.
* @param value Value of the parameter to set.
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
*/
template<typename T, typename = is_supported_parameter_t<T>>
void setParameter(const char* name, size_t nameLength, T const& value);
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(StringLiteral name, T const& value) {
setParameter<T>(name.data, name.size, value);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(const char* name, T const& value) {
setParameter<T>(name, strlen(name), value);
}
/**
* Set a uniform array by name
*
* @param name Name of the parameter array as defined by Material. Cannot be nullptr.
* @param nameLength Length in `char` of the name parameter.
* @param values Array of values to set to the named parameter array.
* @param count Size of the array to set.
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
*/
template<typename T, typename = is_supported_parameter_t<T>>
void setParameter(const char* name, size_t nameLength, const T* values, size_t count);
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(StringLiteral name, const T* values, size_t count) {
setParameter<T>(name.data, name.size, values, count);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(const char* name, const T* values, size_t count) {
setParameter<T>(name, strlen(name), values, count);
}
/**
* Set a texture as the named parameter
*
* Note: Depth textures can't be sampled with a linear filter unless the comparison mode is set
* to COMPARE_TO_TEXTURE.
*
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
* @param nameLength Length in `char` of the name parameter.
* @param texture Non nullptr Texture object pointer.
* @param sampler Sampler parameters.
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
*/
void setParameter(const char* name, size_t nameLength,
Texture const* texture, TextureSampler const& sampler);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name,
Texture const* texture, TextureSampler const& sampler) {
setParameter(name.data, name.size, texture, sampler);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* name,
Texture const* texture, TextureSampler const& sampler) {
setParameter(name, strlen(name), texture, sampler);
}
/**
* Set an RGB color as the named parameter.
* A conversion might occur depending on the specified type
*
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
* @param nameLength Length in `char` of the name parameter.
* @param type Whether the color value is encoded as Linear or sRGB.
* @param color Array of read, green, blue channels values.
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
*/
void setParameter(const char* name, size_t nameLength, RgbType type, math::float3 color);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name, RgbType type, math::float3 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* name, RgbType type, math::float3 color) {
setParameter(name, strlen(name), type, color);
}
/**
* Set an RGBA color as the named parameter.
* A conversion might occur depending on the specified type
*
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
* @param nameLength Length in `char` of the name parameter.
* @param type Whether the color value is encoded as Linear or sRGB/A.
* @param color Array of read, green, blue and alpha channels values.
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
*/
void setParameter(const char* name, size_t nameLength, RgbaType type, math::float4 color);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name, RgbaType type, math::float4 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* name, RgbaType type, math::float4 color) {
setParameter(name, strlen(name), type, color);
}
/**
* Set-up a custom scissor rectangle; by default it is disabled.
*
* The scissor rectangle gets clipped by the View's viewport, in other words, the scissor
* cannot affect fragments outside of the View's Viewport.
*
* Currently the scissor is not compatible with dynamic resolution and should always be
* disabled when dynamic resolution is used.
*
* @param left left coordinate of the scissor box relative to the viewport
* @param bottom bottom coordinate of the scissor box relative to the viewport
* @param width width of the scissor box
* @param height height of the scissor box
*
* @see unsetScissor
* @see View::setViewport
* @see View::setDynamicResolutionOptions
*/
void setScissor(uint32_t left, uint32_t bottom, uint32_t width, uint32_t height) noexcept;
/**
* Returns the scissor rectangle to its default disabled setting.
*
* Currently the scissor is not compatible with dynamic resolution and should always be
* disabled when dynamic resolution is used.
*
* @see View::setDynamicResolutionOptions
*/
void unsetScissor() noexcept;
/**
* Sets a polygon offset that will be applied to all renderables drawn with this material
* instance.
*
* The value of the offset is scale * dz + r * constant, where dz is the change in depth
* relative to the screen area of the triangle, and r is the smallest value that is guaranteed
* to produce a resolvable offset for a given implementation. This offset is added before the
* depth test.
*
* @warning using a polygon offset other than zero has a significant negative performance
* impact, as most implementations have to disable early depth culling. DO NOT USE unless
* absolutely necessary.
*
* @param scale scale factor used to create a variable depth offset for each triangle
* @param constant scale factor used to create a constant depth offset for each triangle
*/
void setPolygonOffset(float scale, float constant) noexcept;
/**
* Overrides the minimum alpha value a fragment must have to not be discarded when the blend
* mode is MASKED. Defaults to 0.4 if it has not been set in the parent Material. The specified
* value should be between 0 and 1 and will be clamped if necessary.
*/
void setMaskThreshold(float threshold) noexcept;
/**
* Gets the minimum alpha value a fragment must have to not be discarded when the blend
* mode is MASKED
*/
float getMaskThreshold() const 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.
*/
void setSpecularAntiAliasingVariance(float variance) noexcept;
/**
* Gets the screen space variance of the filter kernel used when applying specular
* anti-aliasing.
*/
float getSpecularAntiAliasingVariance() const 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.
*/
void setSpecularAntiAliasingThreshold(float threshold) noexcept;
/**
* Gets the clamping threshold used to suppress estimation errors when applying specular
* anti-aliasing.
*/
float getSpecularAntiAliasingThreshold() const noexcept;
/**
* Enables or disables double-sided lighting if the parent Material has double-sided capability,
* otherwise prints a warning. If double-sided lighting is enabled, backface culling is
* automatically disabled.
*/
void setDoubleSided(bool doubleSided) noexcept;
/**
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
* capability.
*/
bool isDoubleSided() const noexcept;
/**
* Specifies how transparent objects should be rendered (default is DEFAULT).
*/
void setTransparencyMode(TransparencyMode mode) noexcept;
/**
* Returns the transparency mode.
*/
TransparencyMode getTransparencyMode() const noexcept;
/**
* Overrides the default triangle culling state that was set on the material.
*/
void setCullingMode(CullingMode culling) noexcept;
/**
* Returns the face culling mode.
*/
CullingMode getCullingMode() const noexcept;
/**
* Overrides the default color-buffer write state that was set on the material.
*/
void setColorWrite(bool enable) noexcept;
/**
* Returns whether color write is enabled.
*/
bool isColorWriteEnabled() const noexcept;
/**
* Overrides the default depth-buffer write state that was set on the material.
*/
void setDepthWrite(bool enable) noexcept;
/**
* Returns whether depth write is enabled.
*/
bool isDepthWriteEnabled() const noexcept;
/**
* Overrides the default depth testing state that was set on the material.
*/
void setDepthCulling(bool enable) noexcept;
/**
* Overrides the default depth function state that was set on the material.
*/
void setDepthFunc(DepthFunc depthFunc) noexcept;
/**
* Returns the depth function state.
*/
DepthFunc getDepthFunc() const noexcept;
/**
* Returns whether depth culling is enabled.
*/
bool isDepthCullingEnabled() const noexcept;
/**
* Overrides the default stencil-buffer write state that was set on the material.
*/
void setStencilWrite(bool enable) noexcept;
/**
* Returns whether stencil write is enabled.
*/
bool isStencilWriteEnabled() const noexcept;
/**
* Sets the stencil comparison function (default is StencilCompareFunc::A).
*
* It's possible to set separate stencil comparison functions; one for front-facing polygons,
* and one for back-facing polygons. The face parameter determines the comparison function(s)
* updated by this call.
*/
void setStencilCompareFunction(StencilCompareFunc func,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the stencil fail operation (default is StencilOperation::KEEP).
*
* The stencil fail operation is performed to update values in the stencil buffer when the
* stencil test fails.
*
* It's possible to set separate stencil fail operations; one for front-facing polygons, and one
* for back-facing polygons. The face parameter determines the stencil fail operation(s) updated
* by this call.
*/
void setStencilOpStencilFail(StencilOperation op,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the depth fail operation (default is StencilOperation::KEEP).
*
* The depth fail operation is performed to update values in the stencil buffer when the depth
* test fails.
*
* It's possible to set separate depth fail operations; one for front-facing polygons, and one
* for back-facing polygons. The face parameter determines the depth fail operation(s) updated
* by this call.
*/
void setStencilOpDepthFail(StencilOperation op,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the depth-stencil pass operation (default is StencilOperation::KEEP).
*
* The depth-stencil pass operation is performed to update values in the stencil buffer when
* both the stencil test and depth test pass.
*
* It's possible to set separate depth-stencil pass operations; one for front-facing polygons,
* and one for back-facing polygons. The face parameter determines the depth-stencil pass
* operation(s) updated by this call.
*/
void setStencilOpDepthStencilPass(StencilOperation op,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the stencil reference value (default is 0).
*
* The stencil reference value is the left-hand side for stencil comparison tests. It's also
* used as the replacement stencil value when StencilOperation is REPLACE.
*
* It's possible to set separate stencil reference values; one for front-facing polygons, and
* one for back-facing polygons. The face parameter determines the reference value(s) updated by
* this call.
*/
void setStencilReferenceValue(uint8_t value,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the stencil read mask (default is 0xFF).
*
* The stencil read mask masks the bits of the values participating in the stencil comparison
* test- both the value read from the stencil buffer and the reference value.
*
* It's possible to set separate stencil read masks; one for front-facing polygons, and one for
* back-facing polygons. The face parameter determines the stencil read mask(s) updated by this
* call.
*/
void setStencilReadMask(uint8_t readMask,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
/**
* Sets the stencil write mask (default is 0xFF).
*
* The stencil write mask masks the bits in the stencil buffer updated by stencil operations.
*
* It's possible to set separate stencil write masks; one for front-facing polygons, and one for
* back-facing polygons. The face parameter determines the stencil write mask(s) updated by this
* call.
*/
void setStencilWriteMask(uint8_t writeMask,
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_MATERIALINSTANCE_H

View File

@@ -0,0 +1,143 @@
/*
* 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_MORPHTARGETBUFFER_H
#define TNT_FILAMENT_MORPHTARGETBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/Engine.h>
#include <math/mathfwd.h>
namespace filament {
/**
* MorphTargetBuffer is used to hold morphing data (positions and tangents).
*
* Both positions and tangents are required.
*
*/
class UTILS_PUBLIC MorphTargetBuffer : public FilamentAPI {
struct BuilderDetails;
public:
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Size of the morph targets in vertex counts.
* @param vertexCount Number of vertex counts the morph targets can hold.
* @return A reference to this Builder for chaining calls.
*/
Builder& vertexCount(size_t vertexCount) noexcept;
/**
* Size of the morph targets in targets.
* @param count Number of targets the morph targets can hold.
* @return A reference to this Builder for chaining calls.
*/
Builder& count(size_t count) noexcept;
/**
* Creates the MorphTargetBuffer object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this MorphTargetBuffer with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
MorphTargetBuffer* build(Engine& engine);
private:
friend class FMorphTargetBuffer;
};
/**
* Updates positions for the given morph target.
*
* This is equivalent to the float4 method, but uses 1.0 for the 4th component.
*
* Both positions and tangents must be provided.
*
* @param engine Reference to the filament::Engine associated with this MorphTargetBuffer.
* @param targetIndex the index of morph target to be updated.
* @param positions pointer to at least "count" positions
* @param count number of float3 vectors in positions
* @param offset offset into the target buffer, expressed as a number of float4 vectors
* @see setTangentsAt
*/
void setPositionsAt(Engine& engine, size_t targetIndex,
math::float3 const* positions, size_t count, size_t offset = 0);
/**
* Updates positions for the given morph target.
*
* Both positions and tangents must be provided.
*
* @param engine Reference to the filament::Engine associated with this MorphTargetBuffer.
* @param targetIndex the index of morph target to be updated.
* @param positions pointer to at least "count" positions
* @param count number of float4 vectors in positions
* @param offset offset into the target buffer, expressed as a number of float4 vectors
* @see setTangentsAt
*/
void setPositionsAt(Engine& engine, size_t targetIndex,
math::float4 const* positions, size_t count, size_t offset = 0);
/**
* Updates tangents for the given morph target.
*
* These quaternions must be represented as signed shorts, where real numbers in the [-1,+1]
* range multiplied by 32767.
*
* @param engine Reference to the filament::Engine associated with this MorphTargetBuffer.
* @param targetIndex the index of morph target to be updated.
* @param tangents pointer to at least "count" tangents
* @param count number of short4 quaternions in tangents
* @param offset offset into the target buffer, expressed as a number of short4 vectors
* @see setPositionsAt
*/
void setTangentsAt(Engine& engine, size_t targetIndex,
math::short4 const* tangents, size_t count, size_t offset = 0);
/**
* Returns the vertex count of this MorphTargetBuffer.
* @return The number of vertices the MorphTargetBuffer holds.
*/
size_t getVertexCount() const noexcept;
/**
* Returns the target count of this MorphTargetBuffer.
* @return The number of targets the MorphTargetBuffer holds.
*/
size_t getCount() const noexcept;
};
} // namespace filament
#endif //TNT_FILAMENT_MORPHTARGETBUFFER_H

View File

@@ -0,0 +1,546 @@
/*
* 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_OPTIONS_H
#define TNT_FILAMENT_OPTIONS_H
#include <filament/Color.h>
#include <stdint.h>
#include <math.h>
namespace filament {
class Texture;
/**
* Generic quality level.
*/
enum class QualityLevel : uint8_t {
LOW,
MEDIUM,
HIGH,
ULTRA
};
enum class BlendMode : uint8_t {
OPAQUE,
TRANSLUCENT
};
/**
* Dynamic resolution can be used to either reach a desired target frame rate
* by lowering the resolution of a View, or to increase the quality when the
* rendering is faster than the target frame rate.
*
* This structure can be used to specify the minimum scale factor used when
* lowering the resolution of a View, and the maximum scale factor used when
* increasing the resolution for higher quality rendering. The scale factors
* can be controlled on each X and Y axis independently. By default, all scale
* factors are set to 1.0.
*
* enabled: enable or disables dynamic resolution on a View
*
* homogeneousScaling: by default the system scales the major axis first. Set this to true
* to force homogeneous scaling.
*
* minScale: the minimum scale in X and Y this View should use
*
* maxScale: the maximum scale in X and Y this View should use
*
* quality: upscaling quality.
* LOW: 1 bilinear tap, Medium: 4 bilinear taps, High: 9 bilinear taps (tent)
*
* \note
* Dynamic resolution is only supported on platforms where the time to render
* a frame can be measured accurately. Dynamic resolution is currently only
* supported on Android.
*
* @see Renderer::FrameRateOptions
*
*/
struct DynamicResolutionOptions {
math::float2 minScale = {0.5f, 0.5f}; //!< minimum scale factors in x and y %codegen_java_float%
math::float2 maxScale = {1.0f, 1.0f}; //!< maximum scale factors in x and y %codegen_java_float%
float sharpness = 0.9f; //!< sharpness when QualityLevel::MEDIUM or higher is used [0 (disabled), 1 (sharpest)]
bool enabled = false; //!< enable or disable dynamic resolution
bool homogeneousScaling = false; //!< set to true to force homogeneous scaling
/**
* Upscaling quality
* LOW: bilinear filtered blit. Fastest, poor quality
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations
* ULTRA: AMD FidelityFX FSR1
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
*
* The default upscaling quality is set to LOW.
*/
QualityLevel quality = QualityLevel::LOW;
};
/**
* Options to control the bloom effect
*
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
*
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* maximum is 12. This value together with resolution influences the spread of the
* blur effect. This value can be silently reduced to accommodate the original
* image size.
*
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 4096. This parameter is
* silently clamped to the minimum and maximum.
* It is highly recommended that this value be smaller than the target resolution
* after dynamic resolution is applied (horizontally and vertically).
*
* strength: how much of the bloom is added to the original image. Between 0 and 1.
*
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
* image (true).
*
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
*
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
* useful for artistic reasons and is usually needed when a dirt texture is used.
*
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
* enabled for the dirt effect to work properly.
*
* dirtStrength: Strength of the dirt texture.
*/
struct BloomOptions {
enum class BlendMode : uint8_t {
ADD, //!< Bloom is modulated by the strength parameter and added to the scene
INTERPOLATE //!< Bloom is interpolated with the scene using the strength parameter
};
Texture* dirt = nullptr; //!< user provided dirt texture %codegen_skip_json% %codegen_skip_javascript%
float dirtStrength = 0.2f; //!< strength of the dirt texture %codegen_skip_json% %codegen_skip_javascript%
float strength = 0.10f; //!< bloom's strength between 0.0 and 1.0
uint32_t resolution = 360; //!< resolution of vertical axis (2^levels to 2048)
float anamorphism = 1.0f; //!< bloom x/y aspect-ratio (1/32 to 32)
uint8_t levels = 6; //!< number of blur levels (3 to 11)
BlendMode blendMode = BlendMode::ADD; //!< how the bloom effect is applied
bool threshold = true; //!< whether to threshold the source
bool enabled = false; //!< enable or disable bloom
float highlight = 1000.0f; //!< limit highlights to this value before bloom [10, +inf]
bool lensFlare = false; //!< enable screen-space lens flare
bool starburst = true; //!< enable starburst effect on lens flare
float chromaticAberration = 0.005f; //!< amount of chromatic aberration
uint8_t ghostCount = 4; //!< number of flare "ghosts"
float ghostSpacing = 0.6f; //!< spacing of the ghost in screen units [0, 1[
float ghostThreshold = 10.0f; //!< hdr threshold for the ghosts
float haloThickness = 0.1f; //!< thickness of halo in vertical screen units, 0 to disable
float haloRadius = 0.4f; //!< radius of halo in vertical screen units [0, 0.5]
float haloThreshold = 10.0f; //!< hdr threshold for the halo
};
/**
* Options to control large-scale fog in the scene
*/
struct FogOptions {
/**
* Distance in world units [m] from the camera to where the fog starts ( >= 0.0 )
*/
float distance = 0.0f;
/**
* Distance in world units [m] after which the fog calculation is disabled.
* This can be used to exclude the skybox, which is desirable if it already contains clouds or
* fog. The default value is +infinity which applies the fog to everything.
*
* Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
* plane distance and projection used though).
*/
float cutOffDistance = INFINITY;
/**
* fog's maximum opacity between 0 and 1
*/
float maximumOpacity = 1.0f;
/**
* Fog's floor in world units [m]. This sets the "sea level".
*/
float height = 0.0f;
/**
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
* factor 2.78 (e) change in fog density.
*
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
* faster computations.
*/
float heightFalloff = 1.0f;
/**
* Fog's color is used for ambient light in-scattering, a good value is
* to use the average of the ambient light, possibly tinted towards blue
* for outdoors environments. Color component's values should be between 0 and 1, values
* above one are allowed but could create a non energy-conservative fog (this is dependant
* on the IBL's intensity as well).
*
* We assume that our fog has no absorption and therefore all the light it scatters out
* becomes ambient light in-scattering and has lost all directionality, i.e.: scattering is
* isotropic. This somewhat simulates Rayleigh scattering.
*
* This value is used as a tint instead, when fogColorFromIbl is enabled.
*
* @see fogColorFromIbl
*/
LinearColor color = { 1.0f, 1.0f, 1.0f };
/**
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
* the incoming light to 37% of its original value.
*
* Note: The extinction factor is related to the fog density, it's usually some constant K times
* the density at sea level (more specifically at fog height). The constant K depends on
* the composition of the fog/atmosphere.
*
* For historical reason this parameter is called `density`.
*/
float density = 0.1f;
/**
* Distance in world units [m] from the camera where the Sun in-scattering starts.
*/
float inScatteringStart = 0.0f;
/**
* Very inaccurately simulates the Sun's in-scattering. That is, the light from the sun that
* is scattered (by the fog) towards the camera.
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
* Smaller values result is a larger scattering size.
*/
float inScatteringSize = -1.0f;
/**
* The fog color will be sampled from the IBL in the view direction and tinted by `color`.
* Depending on the scene this can produce very convincing results.
*
* This simulates a more anisotropic phase-function.
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
*
* @see skyColor
*/
bool fogColorFromIbl = false;
/**
* skyTexture must be a mipmapped cubemap. When provided, the fog color will be sampled from
* this texture, higher resolution mip levels will be used for objects at the far clip plane,
* and lower resolution mip levels for objects closer to the camera. The skyTexture should
* typically be heavily blurred; a typical way to produce this texture is to blur the base
* level with a strong gaussian filter or even an irradiance filter and then generate mip
* levels as usual. How blurred the base level is somewhat of an artistic decision.
*
* This simulates a more anisotropic phase-function.
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
*
* @see Texture
* @see fogColorFromIbl
*/
Texture* skyColor = nullptr; //!< %codegen_skip_json% %codegen_skip_javascript%
/**
* Enable or disable large-scale fog
*/
bool enabled = false;
};
/**
* Options to control Depth of Field (DoF) effect in the scene.
*
* cocScale can be used to set the depth of field blur independently from the camera
* aperture, e.g. for artistic reasons. This can be achieved by setting:
* cocScale = cameraAperture / desiredDoFAperture
*
* @see Camera
*/
struct DepthOfFieldOptions {
enum class Filter : uint8_t {
NONE,
UNUSED,
MEDIAN
};
float cocScale = 1.0f; //!< circle of confusion scale factor (amount of blur)
float maxApertureDiameter = 0.01f; //!< maximum aperture diameter in meters (zero to disable rotation)
bool enabled = false; //!< enable or disable depth of field effect
Filter filter = Filter::MEDIAN; //!< filter to use for filling gaps in the kernel
bool nativeResolution = false; //!< perform DoF processing at native resolution
/**
* Number of of rings used by the gather kernels. The number of rings affects quality
* and performance. The actual number of sample per pixel is defined
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:
* 3 rings : 25 ( 5x 5 grid)
* 4 rings : 49 ( 7x 7 grid)
* 5 rings : 81 ( 9x 9 grid)
* 17 rings : 1089 (33x33 grid)
*
* With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.
*
* Usually all three settings below are set to the same value, however, it is often
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
* Fast tiles are regions of the screen where every pixels have a similar
* circle-of-confusion radius.
*
* A value of 0 means default, which is 5 on desktop and 3 on mobile.
*
* @{
*/
uint8_t foregroundRingCount = 0; //!< number of kernel rings for foreground tiles
uint8_t backgroundRingCount = 0; //!< number of kernel rings for background tiles
uint8_t fastGatherRingCount = 0; //!< number of kernel rings for fast tiles
/** @}*/
/**
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
*/
uint16_t maxForegroundCOC = 0;
/**
* maximum circle-of-confusion in pixels for the background, must be in [0, 32] range.
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
*/
uint16_t maxBackgroundCOC = 0;
};
/**
* Options to control the vignetting effect.
*/
struct VignetteOptions {
float midPoint = 0.5f; //!< high values restrict the vignette closer to the corners, between 0 and 1
float roundness = 0.5f; //!< controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5), to a circle (1.0)
float feather = 0.5f; //!< softening amount of the vignette effect, between 0 and 1
LinearColorA color = {0.0f, 0.0f, 0.0f, 1.0f}; //!< color of the vignette effect, alpha is currently ignored
bool enabled = false; //!< enables or disables the vignette effect
};
/**
* Structure used to set the precision of the color buffer and related quality settings.
*
* @see setRenderQuality, getRenderQuality
*/
struct RenderQuality {
/**
* Sets the quality of the HDR color buffer.
*
* A quality of HIGH or ULTRA means using an RGB16F or RGBA16F color buffer. This means
* colors in the LDR range (0..1) have a 10 bit precision. A quality of LOW or MEDIUM means
* using an R11G11B10F opaque color buffer or an RGBA16F transparent color buffer. With
* R11G11B10F colors in the LDR range have a precision of either 6 bits (red and green
* channels) or 5 bits (blue channel).
*/
QualityLevel hdrColorBuffer = QualityLevel::HIGH;
};
/**
* Options for screen space Ambient Occlusion (SSAO) and Screen Space Cone Tracing (SSCT)
* @see setAmbientOcclusionOptions()
*/
struct AmbientOcclusionOptions {
float radius = 0.3f; //!< Ambient Occlusion radius in meters, between 0 and ~10.
float power = 1.0f; //!< Controls ambient occlusion's contrast. Must be positive.
float bias = 0.0005f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
float resolution = 0.5f;//!< How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0.
float intensity = 1.0f; //!< Strength of the Ambient Occlusion effect.
float bilateralThreshold = 0.05f; //!< depth distance that constitute an edge for filtering
QualityLevel quality = QualityLevel::LOW; //!< affects # of samples used for AO.
QualityLevel lowPassFilter = QualityLevel::MEDIUM; //!< affects AO smoothness
QualityLevel upsampling = QualityLevel::LOW; //!< affects AO buffer upsampling quality
bool enabled = false; //!< enables or disables screen-space ambient occlusion
bool bentNormals = false; //!< enables bent normals computation from AO, and specular AO
float minHorizonAngleRad = 0.0f; //!< min angle in radian to consider
/**
* Screen Space Cone Tracing (SSCT) options
* Ambient shadows from dominant light
*/
struct Ssct {
float lightConeRad = 1.0f; //!< full cone angle in radian, between 0 and pi/2
float shadowDistance = 0.3f; //!< how far shadows can be cast
float contactDistanceMax = 1.0f; //!< max distance for contact
float intensity = 0.8f; //!< intensity
math::float3 lightDirection = { 0, -1, 0 }; //!< light direction
float depthBias = 0.01f; //!< depth bias in world units (mitigate self shadowing)
float depthSlopeBias = 0.01f; //!< depth slope bias (mitigate self shadowing)
uint8_t sampleCount = 4; //!< tracing sample count, between 1 and 255
uint8_t rayCount = 1; //!< # of rays to trace, between 1 and 255
bool enabled = false; //!< enables or disables SSCT
};
Ssct ssct; // %codegen_skip_javascript% %codegen_java_flatten%
};
/**
* Options for Temporal Multi-Sample Anti-aliasing (MSAA)
* @see setMultiSampleAntiAliasingOptions()
*/
struct MultiSampleAntiAliasingOptions {
bool enabled = false; //!< enables or disables msaa
/**
* sampleCount number of samples to use for multi-sampled anti-aliasing.\n
* 0: treated as 1
* 1: no anti-aliasing
* n: sample count. Effective sample could be different depending on the
* GPU capabilities.
*/
uint8_t sampleCount = 4;
/**
* custom resolve improves quality for HDR scenes, but may impact performance.
*/
bool customResolve = false;
};
/**
* Options for Temporal Anti-aliasing (TAA)
* @see setTemporalAntiAliasingOptions()
*/
struct TemporalAntiAliasingOptions {
float filterWidth = 1.0f; //!< reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother)
float feedback = 0.04f; //!< history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
bool enabled = false; //!< enables or disables temporal anti-aliasing
};
/**
* Options for Screen-space Reflections.
* @see setScreenSpaceReflectionsOptions()
*/
struct ScreenSpaceReflectionsOptions {
float thickness = 0.1f; //!< ray thickness, in world units
float bias = 0.01f; //!< bias, in world units, to prevent self-intersections
float maxDistance = 3.0f; //!< maximum distance, in world units, to raycast
float stride = 2.0f; //!< stride, in texels, for samples along the ray.
bool enabled = false;
};
/**
* Options for the screen-space guard band.
* A guard band can be enabled to avoid some artifacts towards the edge of the screen when
* using screen-space effects such as SSAO. Enabling the guard band reduces performance slightly.
* Currently the guard band can only be enabled or disabled.
*/
struct GuardBandOptions {
bool enabled = false;
};
/**
* List of available post-processing anti-aliasing techniques.
* @see setAntiAliasing, getAntiAliasing, setSampleCount
*/
enum class AntiAliasing : uint8_t {
NONE, //!< no anti aliasing performed as part of post-processing
FXAA //!< FXAA is a low-quality but very efficient type of anti-aliasing. (default).
};
/**
* List of available post-processing dithering techniques.
*/
enum class Dithering : uint8_t {
NONE, //!< No dithering
TEMPORAL //!< Temporal dithering (default)
};
/**
* List of available shadow mapping techniques.
* @see setShadowType
*/
enum class ShadowType : uint8_t {
PCF, //!< percentage-closer filtered shadows (default)
VSM, //!< variance shadows
DPCF, //!< PCF with contact hardening simulation
PCSS //!< PCF with soft shadows and contact hardening
};
/**
* View-level options for VSM Shadowing.
* @see setVsmShadowOptions()
* @warning This API is still experimental and subject to change.
*/
struct VsmShadowOptions {
/**
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
* than 0, mipmaps will automatically be generated each frame for all lights.
*
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
*/
uint8_t anisotropy = 0;
/**
* Whether to generate mipmaps for all VSM shadow maps.
*/
bool mipmapping = false;
/**
* The number of MSAA samples to use when rendering VSM shadow maps.
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
* off MSAA.
* Higher values may not be available depending on the underlying hardware.
*/
uint8_t msaaSamples = 1;
/**
* Whether to use a 32-bits or 16-bits texture format for VSM shadow maps. 32-bits
* precision is rarely needed, but it does reduces light leaks as well as "fading"
* of the shadows in some situations. Setting highPrecision to true for a single
* shadow map will double the memory usage of all shadow maps.
*/
bool highPrecision = false;
/**
* VSM minimum variance scale, must be positive.
*/
float minVarianceScale = 0.5f;
/**
* VSM light bleeding reduction amount, between 0 and 1.
*/
float lightBleedReduction = 0.15f;
};
/**
* View-level options for DPCF and PCSS Shadowing.
* @see setSoftShadowOptions()
* @warning This API is still experimental and subject to change.
*/
struct SoftShadowOptions {
/**
* Globally scales the penumbra of all DPCF and PCSS shadows
* Acceptable values are greater than 0
*/
float penumbraScale = 1.0f;
/**
* Globally scales the computed penumbra ratio of all DPCF and PCSS shadows.
* This effectively controls the strength of contact hardening effect and is useful for
* artistic purposes. Higher values make the shadows become softer faster.
* Acceptable values are equal to or greater than 1.
*/
float penumbraRatioScale = 1.0f;
};
} // namespace filament
#endif //TNT_FILAMENT_OPTIONS_H

View File

@@ -0,0 +1,187 @@
/*
* 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_RENDERTARGET_H
#define TNT_FILAMENT_RENDERTARGET_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/TargetBufferInfo.h>
#include <stddef.h>
namespace filament {
class FRenderTarget;
class Engine;
class Texture;
/**
* An offscreen render target that can be associated with a View and contains
* weak references to a set of attached Texture objects.
*
* RenderTarget is intended to be used with the View's post-processing disabled for the most part.
* especially when a DEPTH attachment is also used (see Builder::texture()).
*
* Custom RenderTarget are ultimately intended to render into textures that might be used during
* the main render pass.
*
* Clients are responsible for the lifetime of all associated Texture attachments.
*
* @see View
*/
class UTILS_PUBLIC RenderTarget : public FilamentAPI {
struct BuilderDetails;
public:
using CubemapFace = backend::TextureCubemapFace;
/** Minimum number of color attachment supported */
static constexpr uint8_t MIN_SUPPORTED_COLOR_ATTACHMENTS_COUNT =
backend::MRT::MIN_SUPPORTED_RENDER_TARGET_COUNT;
/** Maximum number of color attachment supported */
static constexpr uint8_t MAX_SUPPORTED_COLOR_ATTACHMENTS_COUNT =
backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
/**
* Attachment identifiers
*/
enum class AttachmentPoint : uint8_t {
COLOR0 = 0, //!< identifies the 1st color attachment
COLOR1 = 1, //!< identifies the 2nd color attachment
COLOR2 = 2, //!< identifies the 3rd color attachment
COLOR3 = 3, //!< identifies the 4th color attachment
COLOR4 = 4, //!< identifies the 5th color attachment
COLOR5 = 5, //!< identifies the 6th color attachment
COLOR6 = 6, //!< identifies the 7th color attachment
COLOR7 = 7, //!< identifies the 8th color attachment
DEPTH = MAX_SUPPORTED_COLOR_ATTACHMENTS_COUNT, //!< identifies the depth attachment
COLOR = COLOR0, //!< identifies the 1st color attachment
};
//! Use Builder to construct a RenderTarget object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Sets a texture to a given attachment point.
*
* When using a DEPTH attachment, it is important to always disable post-processing
* in the View. Failing to do so will cause the DEPTH attachment to be ignored in most
* cases.
*
* When the intention is to keep the content of the DEPTH attachment after rendering,
* Usage::SAMPLEABLE must be set on the DEPTH attachment, otherwise the content of the
* DEPTH buffer may be discarded.
*
* @param attachment The attachment point of the texture.
* @param texture The associated texture object.
* @return A reference to this Builder for chaining calls.
*/
Builder& texture(AttachmentPoint attachment, Texture* texture) noexcept;
/**
* Sets the mipmap level for a given attachment point.
*
* @param attachment The attachment point of the texture.
* @param level The associated mipmap level, 0 by default.
* @return A reference to this Builder for chaining calls.
*/
Builder& mipLevel(AttachmentPoint attachment, uint8_t level) noexcept;
/**
* Sets the cubemap face for a given attachment point.
*
* @param attachment The attachment point.
* @param face The associated cubemap face.
* @return A reference to this Builder for chaining calls.
*/
Builder& face(AttachmentPoint attachment, CubemapFace face) noexcept;
/**
* Sets the layer for a given attachment point (for 3D textures).
*
* @param attachment The attachment point.
* @param layer The associated cubemap layer.
* @return A reference to this Builder for chaining calls.
*/
Builder& layer(AttachmentPoint attachment, uint32_t layer) noexcept;
/**
* Creates the RenderTarget object and returns a pointer to it.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*/
RenderTarget* build(Engine& engine);
private:
friend class FRenderTarget;
};
/**
* Gets the texture set on the given attachment point
* @param attachment Attachment point
* @return A Texture object or nullptr if no texture is set for this attachment point
*/
Texture* getTexture(AttachmentPoint attachment) const noexcept;
/**
* Returns the mipmap level set on the given attachment point
* @param attachment Attachment point
* @return the mipmap level set on the given attachment point
*/
uint8_t getMipLevel(AttachmentPoint attachment) const noexcept;
/**
* Returns the face of a cubemap set on the given attachment point
* @param attachment Attachment point
* @return A cubemap face identifier. This is only relevant if the attachment's texture is
* a cubemap.
*/
CubemapFace getFace(AttachmentPoint attachment) const noexcept;
/**
* Returns the texture-layer set on the given attachment point
* @param attachment Attachment point
* @return A texture layer. This is only relevant if the attachment's texture is a 3D texture.
*/
uint32_t getLayer(AttachmentPoint attachment) const noexcept;
/**
* Returns the number of color attachments usable by this instance of Engine. This method is
* guaranteed to return at least MIN_SUPPORTED_COLOR_ATTACHMENTS_COUNT and at most
* MAX_SUPPORTED_COLOR_ATTACHMENTS_COUNT.
* @return Number of color attachments usable in a render target.
*/
uint8_t getSupportedColorAttachmentsCount() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_RENDERTARGET_H

View File

@@ -0,0 +1,810 @@
/*
* 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_RENDERABLEMANAGER_H
#define TNT_FILAMENT_RENDERABLEMANAGER_H
#include <filament/Box.h>
#include <filament/FilamentAPI.h>
#include <filament/MaterialEnums.h>
#include <filament/MorphTargetBuffer.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/EntityInstance.h>
#include <math/mathfwd.h>
#include <type_traits>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
class BufferObject;
class Engine;
class IndexBuffer;
class MaterialInstance;
class Renderer;
class SkinningBuffer;
class VertexBuffer;
class Texture;
class InstanceBuffer;
class FEngine;
class FRenderPrimitive;
class FRenderableManager;
/**
* Factory and manager for \em renderables, which are entities that can be drawn.
*
* Renderables are bundles of \em primitives, each of which has its own geometry and material. All
* primitives in a particular renderable share a set of rendering attributes, such as whether they
* cast shadows or use vertex skinning.
*
* Usage example:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* auto renderable = utils::EntityManager::get().create();
*
* RenderableManager::Builder(1)
* .boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
* .material(0, matInstance)
* .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertBuffer, indBuffer, 0, 3)
* .receiveShadows(false)
* .build(engine, renderable);
*
* scene->addEntity(renderable);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To modify the state of an existing renderable, clients should first use RenderableManager
* to get a temporary handle called an \em instance. The instance can then be used to get or set
* the renderable's state. Please note that instances are ephemeral; clients should store entities,
* not instances.
*
* - For details about constructing renderables, see RenderableManager::Builder.
* - To associate a 4x4 transform with an entity, see TransformManager.
* - To associate a human-readable label with an entity, see utils::NameComponentManager.
*/
class UTILS_PUBLIC RenderableManager : public FilamentAPI {
struct BuilderDetails;
public:
using Instance = utils::EntityInstance<RenderableManager>;
using PrimitiveType = backend::PrimitiveType;
/**
* Checks if the given entity already has a renderable component.
*/
bool hasComponent(utils::Entity e) const noexcept;
/**
* Gets a temporary handle that can be used to access the renderable state.
*
* @return Non-zero handle if the entity has a renderable component, 0 otherwise.
*/
Instance getInstance(utils::Entity e) const noexcept;
/**
* The transformation associated with a skinning joint.
*
* Clients can specify bones either using this quat-vec3 pair, or by using 4x4 matrices.
*/
struct Bone {
math::quatf unitQuaternion = { 1.f, 0.f, 0.f, 0.f };
math::float3 translation = { 0.f, 0.f, 0.f };
float reserved = 0;
};
/**
* Adds renderable components to entities using a builder pattern.
*/
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
enum Result { Error = -1, Success = 0 };
/**
* Default render channel
* @see Builder::channel()
*/
static constexpr uint8_t DEFAULT_CHANNEL = 2u;
/**
* Creates a builder for renderable components.
*
* @param count the number of primitives that will be supplied to the builder
*
* Note that builders typically do not have a long lifetime since clients should discard
* them after calling build(). For a usage example, see RenderableManager.
*/
explicit Builder(size_t count) noexcept;
/*! \cond PRIVATE */
Builder(Builder const& rhs) = delete;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder& rhs) = delete;
Builder& operator=(Builder&& rhs) noexcept;
/*! \endcond */
/**
* Specifies the geometry data for a primitive.
*
* Filament primitives must have an associated VertexBuffer and IndexBuffer. Typically, each
* primitive is specified with a pair of daisy-chained calls: \c geometry(...) and \c
* material(...).
*
* @param index zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param type specifies the topology of the primitive (e.g., \c RenderableManager::PrimitiveType::TRIANGLES)
* @param vertices specifies the vertex buffer, which in turn specifies a set of attributes
* @param indices specifies the index buffer (either u16 or u32)
* @param offset specifies where in the index buffer to start reading (expressed as a number of indices)
* @param minIndex specifies the minimum index contained in the index buffer
* @param maxIndex specifies the maximum index contained in the index buffer
* @param count number of indices to read (for triangles, this should be a multiple of 3)
*/
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices, size_t offset, size_t minIndex, size_t maxIndex, size_t count) noexcept;
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices, size_t offset, size_t count) noexcept; //!< \overload
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices) noexcept; //!< \overload
/**
* Binds a material instance to the specified primitive.
*
* If no material is specified for a given primitive, Filament will fall back to a basic
* default material.
*
* The MaterialInstance's material must have a feature level equal or lower to the engine's
* selected feature level.
*
* @param index zero-based index of the primitive, must be less than the count passed to
* Builder constructor
* @param materialInstance the material to bind
*
* @see Engine::setActiveFeatureLevel
*/
Builder& material(size_t index, MaterialInstance const* materialInstance) noexcept;
/**
* The axis-aligned bounding box of the renderable.
*
* This is an object-space AABB used for frustum culling. For skinning and morphing, this
* should encompass all possible vertex positions. It is mandatory unless culling is
* disabled for the renderable.
*
* \see computeAABB()
*/
Builder& boundingBox(const Box& axisAlignedBoundingBox) noexcept;
/**
* Sets bits in a visibility mask. By default, this is 0x1.
*
* This feature provides a simple mechanism for hiding and showing groups of renderables
* in a Scene. See View::setVisibleLayers().
*
* For example, to set bit 1 and reset bits 0 and 2 while leaving all other bits unaffected,
* do: `builder.layerMask(7, 2)`.
*
* To change this at run time, see RenderableManager::setLayerMask.
*
* @param select the set of bits to affect
* @param values the replacement values for the affected bits
*/
Builder& layerMask(uint8_t select, uint8_t values) noexcept;
/**
* Provides coarse-grained control over draw order.
*
* In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using \em priority.
* The priority is applied separately for opaque and translucent objects, that is, opaque
* objects are always drawn before translucent objects regardless of the priority.
*
* For example, this could be used to draw a semitransparent HUD on top of everything,
* without using a separate View. Note that priority is completely orthogonal to
* Builder::layerMask, which merely controls visibility.
*
* The Skybox always using the lowest priority, so it's drawn last, which may improve
* performance.
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see Builder::blendOrder()
* @see Builder::channel()
* @see RenderableManager::setPriority()
* @see RenderableManager::setBlendOrderAt()
*/
Builder& priority(uint8_t priority) noexcept;
/**
* Set the channel this renderable is associated to. There can be 4 channels.
* All renderables in a given channel are rendered together, regardless of anything else.
* They are sorted as usual within a channel.
* Channels work similarly to priorities, except that they enforce the strongest ordering.
*
* Channels 0 and 1 may not have render primitives using a material with `refractionType`
* set to `screenspace`.
*
* @param channel clamped to the range [0..3], defaults to 2.
*
* @return Builder reference for chaining calls.
*
* @see Builder::blendOrder()
* @see Builder::priority()
* @see RenderableManager::setBlendOrderAt()
*/
Builder& channel(uint8_t channel) noexcept;
/**
* Controls frustum culling, true by default.
*
* \note Do not confuse frustum culling with backface culling. The latter is controlled via
* the material.
*/
Builder& culling(bool enable) noexcept;
/**
* Enables or disables a light channel. Light channel 0 is enabled by default.
*
* @param channel Light channel to enable or disable, between 0 and 7.
* @param enable Whether to enable or disable the light channel.
*/
Builder& lightChannel(unsigned int channel, bool enable = true) noexcept;
/**
* Controls if this renderable casts shadows, false by default.
*
* If the View's shadow type is set to ShadowType::VSM, castShadows should only be disabled
* if either is true:
* - receiveShadows is also disabled
* - the object is guaranteed to not cast shadows on itself or other objects (for example,
* a ground plane)
*/
Builder& castShadows(bool enable) noexcept;
/**
* Controls if this renderable receives shadows, true by default.
*/
Builder& receiveShadows(bool enable) noexcept;
/**
* Controls if this renderable uses screen-space contact shadows. This is more
* expensive but can improve the quality of shadows, especially in large scenes.
* (off by default).
*/
Builder& screenSpaceContactShadows(bool enable) noexcept;
/**
* Allows bones to be swapped out and shared using SkinningBuffer.
*
* If skinning buffer mode is enabled, clients must call setSkinningBuffer() rather than
* setBones(). This allows sharing of data between renderables.
*
* @param enabled If true, enables buffer object mode. False by default.
*/
Builder& enableSkinningBuffers(bool enabled = true) noexcept;
/**
* Controls if this renderable is affected by the large-scale fog.
* @param enabled If true, enables large-scale fog on this object. Disables it otherwise.
* True by default.
* @return A reference to this Builder for chaining calls.
*/
Builder& fog(bool enabled = true) noexcept;
/**
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
*
* Skinning Buffer mode must be enabled.
*
* Each vertex can be affected by up to 4 bones simultaneously. The attached
* VertexBuffer must provide data in the \c BONE_INDICES slot (uvec4) and the
* \c BONE_WEIGHTS slot (float4).
*
* See also RenderableManager::setSkinningBuffer() or SkinningBuffer::setBones(),
* which can be called on a per-frame basis to advance the animation.
*
* @param skinningBuffer nullptr to disable, otherwise the SkinningBuffer to use
* @param count 0 to disable, otherwise the number of bone transforms (up to 255)
* @param offset offset in the SkinningBuffer
*/
Builder& skinning(SkinningBuffer* skinningBuffer, size_t count, size_t offset) noexcept;
/**
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
*
* Skinning Buffer mode must be disabled.
*
* Each vertex can be affected by up to 4 bones simultaneously. The attached
* VertexBuffer must provide data in the \c BONE_INDICES slot (uvec4) and the
* \c BONE_WEIGHTS slot (float4).
*
* See also RenderableManager::setBones(), which can be called on a per-frame basis
* to advance the animation.
*
* @param boneCount 0 to disable, otherwise the number of bone transforms (up to 255)
* @param transforms the initial set of transforms (one for each bone)
*/
Builder& skinning(size_t boneCount, math::mat4f const* transforms) noexcept;
Builder& skinning(size_t boneCount, Bone const* bones) noexcept; //!< \overload
Builder& skinning(size_t boneCount) noexcept; //!< \overload
/**
* Controls if the renderable has vertex morphing targets, zero by default. This is
* required to enable GPU morphing.
*
* Filament supports two morphing modes: standard (default) and legacy.
*
* For standard morphing, A MorphTargetBuffer must be created and provided via
* RenderableManager::setMorphTargetBufferAt(). Standard morphing supports up to
* \c CONFIG_MAX_MORPH_TARGET_COUNT morph targets.
*
* For legacy morphing, the attached VertexBuffer must provide data in the
* appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc). Legacy morphing only
* supports up to 4 morph targets and will be deprecated in the future. Legacy morphing must
* be enabled on the material definition: either via the legacyMorphing material attribute
* or by calling filamat::MaterialBuilder::useLegacyMorphing().
*
* See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis
* to advance the animation.
*/
Builder& morphing(size_t targetCount) noexcept;
/**
* Specifies the morph target buffer for a primitive.
*
* The morph target buffer must have an associated renderable and geometry. Two conditions
* must be met:
* 1. The number of morph targets in the buffer must equal the renderable's morph target
* count.
* 2. The vertex count of each morph target must equal the geometry's vertex count.
*
* @param level the level of detail (lod), only 0 can be specified
* @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param morphTargetBuffer specifies the morph target buffer
* @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices)
* @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3)
*/
Builder& morphing(uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer, size_t offset, size_t count) noexcept;
inline Builder& morphing(uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer) noexcept;
/**
* Sets the drawing order for blended primitives. The drawing order is either global or
* local (default) to this Renderable. In either case, the Renderable priority takes
* precedence.
*
* @param primitiveIndex the primitive of interest
* @param order draw order number (0 by default). Only the lowest 15 bits are used.
*
* @return Builder reference for chaining calls.
*
* @see globalBlendOrderEnabled
*/
Builder& blendOrder(size_t primitiveIndex, uint16_t order) noexcept;
/**
* Sets whether the blend order is global or local to this Renderable (by default).
*
* @param primitiveIndex the primitive of interest
* @param enabled true for global, false for local blend ordering.
*
* @return Builder reference for chaining calls.
*
* @see blendOrder
*/
Builder& globalBlendOrderEnabled(size_t primitiveIndex, bool enabled) noexcept;
/**
* Specifies the number of draw instances of this renderable. The default is 1 instance and
* the maximum number of instances allowed is 32767. 0 is invalid.
*
* All instances are culled using the same bounding box, so care must be taken to make
* sure all instances render inside the specified bounding box.
*
* The material must set its `instanced` parameter to `true` in order to use
* getInstanceIndex() in the vertex or fragment shader to get the instance index and
* possibly adjust the position or transform.
*
* @param instanceCount the number of instances silently clamped between 1 and 32767.
*/
Builder& instances(size_t instanceCount) noexcept;
/**
* Specifies the number of draw instances of this renderable and an \c InstanceBuffer
* containing their local transforms. The default is 1 instance and the maximum number of
* instances allowed when supplying transforms is given by
* \c Engine::getMaxAutomaticInstances (64 on most platforms). 0 is invalid. The
* \c InstanceBuffer must not be destroyed before this renderable.
*
* All instances are culled using the same bounding box, so care must be taken to make
* sure all instances render inside the specified bounding box.
*
* The material must set its `instanced` parameter to `true` in order to use
* \c getInstanceIndex() in the vertex or fragment shader to get the instance index.
*
* Only the \c VERTEX_DOMAIN_OBJECT vertex domain is supported.
*
* The local transforms of each instance can be updated with
* \c InstanceBuffer::setLocalTransforms.
*
* \see InstanceBuffer
* \see instances(size_t, * math::mat4f const*)
* @param instanceCount the number of instances, silently clamped between 1 and
* the result of Engine::getMaxAutomaticInstances().
* @param instanceBuffer an InstanceBuffer containing at least instanceCount transforms
*/
Builder& instances(size_t instanceCount, InstanceBuffer* instanceBuffer) noexcept;
/**
* Adds the Renderable component to an entity.
*
* @param engine Reference to the filament::Engine to associate this Renderable with.
* @param entity Entity to add the Renderable component to.
* @return Success if the component was created successfully, Error otherwise.
*
* If exceptions are disabled and an error occurs, this function is a no-op.
* Success can be checked by looking at the return value.
*
* If this component already exists on the given entity and the construction is successful,
* it is first destroyed as if destroy(utils::Entity e) was called. In case of error,
* the existing component is unmodified.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Result build(Engine& engine, utils::Entity entity);
private:
friend class FEngine;
friend class FRenderPrimitive;
friend class FRenderableManager;
struct Entry {
VertexBuffer* vertices = nullptr;
IndexBuffer* indices = nullptr;
size_t offset = 0;
size_t minIndex = 0;
size_t maxIndex = 0;
size_t count = 0;
MaterialInstance const* materialInstance = nullptr;
PrimitiveType type = PrimitiveType::TRIANGLES;
uint16_t blendOrder = 0;
bool globalBlendOrderEnabled = false;
struct {
MorphTargetBuffer* buffer = nullptr;
size_t offset = 0;
size_t count = 0;
} morphing;
};
};
/**
* Destroys the renderable component in the given entity.
*/
void destroy(utils::Entity e) noexcept;
/**
* Changes the bounding box used for frustum culling.
*
* \see Builder::boundingBox()
* \see RenderableManager::getAxisAlignedBoundingBox()
*/
void setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept;
/**
* Changes the visibility bits.
*
* \see Builder::layerMask()
* \see View::setVisibleLayers().
* \see RenderableManager::getLayerMask()
*/
void setLayerMask(Instance instance, uint8_t select, uint8_t values) noexcept;
/**
* Changes the coarse-level draw ordering.
*
* \see Builder::priority().
*/
void setPriority(Instance instance, uint8_t priority) noexcept;
/**
* Changes the channel a renderable is associated to.
*
* \see Builder::channel().
*/
void setChannel(Instance instance, uint8_t channel) noexcept;
/**
* Changes whether or not frustum culling is on.
*
* \see Builder::culling()
*/
void setCulling(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the large-scale fog is applied to this renderable
* @see Builder::fog()
*/
void setFogEnabled(Instance instance, bool enable) noexcept;
/**
* Returns whether large-scale fog is enabled for this renderable.
* @return True if fog is enabled for this renderable.
* @see Builder::fog()
*/
bool getFogEnabled(Instance instance) const noexcept;
/**
* Enables or disables a light channel.
* Light channel 0 is enabled by default.
*
* \see Builder::lightChannel()
*/
void setLightChannel(Instance instance, unsigned int channel, bool enable) noexcept;
/**
* Returns whether a light channel is enabled on a specified renderable.
* @param instance Instance of the component obtained from getInstance().
* @param channel Light channel to query
* @return true if the light channel is enabled, false otherwise
*/
bool getLightChannel(Instance instance, unsigned int channel) const noexcept;
/**
* Changes whether or not the renderable casts shadows.
*
* \see Builder::castShadows()
*/
void setCastShadows(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the renderable can receive shadows.
*
* \see Builder::receiveShadows()
*/
void setReceiveShadows(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the renderable can use screen-space contact shadows.
*
* \see Builder::screenSpaceContactShadows()
*/
void setScreenSpaceContactShadows(Instance instance, bool enable) noexcept;
/**
* Checks if the renderable can cast shadows.
*
* \see Builder::castShadows().
*/
bool isShadowCaster(Instance instance) const noexcept;
/**
* Checks if the renderable can receive shadows.
*
* \see Builder::receiveShadows().
*/
bool isShadowReceiver(Instance instance) const noexcept;
/**
* Updates the bone transforms in the range [offset, offset + boneCount).
* The bones must be pre-allocated using Builder::skinning().
*/
void setBones(Instance instance, Bone const* transforms, size_t boneCount = 1, size_t offset = 0);
void setBones(Instance instance, math::mat4f const* transforms, size_t boneCount = 1, size_t offset = 0); //!< \overload
/**
* Associates a region of a SkinningBuffer to a renderable instance
*
* Note: due to hardware limitations offset + 256 must be smaller or equal to
* skinningBuffer->getBoneCount()
*
* @param instance Instance of the component obtained from getInstance().
* @param skinningBuffer skinning buffer to associate to the instance
* @param count Size of the region in bones, must be smaller or equal to 256.
* @param offset Start offset of the region in bones
*/
void setSkinningBuffer(Instance instance, SkinningBuffer* skinningBuffer,
size_t count, size_t offset);
/**
* Updates the vertex morphing weights on a renderable, all zeroes by default.
*
* The renderable must be built with morphing enabled, see Builder::morphing(). In legacy
* morphing mode, only the first 4 weights are considered.
*
* @param instance Instance of the component obtained from getInstance().
* @param weights Pointer to morph target weights to be update.
* @param count Number of morph target weights.
* @param offset Index of the first morph target weight to set at instance.
*/
void setMorphWeights(Instance instance,
float const* weights, size_t count, size_t offset = 0);
/**
* Associates a MorphTargetBuffer to the given primitive.
*/
void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer, size_t offset, size_t count);
/**
* Utility method to change a MorphTargetBuffer to the given primitive
*/
inline void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer);
/**
* Get a MorphTargetBuffer to the given primitive or null if it doesn't exist.
*/
MorphTargetBuffer* getMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex) const noexcept;
/**
* Gets the number of morphing in the given entity.
*/
size_t getMorphTargetCount(Instance instance) const noexcept;
/**
* Gets the bounding box used for frustum culling.
*
* \see Builder::boundingBox()
* \see RenderableManager::setAxisAlignedBoundingBox()
*/
const Box& getAxisAlignedBoundingBox(Instance instance) const noexcept;
/**
* Get the visibility bits.
*
* \see Builder::layerMask()
* \see View::setVisibleLayers().
* \see RenderableManager::getLayerMask()
*/
uint8_t getLayerMask(Instance instance) const noexcept;
/**
* Gets the immutable number of primitives in the given renderable.
*/
size_t getPrimitiveCount(Instance instance) const noexcept;
/**
* Changes the material instance binding for the given primitive.
*
* The MaterialInstance's material must have a feature level equal or lower to the engine's
* selected feature level.
*
* @exception utils::PreConditionPanic if the engine doesn't support the material's
* feature level.
*
* @see Builder::material()
* @see Engine::setActiveFeatureLevel
*/
void setMaterialInstanceAt(Instance instance,
size_t primitiveIndex, MaterialInstance const* materialInstance);
/**
* Retrieves the material instance that is bound to the given primitive.
*/
MaterialInstance* getMaterialInstanceAt(Instance instance, size_t primitiveIndex) const noexcept;
/**
* Changes the geometry for the given primitive.
*
* \see Builder::geometry()
*/
void setGeometryAt(Instance instance, size_t primitiveIndex,
PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices,
size_t offset, size_t count) noexcept;
/**
* Changes the drawing order for blended primitives. The drawing order is either global or
* local (default) to this Renderable. In either case, the Renderable priority takes precedence.
*
* @param instance the renderable of interest
* @param primitiveIndex the primitive of interest
* @param order draw order number (0 by default). Only the lowest 15 bits are used.
*
* @see Builder::blendOrder(), setGlobalBlendOrderEnabledAt()
*/
void setBlendOrderAt(Instance instance, size_t primitiveIndex, uint16_t order) noexcept;
/**
* Changes whether the blend order is global or local to this Renderable (by default).
*
* @param instance the renderable of interest
* @param primitiveIndex the primitive of interest
* @param enabled true for global, false for local blend ordering.
*
* @see Builder::globalBlendOrderEnabled(), setBlendOrderAt()
*/
void setGlobalBlendOrderEnabledAt(Instance instance, size_t primitiveIndex, bool enabled) noexcept;
/**
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
*/
AttributeBitset getEnabledAttributesAt(Instance instance, size_t primitiveIndex) const noexcept;
/*! \cond PRIVATE */
template<typename T>
struct is_supported_vector_type {
using type = typename std::enable_if<
std::is_same<math::float4, T>::value ||
std::is_same<math::half4, T>::value ||
std::is_same<math::float3, T>::value ||
std::is_same<math::half3, T>::value
>::type;
};
template<typename T>
struct is_supported_index_type {
using type = typename std::enable_if<
std::is_same<uint16_t, T>::value ||
std::is_same<uint32_t, T>::value
>::type;
};
/*! \endcond */
/**
* Utility method that computes the axis-aligned bounding box from a set of vertices.
*
* - The index type must be \c uint16_t or \c uint32_t.
* - The vertex type must be \c float4, \c half4, \c float3, or \c half3.
* - For 4-component vertices, the w component is ignored (implicitly replaced with 1.0).
*/
template<typename VECTOR, typename INDEX,
typename = typename is_supported_vector_type<VECTOR>::type,
typename = typename is_supported_index_type<INDEX>::type>
static Box computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride = sizeof(VECTOR)) noexcept;
};
RenderableManager::Builder& RenderableManager::Builder::morphing(uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer) noexcept {
return morphing(level, primitiveIndex, morphTargetBuffer, 0,
morphTargetBuffer->getVertexCount());
}
void RenderableManager::setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex,
MorphTargetBuffer* morphTargetBuffer) {
setMorphTargetBufferAt(instance, level, primitiveIndex, morphTargetBuffer, 0,
morphTargetBuffer->getVertexCount());
}
template<typename VECTOR, typename INDEX, typename, typename>
Box RenderableManager::computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride) noexcept {
math::float3 bmin(std::numeric_limits<float>::max());
math::float3 bmax(std::numeric_limits<float>::lowest());
for (size_t i = 0; i < count; ++i) {
VECTOR const* p = reinterpret_cast<VECTOR const*>(
(char const*)vertices + indices[i] * stride);
const math::float3 v(p->x, p->y, p->z);
bmin = min(bmin, v);
bmax = max(bmax, v);
}
return Box().set(bmin, bmax);
}
} // namespace filament
#endif // TNT_FILAMENT_RENDERABLEMANAGER_H

View File

@@ -0,0 +1,580 @@
/*
* 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_RENDERER_H
#define TNT_FILAMENT_RENDERER_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <backend/PresentCallable.h>
#include <backend/DriverEnums.h>
#include <math/vec4.h>
#include <stdint.h>
namespace filament {
class Engine;
class RenderTarget;
class SwapChain;
class View;
class Viewport;
namespace backend {
class PixelBufferDescriptor;
} // namespace backend
/**
* A Renderer instance represents an operating system's window.
*
* Typically, applications create a Renderer per window. The Renderer generates drawing commands
* for the render thread and manages frame latency.
*
* A Renderer generates drawing commands from a View, itself containing a Scene description.
*
* Creation and Destruction
* ========================
*
* A Renderer is created using Engine.createRenderer() and destroyed using
* Engine.destroy(const Renderer*).
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Renderer.h>
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
*
* Renderer* renderer = engine->createRenderer();
* engine->destroy(&renderer);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @see Engine, View
*/
class UTILS_PUBLIC Renderer : public FilamentAPI {
public:
/**
* Use DisplayInfo to set important Display properties. This is used to achieve correct
* frame pacing and dynamic resolution scaling.
*/
struct DisplayInfo {
// refresh-rate of the display in Hz. set to 0 for offscreen or turn off frame-pacing.
float refreshRate = 60.0f;
UTILS_DEPRECATED uint64_t presentationDeadlineNanos = 0;
UTILS_DEPRECATED uint64_t vsyncOffsetNanos = 0;
};
/**
* Use FrameRateOptions to set the desired frame rate and control how quickly the system
* reacts to GPU load changes.
*
* interval: desired frame interval in multiple of the refresh period, set in DisplayInfo
* (as 1 / DisplayInfo::refreshRate)
*
* The parameters below are relevant when some Views are using dynamic resolution scaling:
*
* headRoomRatio: additional headroom for the GPU as a ratio of the targetFrameTime.
* Useful for taking into account constant costs like post-processing or
* GPU drivers on different platforms.
* history: History size. higher values, tend to filter more (clamped to 31)
* scaleRate: rate at which the gpu load is adjusted to reach the target frame rate
* This value can be computed as 1 / N, where N is the number of frames
* needed to reach 64% of the target scale factor.
* Higher values make the dynamic resolution react faster.
*
* @see View::DynamicResolutionOptions
* @see Renderer::DisplayInfo
*
*/
struct FrameRateOptions {
float headRoomRatio = 0.0f; //!< additional headroom for the GPU
float scaleRate = 1.0f / 8.0f; //!< rate at which the system reacts to load changes
uint8_t history = 15; //!< history size
uint8_t interval = 1; //!< desired frame interval in unit of 1.0 / DisplayInfo::refreshRate
};
/**
* ClearOptions are used at the beginning of a frame to clear or retain the SwapChain content.
*/
struct ClearOptions {
/**
* Color (sRGB linear) to use to clear the RenderTarget (typically the SwapChain).
*
* The RenderTarget is cleared using this color, which won't be tone-mapped since
* tone-mapping is part of View rendering (this is not).
*
* When a View is rendered, there are 3 scenarios to consider:
* - Pixels rendered by the View replace the clear color (or blend with it in
* `BlendMode::TRANSLUCENT` mode).
*
* - With blending mode set to `BlendMode::TRANSLUCENT`, Pixels untouched by the View
* are considered fulling transparent and let the clear color show through.
*
* - With blending mode set to `BlendMode::OPAQUE`, Pixels untouched by the View
* are set to the clear color. However, because it is now used in the context of a View,
* it will go through the post-processing stage, which includes tone-mapping.
*
* For consistency, it is recommended to always use a Skybox to clear an opaque View's
* background, or to use black or fully-transparent (i.e. {0,0,0,0}) as the clear color.
*/
math::float4 clearColor = {};
/** Value to clear the stencil buffer */
uint8_t clearStencil = 0u;
/**
* Whether the SwapChain should be cleared using the clearColor. Use this if translucent
* View will be drawn, for instance.
*/
bool clear = false;
/**
* Whether the SwapChain content should be discarded. clear implies discard. Set this
* to false (along with clear to false as well) if the SwapChain already has content that
* needs to be preserved
*/
bool discard = true;
};
/**
* Information about the display this Renderer is associated to. This information is needed
* to accurately compute dynamic-resolution scaling and for frame-pacing.
*/
void setDisplayInfo(const DisplayInfo& info) noexcept;
/**
* Set options controlling the desired frame-rate.
*/
void setFrameRateOptions(FrameRateOptions const& options) noexcept;
/**
* Set ClearOptions which are used at the beginning of a frame to clear or retain the
* SwapChain content.
*/
void setClearOptions(const ClearOptions& options);
/**
* Get the Engine that created this Renderer.
*
* @return A pointer to the Engine instance this Renderer is associated to.
*/
Engine* getEngine() noexcept;
/**
* Get the Engine that created this Renderer.
*
* @return A constant pointer to the Engine instance this Renderer is associated to.
*/
inline Engine const* getEngine() const noexcept {
return const_cast<Renderer *>(this)->getEngine();
}
/**
* Flags used to configure the behavior of copyFrame().
*
* @see
* copyFrame()
*/
using CopyFrameFlag = uint32_t;
/**
* Indicates that the dstSwapChain passed into copyFrame() should be
* committed after the frame has been copied.
*
* @see
* copyFrame()
*/
static constexpr CopyFrameFlag COMMIT = 0x1;
/**
* Indicates that the presentation time should be set on the dstSwapChain
* passed into copyFrame to the monotonic clock time when the frame is
* copied.
*
* @see
* copyFrame()
*/
static constexpr CopyFrameFlag SET_PRESENTATION_TIME = 0x2;
/**
* Indicates that the dstSwapChain passed into copyFrame() should be
* cleared to black before the frame is copied into the specified viewport.
*
* @see
* copyFrame()
*/
static constexpr CopyFrameFlag CLEAR = 0x4;
/**
* Set-up a frame for this Renderer.
*
* beginFrame() manages frame pacing, and returns whether or not a frame should be drawn. The
* goal of this is to skip frames when the GPU falls behind in order to keep the frame
* latency low.
*
* If a given frame takes too much time in the GPU, the CPU will get ahead of the GPU. The
* display will draw the same frame twice producing a stutter. At this point, the CPU is
* ahead of the GPU and depending on how many frames are buffered, latency increases.
*
* beginFrame() attempts to detect this situation and returns false in that case, indicating
* to the caller to skip the current frame.
*
* When beginFrame() returns true, it is mandatory to render the frame and call endFrame().
* However, when beginFrame() returns false, the caller has the choice to either skip the
* frame and not call endFrame(), or proceed as though true was returned.
*
* @param vsyncSteadyClockTimeNano The time in nanosecond of when the current frame started,
* or 0 if unknown. This value should be the timestamp of
* the last h/w vsync. It is expressed in the
* std::chrono::steady_clock time base.
* @param swapChain A pointer to the SwapChain instance to use.
*
* @return
* *false* the current frame should be skipped,
* *true* the current frame must be drawn and endFrame() must be called.
*
* @remark
* When skipping a frame, the whole frame is canceled, and endFrame() must not be called.
*
* @note
* All calls to render() must happen *after* beginFrame().
*
* @see
* endFrame()
*/
bool beginFrame(SwapChain* swapChain,
uint64_t vsyncSteadyClockTimeNano = 0u);
/**
* Set the time at which the frame must be presented to the display.
*
* This must be called between beginFrame() and endFrame().
*
* @param monotonic_clock_ns the time in nanoseconds corresponding to the system monotonic up-time clock.
* the presentation time is typically set in the middle of the period
* of interest. The presentation time cannot be too far in the
* future because it is limited by how many buffers are available in
* the display sub-system. Typically it is set to 1 or 2 vsync periods
* away.
*/
void setPresentationTime(int64_t monotonic_clock_ns);
/**
* Render a View into this renderer's window.
*
* This is filament main rendering method, most of the CPU-side heavy lifting is performed
* here. render() main function is to generate render commands which are asynchronously
* executed by the Engine's render thread.
*
* render() generates commands for each of the following stages:
*
* 1. Shadow map passes, if needed.
* 2. Depth pre-pass.
* 3. Color pass.
* 4. Post-processing pass.
*
* A typical render loop looks like this:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Renderer.h>
* #include <filament/View.h>
* using namespace filament;
*
* void renderLoop(Renderer* renderer, SwapChain* swapChain) {
* do {
* // typically we wait for VSYNC and user input events
* if (renderer->beginFrame(swapChain)) {
* renderer->render(mView);
* renderer->endFrame();
* }
* } while (!quit());
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*
* @param view A pointer to the view to render.
*
* @attention
* render() must be called *after* beginFrame() and *before* endFrame().
*
* @note
* render() must be called from the Engine's main thread (or external synchronization
* must be provided). In particular, calls to render() on different Renderer instances
* **must** be synchronized.
*
* @remark
* render() perform potentially heavy computations and cannot be multi-threaded. However,
* internally, render() is highly multi-threaded to both improve performance in mitigate
* the call's latency.
*
* @remark
* render() is typically called once per frame (but not necessarily).
*
* @see
* beginFrame(), endFrame(), View
*
*/
void render(View const* view);
/**
* Copy the currently rendered view to the indicated swap chain, using the
* indicated source and destination rectangle.
*
* @param dstSwapChain The swap chain into which the frame should be copied.
* @param dstViewport The destination rectangle in which to draw the view.
* @param srcViewport The source rectangle to be copied.
* @param flags One or more CopyFrameFlag behavior configuration flags.
*
* @remark
* copyFrame() should be called after a frame is rendered using render()
* but before endFrame() is called.
*/
void copyFrame(SwapChain* dstSwapChain, Viewport const& dstViewport,
Viewport const& srcViewport, uint32_t flags = 0);
/**
* Reads back the content of the SwapChain associated with this Renderer.
*
* @param xoffset Left offset of the sub-region to read back.
* @param yoffset Bottom offset of the sub-region to read back.
* @param width Width of the sub-region to read back.
* @param height Height of the sub-region to read back.
* @param buffer Client-side buffer where the read-back will be written.
*
* The following formats are always supported:
* - PixelBufferDescriptor::PixelDataFormat::RGBA
* - PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER
*
* The following types are always supported:
* - PixelBufferDescriptor::PixelDataType::UBYTE
* - PixelBufferDescriptor::PixelDataType::UINT
* - PixelBufferDescriptor::PixelDataType::INT
* - PixelBufferDescriptor::PixelDataType::FLOAT
*
* Other combinations of format/type may be supported. If a combination is
* not supported, this operation may fail silently. Use a DEBUG build
* to get some logs about the failure.
*
*
* Framebuffer as seen on User buffer (PixelBufferDescriptor&)
* screen
*
* +--------------------+
* | | .stride .alignment
* | | ----------------------->-->
* | | O----------------------+--+ low addresses
* | | | | | |
* | w | | | .top | |
* | <---------> | | V | |
* | +---------+ | | +---------+ | |
* | | ^ | | ======> | | | | |
* | x | h| | | |.left| | | |
* +------>| v | | +---->| | | |
* | +.........+ | | +.........+ | |
* | ^ | | | |
* | y | | +----------------------+--+ high addresses
* O------------+-------+
*
*
* readPixels() must be called within a frame, meaning after beginFrame() and before endFrame().
* Typically, readPixels() will be called after render().
*
* After issuing this method, the callback associated with `buffer` will be invoked on the
* main thread, indicating that the read-back has completed. Typically, this will happen
* after multiple calls to beginFrame(), render(), endFrame().
*
* It is also possible to use a Fence to wait for the read-back.
*
* @remark
* readPixels() is intended for debugging and testing. It will impact performance significantly.
*
*/
void readPixels(uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
backend::PixelBufferDescriptor&& buffer);
/**
* Finishes the current frame and schedules it for display.
*
* endFrame() schedules the current frame to be displayed on the Renderer's window.
*
* @note
* All calls to render() must happen *before* endFrame(). endFrame() must be called if
* beginFrame() returned true, otherwise, endFrame() must not be called unless the caller
* ignored beginFrame()'s return value.
*
* @see
* beginFrame()
*/
void endFrame();
/**
* Reads back the content of the provided RenderTarget.
*
* @param renderTarget RenderTarget to read back from.
* @param xoffset Left offset of the sub-region to read back.
* @param yoffset Bottom offset of the sub-region to read back.
* @param width Width of the sub-region to read back.
* @param height Height of the sub-region to read back.
* @param buffer Client-side buffer where the read-back will be written.
*
* The following formats are always supported:
* - PixelBufferDescriptor::PixelDataFormat::RGBA
* - PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER
*
* The following types are always supported:
* - PixelBufferDescriptor::PixelDataType::UBYTE
* - PixelBufferDescriptor::PixelDataType::UINT
* - PixelBufferDescriptor::PixelDataType::INT
* - PixelBufferDescriptor::PixelDataType::FLOAT
*
* Other combinations of format/type may be supported. If a combination is
* not supported, this operation may fail silently. Use a DEBUG build
* to get some logs about the failure.
*
*
* Framebuffer as seen on User buffer (PixelBufferDescriptor&)
* screen
*
* +--------------------+
* | | .stride .alignment
* | | ----------------------->-->
* | | O----------------------+--+ low addresses
* | | | | | |
* | w | | | .top | |
* | <---------> | | V | |
* | +---------+ | | +---------+ | |
* | | ^ | | ======> | | | | |
* | x | h| | | |.left| | | |
* +------>| v | | +---->| | | |
* | +.........+ | | +.........+ | |
* | ^ | | | |
* | y | | +----------------------+--+ high addresses
* O------------+-------+
*
*
* Typically readPixels() will be called after render() and before endFrame().
*
* After issuing this method, the callback associated with `buffer` will be invoked on the
* main thread, indicating that the read-back has completed. Typically, this will happen
* after multiple calls to beginFrame(), render(), endFrame().
*
* It is also possible to use a Fence to wait for the read-back.
*
* OpenGL only: if issuing a readPixels on a RenderTarget backed by a Texture that had data
* uploaded to it via setImage, the data returned from readPixels will be y-flipped with respect
* to the setImage call.
*
* @remark
* readPixels() is intended for debugging and testing. It will impact performance significantly.
*
*/
void readPixels(RenderTarget* renderTarget,
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
backend::PixelBufferDescriptor&& buffer);
/**
* Render a standalone View into its associated RenderTarget
*
* This call is mostly equivalent to calling render(View*) inside a
* beginFrame / endFrame block, but incurs less overhead. It can be used
* as a poor man's compute API.
*
* @param view A pointer to the view to render. This View must have a RenderTarget associated
* to it.
*
* @attention
* renderStandaloneView() must be called outside of beginFrame() / endFrame().
*
* @note
* renderStandaloneView() must be called from the Engine's main thread
* (or external synchronization must be provided). In particular, calls to
* renderStandaloneView() on different Renderer instances **must** be synchronized.
*
* @remark
* renderStandaloneView() perform potentially heavy computations and cannot be multi-threaded.
* However, internally, renderStandaloneView() is highly multi-threaded to both improve
* performance in mitigate the call's latency.
*/
void renderStandaloneView(View const* view);
/**
* Returns the time in second of the last call to beginFrame(). This value is constant for all
* views rendered during a frame. The epoch is set with resetUserTime().
*
* In materials, this value can be queried using `vec4 getUserTime()`. The value returned
* is a highp vec4 encoded as follows:
*
* time.x = (float)Renderer.getUserTime();
* time.y = Renderer.getUserTime() - time.x;
*
* It follows that the following invariants are true:
*
* (double)time.x + (double)time.y == Renderer.getUserTime()
* time.x == (float)Renderer.getUserTime()
*
* This encoding allows the shader code to perform high precision (i.e. double) time
* calculations when needed despite the lack of double precision in the shader, for e.g.:
*
* To compute (double)time * vertex in the material, use the following construct:
*
* vec3 result = time.x * vertex + time.y * vertex;
*
*
* Most of the time, high precision computations are not required, but be aware that the
* precision of time.x rapidly diminishes as time passes:
*
* time | precision
* --------+----------
* 16.7s | us
* 4h39 | ms
* 77h | 1/60s
*
*
* In other words, it only possible to get microsecond accuracy for about 16s or millisecond
* accuracy for just under 5h.
*
* This problem can be mitigated by calling resetUserTime(), or using high precision time as
* described above.
*
* @return The time is seconds since resetUserTime() was last called.
*
* @see
* resetUserTime()
*/
double getUserTime() const;
/**
* Sets the user time epoch to now, i.e. resets the user time to zero.
*
* Use this method used to keep the precision of time high in materials, in practice it should
* be called at least when the application is paused, e.g. Activity.onPause() in Android.
*
* @see
* getUserTime()
*/
void resetUserTime();
};
} // namespace filament
#endif // TNT_FILAMENT_RENDERER_H

View File

@@ -0,0 +1,175 @@
/*
* 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_SCENE_H
#define TNT_FILAMENT_SCENE_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
class IndirectLight;
class Skybox;
/**
* A Scene is a flat container of Renderable and Light instances.
*
* A Scene doesn't provide a hierarchy of Renderable objects, i.e.: it's not a scene-graph.
* However, it manages the list of objects to render and the list of lights. Renderable
* and Light objects can be added or removed from a Scene at any time.
*
* A Renderable *must* be added to a Scene in order to be rendered, and the Scene must be
* provided to a View.
*
*
* Creation and Destruction
* ========================
*
* A Scene is created using Engine.createScene() and destroyed using
* Engine.destroy(const Scene*).
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <filament/Scene.h>
* #include <filament/Engine.h>
* using namespace filament;
*
* Engine* engine = Engine::create();
*
* Scene* scene = engine->createScene();
* engine->destroy(&scene);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @see View, Renderable, Light
*/
class UTILS_PUBLIC Scene : public FilamentAPI {
public:
/**
* Sets the Skybox.
*
* The Skybox is drawn last and covers all pixels not touched by geometry.
*
* @param skybox The Skybox to use to fill untouched pixels, or nullptr to unset the Skybox.
*/
void setSkybox(Skybox* skybox) noexcept;
/**
* Returns the Skybox associated with the Scene.
*
* @return The associated Skybox, or nullptr if there is none.
*/
Skybox* getSkybox() const noexcept;
/**
* Set the IndirectLight to use when rendering the Scene.
*
* Currently, a Scene may only have a single IndirectLight. This call replaces the current
* IndirectLight.
*
* @param ibl The IndirectLight to use when rendering the Scene or nullptr to unset.
* @see getIndirectLight
*/
void setIndirectLight(IndirectLight* ibl) noexcept;
/**
* Get the IndirectLight or nullptr if none is set.
*
* @return the the IndirectLight or nullptr if none is set
* @see setIndirectLight
*/
IndirectLight* getIndirectLight() const noexcept;
/**
* Adds an Entity to the Scene.
*
* @param entity The entity is ignored if it doesn't have a Renderable or Light component.
*
* \attention
* A given Entity object can only be added once to a Scene.
*
*/
void addEntity(utils::Entity entity);
/**
* Adds a list of entities to the Scene.
*
* @param entities Array containing entities to add to the scene.
* @param count Size of the entity array.
*/
void addEntities(const utils::Entity* entities, size_t count);
/**
* Removes the Renderable from the Scene.
*
* @param entity The Entity to remove from the Scene. If the specified
* \p entity doesn't exist, this call is ignored.
*/
void remove(utils::Entity entity);
/**
* Removes a list of entities to the Scene.
*
* This is equivalent to calling remove in a loop.
* If any of the specified entities do not exist in the scene, they are skipped.
*
* @param entities Array containing entities to remove from the scene.
* @param count Size of the entity array.
*/
void removeEntities(const utils::Entity* entities, size_t count);
/**
* Returns the number of Renderable objects in the Scene.
*
* @return number of Renderable objects in the Scene.
*/
size_t getRenderableCount() const noexcept;
/**
* Returns the total number of Light objects in the Scene.
*
* @return The total number of Light objects in the Scene.
*/
size_t getLightCount() const noexcept;
/**
* Returns true if the given entity is in the Scene.
*
* @return Whether the given entity is in the Scene.
*/
bool hasEntity(utils::Entity entity) const noexcept;
/**
* Invokes user functor on each entity in the scene.
*
* It is not allowed to add or remove an entity from the scene within the functor.
*
* @param functor User provided functor called for each entity in the scene
*/
void forEach(utils::Invocable<void(utils::Entity entity)>&& functor) const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_SCENE_H

View File

@@ -0,0 +1,122 @@
/*
* 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_SKINNINGBUFFER_H
#define TNT_FILAMENT_SKINNINGBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/RenderableManager.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stddef.h>
namespace filament {
/**
* SkinningBuffer is used to hold skinning data (bones). It is a simple wraper around
* a structured UBO.
* @see RenderableManager::setSkinningBuffer
*/
class UTILS_PUBLIC SkinningBuffer : public FilamentAPI {
struct BuilderDetails;
public:
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Size of the skinning buffer in bones.
*
* Due to limitation in the GLSL, the SkinningBuffer must always by a multiple of
* 256, this adjustment is done automatically, but can cause
* some memory overhead. This memory overhead can be mitigated by using the same
* SkinningBuffer to store the bone information for multiple RenderPrimitives.
*
* @param boneCount Number of bones the skinning buffer can hold.
* @return A reference to this Builder for chaining calls.
*/
Builder& boneCount(uint32_t boneCount) noexcept;
/**
* The new buffer is created with identity bones
* @param initialize true to initializing the buffer, false to not.
* @return A reference to this Builder for chaining calls.
*/
Builder& initialize(bool initialize = true) noexcept;
/**
* Creates the SkinningBuffer object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this SkinningBuffer with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*
* @see SkinningBuffer::setBones
*/
SkinningBuffer* build(Engine& engine);
private:
friend class FSkinningBuffer;
};
/**
* Updates the bone transforms in the range [offset, offset + count).
* @param engine Reference to the filament::Engine to associate this SkinningBuffer with.
* @param transforms pointer to at least count Bone
* @param count number of Bone elements in transforms
* @param offset offset in elements (not bytes) in the SkinningBuffer (not in transforms)
* @see RenderableManager::setSkinningBuffer
*/
void setBones(Engine& engine, RenderableManager::Bone const* transforms,
size_t count, size_t offset = 0);
/**
* Updates the bone transforms in the range [offset, offset + count).
* @param engine Reference to the filament::Engine to associate this SkinningBuffer with.
* @param transforms pointer to at least count mat4f
* @param count number of mat4f elements in transforms
* @param offset offset in elements (not bytes) in the SkinningBuffer (not in transforms)
* @see RenderableManager::setSkinningBuffer
*/
void setBones(Engine& engine, math::mat4f const* transforms,
size_t count, size_t offset = 0);
/**
* Returns the size of this SkinningBuffer in elements.
* @return The number of bones the SkinningBuffer holds.
*/
size_t getBoneCount() const noexcept;
};
} // namespace filament
#endif //TNT_FILAMENT_SKINNINGBUFFER_H

View File

@@ -0,0 +1,181 @@
/*
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_SKYBOX_H
#define TNT_FILAMENT_SKYBOX_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <stdint.h>
#include <math/mathfwd.h>
namespace filament {
class FSkybox;
class Engine;
class Texture;
/**
* Skybox
*
* When added to a Scene, the Skybox fills all untouched pixels.
*
* Creation and destruction
* ========================
*
* A Skybox object is created using the Skybox::Builder and destroyed by calling
* Engine::destroy(const Skybox*).
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
*
* filament::IndirectLight* skybox = filament::Skybox::Builder()
* .environment(cubemap)
* .build(*engine);
*
* engine->destroy(skybox);
* ~~~~~~~~~~~
*
*
* @note
* Currently only Texture based sky boxes are supported.
*
* @see Scene, IndirectLight
*/
class UTILS_PUBLIC Skybox : public FilamentAPI {
struct BuilderDetails;
public:
//! Use Builder to construct an Skybox object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Set the environment map (i.e. the skybox content).
*
* The Skybox is rendered as though it were an infinitely large cube with the camera
* inside it. This means that the cubemap which is mapped onto the cube's exterior
* will appear mirrored. This follows the OpenGL conventions.
*
* The cmgen tool generates reflection maps by default which are therefore ideal to use
* as skyboxes.
*
* @param cubemap This Texture must be a cube map.
*
* @return This Builder, for chaining calls.
*
* @see Texture
*/
Builder& environment(Texture* cubemap) noexcept;
/**
* Indicates whether the sun should be rendered. The sun can only be
* rendered if there is at least one light of type SUN in the scene.
* The default value is false.
*
* @param show True if the sun should be rendered, false otherwise
*
* @return This Builder, for chaining calls.
*/
Builder& showSun(bool show) noexcept;
/**
* Skybox intensity when no IndirectLight is set on the Scene.
*
* This call is ignored when an IndirectLight is set on the Scene, and the intensity
* of the IndirectLight is used instead.
*
* @param envIntensity Scale factor applied to the skybox texel values such that
* the result is in lux, or lumen/m^2 (default = 30000)
*
* @return This Builder, for chaining calls.
*
* @see IndirectLight::Builder::intensity
*/
Builder& intensity(float envIntensity) noexcept;
/**
* Sets the skybox to a constant color. Default is opaque black.
*
* Ignored if an environment is set.
*
* @param color the constant color
*
* @return This Builder, for chaining calls.
*/
Builder& color(math::float4 color) noexcept;
/**
* Creates the Skybox object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this Skybox with.
*
* @return pointer to the newly created object, or nullptr if the light couldn't be created.
*/
Skybox* build(Engine& engine);
private:
friend class FSkybox;
};
void setColor(math::float4 color) noexcept;
/**
* Sets bits in a visibility mask. By default, this is 0x1.
*
* This provides a simple mechanism for hiding or showing this Skybox in a Scene.
*
* @see View::setVisibleLayers().
*
* For example, to set bit 1 and reset bits 0 and 2 while leaving all other bits unaffected,
* call: `setLayerMask(7, 2)`.
*
* @param select the set of bits to affect
* @param values the replacement values for the affected bits
*/
void setLayerMask(uint8_t select, uint8_t values) noexcept;
/**
* @return the visibility mask bits
*/
uint8_t getLayerMask() const noexcept;
/**
* Returns the skybox's intensity in lux, or lumen/m^2.
*/
float getIntensity() const noexcept;
/**
* @return the associated texture, or null if it does not exist
*/
Texture const* getTexture() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_SKYBOX_H

View File

@@ -0,0 +1,214 @@
/*
* 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_STREAM_H
#define TNT_FILAMENT_STREAM_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/CallbackHandler.h>
#include <utils/compiler.h>
namespace filament {
class FStream;
class Engine;
/**
* Stream is used to attach a video stream to a Filament `Texture`.
*
* Note that the `Stream` class is fairly Android centric. It supports two different
* configurations:
*
* - ACQUIRED.....connects to an Android AHardwareBuffer
* - NATIVE.......connects to an Android SurfaceTexture
*
* Before explaining these different configurations, let's review the high-level structure of an AR
* or video application that uses Filament:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* while (true) {
*
* // Misc application work occurs here, such as:
* // - Writing the image data for a video frame into a Stream
* // - Moving the Filament Camera
*
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Let's say that the video image data at the time of a particular invocation of `beginFrame`
* becomes visible to users at time A. The 3D scene state (including the camera) at the time of
* that same invocation becomes apparent to users at time B.
*
* - If time A matches time B, we say that the stream is \em{synchronized}.
* - Filament invokes low-level graphics commands on the \em{driver thread}.
* - The thread that calls `beginFrame` is called the \em{main thread}.
*
* For ACQUIRED streams, there is no need to perform the copy because Filament explictly acquires
* the stream, then releases it later via a callback function. This configuration is especially
* useful when the Vulkan backend is enabled.
*
* For NATIVE streams, Filament does not make any synchronization guarantee. However they are simple
* to use and do not incur a copy. These are often appropriate in video applications.
*
* Please see `sample-stream-test` and `sample-hello-camera` for usage examples.
*
* @see backend::StreamType
* @see Texture#setExternalStream
* @see Engine#destroyStream
*/
class UTILS_PUBLIC Stream : public FilamentAPI {
struct BuilderDetails;
public:
using Callback = backend::StreamCallback;
using StreamType = backend::StreamType;
/**
* Constructs a Stream object instance.
*
* By default, Stream objects are ACQUIRED and must have external images pushed to them via
* <pre>Stream::setAcquiredImage</pre>.
*
* To create a NATIVE stream, call the <pre>stream</pre> method on the builder.
*/
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Creates a NATIVE stream. Native streams can sample data directly from an
* opaque platform object such as a SurfaceTexture on Android.
*
* @param stream An opaque native stream handle. e.g.: on Android this is an
* `android/graphics/SurfaceTexture` JNI jobject. The wrap mode must
* be CLAMP_TO_EDGE.
*
* @return This Builder, for chaining calls.
*/
Builder& stream(void* stream) noexcept;
/**
*
* @param width initial width of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @return This Builder, for chaining calls.
*/
Builder& width(uint32_t width) noexcept;
/**
*
* @param height initial height of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @return This Builder, for chaining calls.
*/
Builder& height(uint32_t height) noexcept;
/**
* Creates the Stream object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this Stream with.
*
* @return pointer to the newly created object, or nullptr if the stream couldn't be created.
*/
Stream* build(Engine& engine);
private:
friend class FStream;
};
/**
* Indicates whether this stream is a NATIVE stream or ACQUIRED stream.
*/
StreamType getStreamType() const noexcept;
/**
* Updates an ACQUIRED stream with an image that is guaranteed to be used in the next frame.
*
* This method tells Filament to immediately "acquire" the image and trigger a callback
* when it is done with it. This should be called by the user outside of beginFrame / endFrame,
* and should be called only once per frame. If the user pushes images to the same stream
* multiple times in a single frame, only the final image is honored, but all callbacks are
* invoked.
*
* This method should be called on the same thread that calls Renderer::beginFrame, which is
* also where the callback is invoked. This method can only be used for streams that were
* constructed without calling the `stream` method on the builder.
*
* @see Stream for more information about NATIVE and ACQUIRED configurations.
*
* @param image Pointer to AHardwareBuffer, casted to void* since this is a public header.
* @param callback This is triggered by Filament when it wishes to release the image.
* It callback tales two arguments: the AHardwareBuffer and the userdata.
* @param userdata Optional closure data. Filament will pass this into the callback when it
* releases the image.
*/
void setAcquiredImage(void* image, Callback callback, void* userdata) noexcept;
/**
* @see setAcquiredImage(void*, Callback, void*)
*
* @param image Pointer to AHardwareBuffer, casted to void* since this is a public header.
* @param handler Handler to dispatch the AcquiredImage or nullptr for the default handler.
* @param callback This is triggered by Filament when it wishes to release the image.
* It callback tales two arguments: the AHardwareBuffer and the userdata.
* @param userdata Optional closure data. Filament will pass this into the callback when it
* releases the image.
*/
void setAcquiredImage(void* image, backend::CallbackHandler* handler, Callback callback, void* userdata) noexcept;
/**
* Updates the size of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @param width new width of the incoming stream
* @param height new height of the incoming stream
*/
void setDimensions(uint32_t width, uint32_t height) noexcept;
/**
* Returns the presentation time of the currently displayed frame in nanosecond.
*
* This value can change at any time.
*
* @return timestamp in nanosecond.
*/
int64_t getTimestamp() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_STREAM_H

View File

@@ -0,0 +1,259 @@
/*
* 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_SWAPCHAIN_H
#define TNT_FILAMENT_SWAPCHAIN_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PresentCallable.h>
#include <utils/compiler.h>
namespace filament {
class Engine;
/**
* A swap chain represents an Operating System's *native* renderable surface.
*
* Typically it's a native window or a view. Because a SwapChain is initialized from a
* native object, it is given to filament as a `void *`, which must be of the proper type
* for each platform filament is running on.
*
* \code
* SwapChain* swapChain = engine->createSwapChain(nativeWindow);
* \endcode
*
* When Engine::create() is used without specifying a Platform, the `nativeWindow`
* parameter above must be of type:
*
* Platform | nativeWindow type
* :---------------|:----------------------------:
* Android | ANativeWindow*
* macOS - OpenGL | NSView*
* macOS - Metal | CAMetalLayer*
* iOS - OpenGL | CAEAGLLayer*
* iOS - Metal | CAMetalLayer*
* X11 | Window
* Windows | HWND
*
* Otherwise, the `nativeWindow` is defined by the concrete implementation of Platform.
*
*
* Examples:
*
* Android
* -------
*
* On Android, an `ANativeWindow*` can be obtained from a Java `Surface` object using:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* #include <android/native_window_jni.h>
* // parameters
* // env: JNIEnv*
* // surface: jobject
* ANativeWindow* win = ANativeWindow_fromSurface(env, surface);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* \warning
* Don't use reflection to access the `mNativeObject` field, it won't work.
*
* A `Surface` can be retrieved from a `SurfaceView` or `SurfaceHolder` easily using
* `SurfaceHolder.getSurface()` and/or `SurfaceView.getHolder()`.
*
* \note
* To use a `TextureView` as a SwapChain, it is necessary to first get its `SurfaceTexture`,
* for instance using `TextureView.SurfaceTextureListener` and then create a `Surface`:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
* // using a TextureView.SurfaceTextureListener:
* public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
* mSurface = new Surface(surfaceTexture);
* // mSurface can now be used in JNI to create an ANativeWindow.
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Linux
* -----
*
* Example using SDL:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* SDL_SysWMinfo wmi;
* SDL_VERSION(&wmi.version);
* SDL_GetWindowWMInfo(sdlWindow, &wmi);
* Window nativeWindow = (Window) wmi.info.x11.window;
*
* using namespace filament;
* Engine* engine = Engine::create();
* SwapChain* swapChain = engine->createSwapChain((void*) nativeWindow);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Windows
* -------
*
* Example using SDL:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* SDL_SysWMinfo wmi;
* SDL_VERSION(&wmi.version);
* ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!");
* HDC nativeWindow = (HDC) wmi.info.win.hdc;
*
* using namespace filament;
* Engine* engine = Engine::create();
* SwapChain* swapChain = engine->createSwapChain((void*) nativeWindow);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* OSX
* ---
*
* On OSX, any `NSView` can be used *directly* as a `nativeWindow` with createSwapChain().
*
* Example using SDL/Objective-C:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.mm}
* #include <filament/Engine.h>
*
* #include <Cocoa/Cocoa.h>
* #include <SDL_syswm.h>
*
* SDL_SysWMinfo wmi;
* SDL_VERSION(&wmi.version);
* NSWindow* win = (NSWindow*) wmi.info.cocoa.window;
* NSView* view = [win contentView];
* void* nativeWindow = view;
*
* using namespace filament;
* Engine* engine = Engine::create();
* SwapChain* swapChain = engine->createSwapChain(nativeWindow);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @see Engine
*/
class UTILS_PUBLIC SwapChain : public FilamentAPI {
public:
using FrameScheduledCallback = backend::FrameScheduledCallback;
using FrameCompletedCallback = backend::FrameCompletedCallback;
/**
* Requests a SwapChain with an alpha channel.
*/
static const uint64_t CONFIG_TRANSPARENT = backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
/**
* This flag indicates that the swap chain may be used as a source surface
* for reading back render results. This config must be set when creating
* any swap chain that will be used as the source for a blit operation.
*
* @see
* Renderer.copyFrame()
*/
static const uint64_t CONFIG_READABLE = backend::SWAP_CHAIN_CONFIG_READABLE;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
static const uint64_t CONFIG_ENABLE_XCB = backend::SWAP_CHAIN_CONFIG_ENABLE_XCB;
/**
* Indicates that the native window is a CVPixelBufferRef.
*
* This is only supported by the Metal backend. The CVPixelBuffer must be in the
* kCVPixelFormatType_32BGRA format.
*
* It is not necessary to add an additional retain call before passing the pixel buffer to
* Filament. Filament will call CVPixelBufferRetain during Engine::createSwapChain, and
* CVPixelBufferRelease when the swap chain is destroyed.
*/
static const uint64_t CONFIG_APPLE_CVPIXELBUFFER =
backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
/**
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
*
* This flag is ignored if isSRGBSwapChainSupported() is false.
*
* When using this flag, the output colorspace in ColorGrading should be set to
* Rec709-Linear-D65, or post-processing should be disabled.
*
* @see isSRGBSwapChainSupported()
* @see ColorGrading.outputColorSpace()
* @see View.setPostProcessingEnabled()
*/
static constexpr uint64_t CONFIG_SRGB_COLORSPACE = backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @param engine A pointer to the filament Engine
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
static bool isSRGBSwapChainSupported(Engine& engine) noexcept;
void* getNativeWindow() const noexcept;
/**
* FrameScheduledCallback is a callback function that notifies an application when Filament has
* completed processing a frame and that frame is ready to be scheduled for presentation.
*
* Typically, Filament is responsible for scheduling the frame's presentation to the SwapChain.
* If a SwapChain::FrameScheduledCallback is set, however, the application bares the
* responsibility of scheduling a frame for presentation by calling the backend::PresentCallable
* passed to the callback function. Currently this functionality is only supported by the Metal
* backend.
*
* A FrameScheduledCallback can be set on an individual SwapChain through
* SwapChain::setFrameScheduledCallback. If the callback is set, then the SwapChain will *not*
* automatically schedule itself for presentation. Instead, the application must call the
* PresentCallable passed to the FrameScheduledCallback.
*
* @param callback A callback, or nullptr to unset.
* @param user An optional pointer to user data passed to the callback function.
*
* @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.
*
* @see PresentCallable
*/
void setFrameScheduledCallback(FrameScheduledCallback callback, void* user = nullptr);
/**
* FrameCompletedCallback is a callback function that notifies an application when a frame's
* contents have completed rendering on the GPU.
*
* Use SwapChain::setFrameCompletedCallback to set a callback on an individual SwapChain. Each
* time a frame completes GPU rendering, the callback will be called with optional user data.
*
* The FrameCompletedCallback is guaranteed to be called on the main Filament thread.
*
* @param callback A callback, or nullptr to unset.
* @param user An optional pointer to user data passed to the callback function.
*
* @remark Only Filament's Metal backend supports frame callbacks. Other backends ignore the
* callback (which will never be called) and proceed normally.
*/
void setFrameCompletedCallback(FrameCompletedCallback callback, void* user = nullptr);
};
} // namespace filament
#endif // TNT_FILAMENT_SWAPCHAIN_H

View File

@@ -0,0 +1,548 @@
/*
* 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_TEXTURE_H
#define TNT_FILAMENT_TEXTURE_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <utils/compiler.h>
#include <stddef.h>
namespace filament {
class FTexture;
class Engine;
class Stream;
/**
* Texture
*
* The Texture class supports:
* - 2D textures
* - 3D textures
* - Cube maps
* - mip mapping
*
*
* Creation and destruction
* ========================
*
* A Texture object is created using the Texture::Builder and destroyed by calling
* Engine::destroy(const Texture*).
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
*
* filament::Texture* texture = filament::Texture::Builder()
* .width(64)
* .height(64)
* .build(*engine);
*
* engine->destroy(texture);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*/
class UTILS_PUBLIC Texture : public FilamentAPI {
struct BuilderDetails;
public:
static constexpr const size_t BASE_LEVEL = 0;
//! Face offsets for all faces of a cubemap
struct FaceOffsets;
using PixelBufferDescriptor = backend::PixelBufferDescriptor; //!< Geometry of a pixel buffer
using Sampler = backend::SamplerType; //!< Type of sampler
using InternalFormat = backend::TextureFormat; //!< Internal texel format
using CubemapFace = backend::TextureCubemapFace; //!< Cube map faces
using Format = backend::PixelDataFormat; //!< Pixel color format
using Type = backend::PixelDataType; //!< Pixel data format
using CompressedType = backend::CompressedPixelDataType; //!< Compressed pixel data format
using Usage = backend::TextureUsage; //!< Usage affects texel layout
using Swizzle = backend::TextureSwizzle; //!< Texture swizzle
/** @return whether a backend supports a particular format. */
static bool isTextureFormatSupported(Engine& engine, InternalFormat format) noexcept;
/** @return whether a backend supports texture swizzling. */
static bool isTextureSwizzleSupported(Engine& engine) noexcept;
static size_t computeTextureDataSize(Texture::Format format, Texture::Type type,
size_t stride, size_t height, size_t alignment) noexcept;
/**
* Options for environment prefiltering into reflection map
*
* @see generatePrefilterMipmap()
*/
struct PrefilterOptions {
uint16_t sampleCount = 8; //!< sample count used for filtering
bool mirror = true; //!< whether the environment must be mirrored
private:
UTILS_UNUSED uintptr_t reserved[3] = {};
};
//! Use Builder to construct a Texture object instance
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Specifies the width in texels of the texture. Doesn't need to be a power-of-two.
* @param width Width of the texture in texels (default: 1).
* @return This Builder, for chaining calls.
*/
Builder& width(uint32_t width) noexcept;
/**
* Specifies the height in texels of the texture. Doesn't need to be a power-of-two.
* @param height Height of the texture in texels (default: 1).
* @return This Builder, for chaining calls.
*/
Builder& height(uint32_t height) noexcept;
/**
* Specifies the depth in texels of the texture. Doesn't need to be a power-of-two.
* The depth controls the number of layers in a 2D array texture. Values greater than 1
* effectively create a 3D texture.
* @param depth Depth of the texture in texels (default: 1).
* @return This Builder, for chaining calls.
* @attention This Texture instance must use Sampler::SAMPLER_3D or
* Sampler::SAMPLER_2D_ARRAY or it has no effect.
*/
Builder& depth(uint32_t depth) noexcept;
/**
* Specifies the numbers of mip map levels.
* This creates a mip-map pyramid. The maximum number of levels a texture can have is
* such that max(width, height, level) / 2^MAX_LEVELS = 1
* @param levels Number of mipmap levels for this texture.
* @return This Builder, for chaining calls.
*/
Builder& levels(uint8_t levels) noexcept;
/**
* Specifies the type of sampler to use.
* @param target Sampler type
* @return This Builder, for chaining calls.
* @see Sampler
*/
Builder& sampler(Sampler target) noexcept;
/**
* Specifies the *internal* format of this texture.
*
* The internal format specifies how texels are stored (which may be different from how
* they're specified in setImage()). InternalFormat specifies both the color components
* and the data type used.
*
* @param format Format of the texture's texel.
* @return This Builder, for chaining calls.
* @see InternalFormat, setImage
*/
Builder& format(InternalFormat format) noexcept;
/**
* Specifies if the texture will be used as a render target attachment.
*
* If the texture is potentially rendered into, it may require a different memory layout,
* which needs to be known during construction.
*
* @param usage Defaults to Texture::Usage::DEFAULT; c.f. Texture::Usage::COLOR_ATTACHMENT.
* @return This Builder, for chaining calls.
*/
Builder& usage(Usage usage) noexcept;
/**
* Specifies how a texture's channels map to color components
*
* Texture Swizzle is only supported if isTextureSwizzleSupported() returns true.
*
* @param r texture channel for red component
* @param g texture channel for green component
* @param b texture channel for blue component
* @param a texture channel for alpha component
* @return This Builder, for chaining calls.
* @see Texture::isTextureSwizzleSupported()
*/
Builder& swizzle(Swizzle r, Swizzle g, Swizzle b, Swizzle a) noexcept;
/**
* Creates the Texture object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this Texture with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Texture* build(Engine& engine);
/* no user serviceable parts below */
/**
* Specify a native texture to import as a Filament texture.
*
* The texture id is backend-specific:
* - OpenGL: GLuint texture ID
* - Metal: id<MTLTexture>
*
* With Metal, the id<MTLTexture> object should be cast to an intptr_t using
* CFBridgingRetain to transfer ownership to Filament. Filament will release ownership of
* the texture object when the Filament texture is destroyed.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
* id <MTLTexture> metalTexture = ...
* filamentTexture->import((intptr_t) CFBridgingRetain(metalTexture));
* // free to release metalTexture
*
* // after using texture:
* engine->destroy(filamentTexture); // metalTexture is released
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @warning This method should be used as a last resort. This API is subject to change or
* removal.
*
* @param id a backend specific texture identifier
*
* @return This Builder, for chaining calls.
*/
Builder& import(intptr_t id) noexcept;
private:
friend class FTexture;
};
/**
* Returns the width of a 2D or 3D texture level
* @param level texture level.
* @return Width in texel of the specified \p level, clamped to 1.
* @attention If this texture is using Sampler::SAMPLER_EXTERNAL, the dimension
* of the texture are unknown and this method always returns whatever was set on the Builder.
*/
size_t getWidth(size_t level = BASE_LEVEL) const noexcept;
/**
* Returns the height of a 2D or 3D texture level
* @param level texture level.
* @return Height in texel of the specified \p level, clamped to 1.
* @attention If this texture is using Sampler::SAMPLER_EXTERNAL, the dimension
* of the texture are unknown and this method always returns whatever was set on the Builder.
*/
size_t getHeight(size_t level = BASE_LEVEL) const noexcept;
/**
* Returns the depth of a 3D texture level
* @param level texture level.
* @return Depth in texel of the specified \p level, clamped to 1.
* @attention If this texture is using Sampler::SAMPLER_EXTERNAL, the dimension
* of the texture are unknown and this method always returns whatever was set on the Builder.
*/
size_t getDepth(size_t level = BASE_LEVEL) const noexcept;
/**
* Returns the maximum number of levels this texture can have.
* @return maximum number of levels this texture can have.
* @attention If this texture is using Sampler::SAMPLER_EXTERNAL, the dimension
* of the texture are unknown and this method always returns whatever was set on the Builder.
*/
size_t getLevels() const noexcept;
/**
* Return this texture Sampler as set by Builder::sampler().
* @return this texture Sampler as set by Builder::sampler()
*/
Sampler getTarget() const noexcept;
/**
* Return this texture InternalFormat as set by Builder::format().
* @return this texture InternalFormat as set by Builder::format().
*/
InternalFormat getFormat() const noexcept;
/**
* Updates a sub-image of a 3D texture or 2D texture array for a level. Cubemaps are treated
* like a 2D array of six layers.
*
* @param engine Engine this texture is associated to.
* @param level Level to set the image for.
* @param xoffset Left offset of the sub-region to update.
* @param yoffset Bottom offset of the sub-region to update.
* @param zoffset Depth offset of the sub-region to update.
* @param width Width of the sub-region to update.
* @param height Height of the sub-region to update.
* @param depth Depth of the sub-region to update.
* @param buffer Client-side buffer containing the image to set.
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention \p level must be less than getLevels().
* @attention \p buffer's Texture::Format must match that of getFormat().
* @attention This Texture instance must use Sampler::SAMPLER_3D, Sampler::SAMPLER_2D_ARRAY
* or Sampler::SAMPLER_CUBEMAP.
*
* @see Builder::sampler()
*/
void setImage(Engine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
PixelBufferDescriptor&& buffer) const;
/**
* inline helper to update a 2D texture
*
* @see setImage(Engine& engine, size_t level,
* uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
* uint32_t width, uint32_t height, uint32_t depth,
* PixelBufferDescriptor&& buffer)
*/
inline void setImage(Engine& engine, size_t level, PixelBufferDescriptor&& buffer) const {
setImage(engine, level, 0, 0, 0,
uint32_t(getWidth(level)), uint32_t(getHeight(level)), 1, std::move(buffer));
}
/**
* inline helper to update a 2D texture
*
* @see setImage(Engine& engine, size_t level,
* uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
* uint32_t width, uint32_t height, uint32_t depth,
* PixelBufferDescriptor&& buffer)
*/
inline void setImage(Engine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
PixelBufferDescriptor&& buffer) const {
setImage(engine, level, xoffset, yoffset, 0, width, height, 1, std::move(buffer));
}
/**
* Specify all six images of a cube map level.
*
* This method follows exactly the OpenGL conventions.
*
* @param engine Engine this texture is associated to.
* @param level Level to set the image for.
* @param buffer Client-side buffer containing the images to set.
* @param faceOffsets Offsets in bytes into \p buffer for all six images. The offsets
* are specified in the following order: +x, -x, +y, -y, +z, -z
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention \p level must be less than getLevels().
* @attention \p buffer's Texture::Format must match that of getFormat().
* @attention This Texture instance must use Sampler::SAMPLER_CUBEMAP or it has no effect
*
* @see Texture::CubemapFace, Builder::sampler()
*
* @deprecated Instead, use setImage(Engine& engine, size_t level,
* uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
* uint32_t width, uint32_t height, uint32_t depth,
* PixelBufferDescriptor&& buffer)
*/
UTILS_DEPRECATED
void setImage(Engine& engine, size_t level,
PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets) const;
/**
* Specify the external image to associate with this Texture. Typically the external
* image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:
* - only the level of detail (lod) 0 can be specified
* - only nearest or linear filtering is supported
* - the size and format of the texture is defined by the external image
* - only the CLAMP_TO_EDGE wrap mode is supported
*
* @param engine Engine this texture is associated to.
* @param image An opaque handle to a platform specific image. Supported types are
* eglImageOES on Android and CVPixelBufferRef on iOS.
*
* On iOS the following pixel formats are supported:
* - kCVPixelFormatType_32BGRA
* - kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention This Texture instance must use Sampler::SAMPLER_EXTERNAL or it has no effect
*
* @see Builder::sampler()
*
*/
void setExternalImage(Engine& engine, void* image) noexcept;
/**
* Specify the external image and plane to associate with this Texture. Typically the external
* image is OS specific, and can be a video or camera frame. When using this method, the
* external image must be a planar type (such as a YUV camera frame). The plane parameter
* selects which image plane is bound to this texture.
*
* A single external image can be bound to different Filament textures, with each texture
* associated with a separate plane:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* textureA->setExternalImage(engine, image, 0);
* textureB->setExternalImage(engine, image, 1);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* There are many restrictions when using an external image as a texture, such as:
* - only the level of detail (lod) 0 can be specified
* - only nearest or linear filtering is supported
* - the size and format of the texture is defined by the external image
* - only the CLAMP_TO_EDGE wrap mode is supported
*
* @param engine Engine this texture is associated to.
* @param image An opaque handle to a platform specific image. Supported types are
* eglImageOES on Android and CVPixelBufferRef on iOS.
* @param plane The plane index of the external image to associate with this texture.
*
* This method is only meaningful on iOS with
* kCVPixelFormatType_420YpCbCr8BiPlanarFullRange images. On platforms
* other than iOS, this method is a no-op.
*/
void setExternalImage(Engine& engine, void* image, size_t plane) noexcept;
/**
* Specify the external stream to associate with this Texture. Typically the external
* stream is OS specific, and can be a video or camera stream.
* There are many restrictions when using an external stream as a texture, such as:
* - only the level of detail (lod) 0 can be specified
* - only nearest or linear filtering is supported
* - the size and format of the texture is defined by the external stream
*
* @param engine Engine this texture is associated to.
* @param stream A Stream object
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention This Texture instance must use Sampler::SAMPLER_EXTERNAL or it has no effect
*
* @see Builder::sampler(), Stream
*
*/
void setExternalStream(Engine& engine, Stream* stream) noexcept;
/**
* Generates all the mipmap levels automatically. This requires the texture to have a
* color-renderable format.
*
* @param engine Engine this texture is associated to.
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention This Texture instance must NOT use Sampler::SAMPLER_CUBEMAP or it has no effect
*/
void generateMipmaps(Engine& engine) const noexcept;
/**
* Creates a reflection map from an environment map.
*
* This is a utility function that replaces calls to Texture::setImage().
* The provided environment map is processed and all mipmap levels are populated. The
* processing is similar to the offline tool `cmgen` as a lower quality setting.
*
* This function is intended to be used when the environment cannot be processed offline,
* for instance if it's generated at runtime.
*
* The source data must obey to some constraints:
* - the data type must be PixelDataFormat::RGB
* - the data format must be one of
* - PixelDataType::FLOAT
* - PixelDataType::HALF
*
* The current texture must be a cubemap
*
* The reflections cubemap's internal format cannot be a compressed format.
*
* The reflections cubemap's dimension must be a power-of-two.
*
* @warning This operation is computationally intensive, especially with large environments and
* is currently synchronous. Expect about 1ms for a 16x16 cubemap.
*
* @param engine Reference to the filament::Engine to associate this IndirectLight with.
* @param buffer Client-side buffer containing the images to set.
* @param faceOffsets Offsets in bytes into \p buffer for all six images. The offsets
* are specified in the following order: +x, -x, +y, -y, +z, -z
* @param options Optional parameter to controlling user-specified quality and options.
*
* @exception utils::PreConditionPanic if the source data constraints are not respected.
*
*/
void generatePrefilterMipmap(Engine& engine,
PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets,
PrefilterOptions const* options = nullptr);
/** @deprecated */
struct FaceOffsets {
using size_type = size_t;
union {
struct {
size_type px; //!< +x face offset in bytes
size_type nx; //!< -x face offset in bytes
size_type py; //!< +y face offset in bytes
size_type ny; //!< -y face offset in bytes
size_type pz; //!< +z face offset in bytes
size_type nz; //!< -z face offset in bytes
};
size_type offsets[6];
};
size_type operator[](size_t n) const noexcept { return offsets[n]; }
size_type& operator[](size_t n) { return offsets[n]; }
FaceOffsets() noexcept = default;
explicit FaceOffsets(size_type faceSize) noexcept {
px = faceSize * 0;
nx = faceSize * 1;
py = faceSize * 2;
ny = faceSize * 3;
pz = faceSize * 4;
nz = faceSize * 5;
}
FaceOffsets(const FaceOffsets& rhs) noexcept {
px = rhs.px;
nx = rhs.nx;
py = rhs.py;
ny = rhs.ny;
pz = rhs.pz;
nz = rhs.nz;
}
FaceOffsets& operator=(const FaceOffsets& rhs) noexcept {
px = rhs.px;
nx = rhs.nx;
py = rhs.py;
ny = rhs.ny;
pz = rhs.pz;
nz = rhs.nz;
return *this;
}
};
};
} // namespace filament
#endif // TNT_FILAMENT_TEXTURE_H

View File

@@ -0,0 +1,205 @@
/*
* 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_TEXTURESAMPLER_H
#define TNT_FILAMENT_TEXTURESAMPLER_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <math.h>
namespace filament {
/**
* TextureSampler defines how a texture is accessed.
*/
class UTILS_PUBLIC TextureSampler {
public:
using WrapMode = backend::SamplerWrapMode;
using MinFilter = backend::SamplerMinFilter;
using MagFilter = backend::SamplerMagFilter;
using CompareMode = backend::SamplerCompareMode;
using CompareFunc = backend::SamplerCompareFunc;
/**
* Creates a default sampler.
* The default parameters are:
* - filterMag : NEAREST
* - filterMin : NEAREST
* - wrapS : CLAMP_TO_EDGE
* - wrapT : CLAMP_TO_EDGE
* - wrapR : CLAMP_TO_EDGE
* - compareMode : NONE
* - compareFunc : Less or equal
* - no anisotropic filtering
*/
TextureSampler() noexcept = default;
TextureSampler(const TextureSampler& rhs) noexcept = default;
TextureSampler& operator=(const TextureSampler& rhs) noexcept = default;
/**
* Creates a TextureSampler with the default parameters but setting the filtering and wrap modes.
* @param minMag filtering for both minification and magnification
* @param str wrapping mode for all texture coordinate axes
*/
explicit TextureSampler(MagFilter minMag, WrapMode str = WrapMode::CLAMP_TO_EDGE) noexcept {
mSamplerParams.filterMin = MinFilter(minMag);
mSamplerParams.filterMag = minMag;
mSamplerParams.wrapS = str;
mSamplerParams.wrapT = str;
mSamplerParams.wrapR = str;
}
/**
* Creates a TextureSampler with the default parameters but setting the filtering and wrap modes.
* @param min filtering for minification
* @param mag filtering for magnification
* @param str wrapping mode for all texture coordinate axes
*/
TextureSampler(MinFilter min, MagFilter mag, WrapMode str = WrapMode::CLAMP_TO_EDGE) noexcept {
mSamplerParams.filterMin = min;
mSamplerParams.filterMag = mag;
mSamplerParams.wrapS = str;
mSamplerParams.wrapT = str;
mSamplerParams.wrapR = str;
}
/**
* Creates a TextureSampler with the default parameters but setting the filtering and wrap modes.
* @param min filtering for minification
* @param mag filtering for magnification
* @param s wrap mode for the s (horizontal)texture coordinate
* @param t wrap mode for the t (vertical) texture coordinate
* @param r wrap mode for the r (depth) texture coordinate
*/
TextureSampler(MinFilter min, MagFilter mag, WrapMode s, WrapMode t, WrapMode r) noexcept {
mSamplerParams.filterMin = min;
mSamplerParams.filterMag = mag;
mSamplerParams.wrapS = s;
mSamplerParams.wrapT = t;
mSamplerParams.wrapR = r;
}
/**
* Creates a TextureSampler with the default parameters but setting the compare mode and function
* @param mode Compare mode
* @param func Compare function
*/
explicit TextureSampler(CompareMode mode, CompareFunc func = CompareFunc::LE) noexcept {
mSamplerParams.compareMode = mode;
mSamplerParams.compareFunc = func;
}
/**
* Sets the minification filter
* @param v Minification filter
*/
void setMinFilter(MinFilter v) noexcept {
mSamplerParams.filterMin = v;
}
/**
* Sets the magnification filter
* @param v Magnification filter
*/
void setMagFilter(MagFilter v) noexcept {
mSamplerParams.filterMag = v;
}
/**
* Sets the wrap mode for the s (horizontal) texture coordinate
* @param v wrap mode
*/
void setWrapModeS(WrapMode v) noexcept {
mSamplerParams.wrapS = v;
}
/**
* Sets the wrap mode for the t (vertical) texture coordinate
* @param v wrap mode
*/
void setWrapModeT(WrapMode v) noexcept {
mSamplerParams.wrapT = v;
}
/**
* Sets the wrap mode for the r (depth, for 3D textures) texture coordinate
* @param v wrap mode
*/
void setWrapModeR(WrapMode v) noexcept {
mSamplerParams.wrapR = v;
}
/**
* This controls anisotropic filtering.
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 0.
* The maximum permissible value is 7.
*/
void setAnisotropy(float anisotropy) noexcept {
const int log2 = ilogbf(anisotropy > 0 ? anisotropy : -anisotropy);
mSamplerParams.anisotropyLog2 = uint8_t(log2 < 7 ? log2 : 7);
}
/**
* Sets the compare mode and function.
* @param mode Compare mode
* @param func Compare function
*/
void setCompareMode(CompareMode mode, CompareFunc func = CompareFunc::LE) noexcept {
mSamplerParams.compareMode = mode;
mSamplerParams.compareFunc = func;
}
//! returns the minification filter value
MinFilter getMinFilter() const noexcept { return mSamplerParams.filterMin; }
//! returns the magnification filter value
MagFilter getMagFilter() const noexcept { return mSamplerParams.filterMag; }
//! returns the s-coordinate wrap mode (horizontal)
WrapMode getWrapModeS() const noexcept { return mSamplerParams.wrapS; }
//! returns the t-coordinate wrap mode (vertical)
WrapMode getWrapModeT() const noexcept { return mSamplerParams.wrapT; }
//! returns the r-coordinate wrap mode (depth)
WrapMode getWrapModeR() const noexcept { return mSamplerParams.wrapR; }
//! returns the anisotropy value
float getAnisotropy() const noexcept { return float(1u << mSamplerParams.anisotropyLog2); }
//! returns the compare mode
CompareMode getCompareMode() const noexcept { return mSamplerParams.compareMode; }
//! returns the compare function
CompareFunc getCompareFunc() const noexcept { return mSamplerParams.compareFunc; }
// no user-serviceable parts below...
backend::SamplerParams getSamplerParams() const noexcept { return mSamplerParams; }
private:
backend::SamplerParams mSamplerParams{};
};
} // namespace filament
#endif // TNT_FILAMENT_TEXTURESAMPLER_H

View File

@@ -0,0 +1,227 @@
/*
* 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 TNT_FILAMENT_TONEMAPPER_H
#define TNT_FILAMENT_TONEMAPPER_H
#include <utils/compiler.h>
#include <math/mathfwd.h>
namespace filament {
/**
* Interface for tone mapping operators. A tone mapping operator, or tone mapper,
* is responsible for compressing the dynamic range of the rendered scene to a
* dynamic range suitable for display.
*
* In Filament, tone mapping is a color grading step. ToneMapper instances are
* created and passed to the ColorGrading::Builder to produce a 3D LUT that will
* be used during post-processing to prepare the final color buffer for display.
*
* Filament provides several default tone mapping operators that fall into three
* categories:
*
* - Configurable tone mapping operators
* - GenericToneMapper
* - Fixed-aesthetic tone mapping operators
* - ACESToneMapper
* - ACESLegacyToneMapper
* - FilmicToneMapper
* - Debug/validation tone mapping operators
* - LinearToneMapper
* - DisplayRangeToneMapper
*
* You can create custom tone mapping operators by subclassing ToneMapper.
*/
struct UTILS_PUBLIC ToneMapper {
ToneMapper() noexcept;
virtual ~ToneMapper() noexcept;
/**
* Maps an open domain (or "scene referred" values) color value to display
* domain (or "display referred") color value. Both the input and output
* color values are defined in the Rec.2020 color space, with no transfer
* function applied ("linear Rec.2020").
*
* @param c Input color to tone map, in the Rec.2020 color space with no
* transfer function applied ("linear")
*
* @return A tone mapped color in the Rec.2020 color space, with no transfer
* function applied ("linear")
*/
virtual math::float3 operator()(math::float3 c) const noexcept = 0;
};
/**
* Linear tone mapping operator that returns the input color but clamped to
* the 0..1 range. This operator is mostly useful for debugging.
*/
struct UTILS_PUBLIC LinearToneMapper final : public ToneMapper {
LinearToneMapper() noexcept;
~LinearToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* ACES tone mapping operator. This operator is an implementation of the
* ACES Reference Rendering Transform (RRT) combined with the Output Device
* Transform (ODT) for sRGB monitors (dim surround, 100 nits).
*/
struct UTILS_PUBLIC ACESToneMapper final : public ToneMapper {
ACESToneMapper() noexcept;
~ACESToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* ACES tone mapping operator, modified to match the perceived brightness
* of FilmicToneMapper. This operator is the same as ACESToneMapper but
* applies a brightness multiplier of ~1.6 to the input color value to
* target brighter viewing environments.
*/
struct UTILS_PUBLIC ACESLegacyToneMapper final : public ToneMapper {
ACESLegacyToneMapper() noexcept;
~ACESLegacyToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* "Filmic" tone mapping operator. This tone mapper was designed to
* approximate the aesthetics of the ACES RRT + ODT for Rec.709
* and historically Filament's default tone mapping operator. It exists
* only for backward compatibility purposes and is not otherwise recommended.
*/
struct UTILS_PUBLIC FilmicToneMapper final : public ToneMapper {
FilmicToneMapper() noexcept;
~FilmicToneMapper() noexcept final;
math::float3 operator()(math::float3 x) const noexcept override;
};
/**
* Generic tone mapping operator that gives control over the tone mapping
* curve. This operator can be used to control the aesthetics of the final
* image. This operator also allows to control the dynamic range of the
* scene referred values.
*
* The tone mapping curve is defined by 5 parameters:
* - contrast: controls the contrast of the curve
* - midGrayIn: sets the input middle gray
* - midGrayOut: sets the output middle gray
* - hdrMax: defines the maximum input value that will be mapped to
* output white
*/
struct UTILS_PUBLIC GenericToneMapper final : public ToneMapper {
/**
* Builds a new generic tone mapper. The default values of the
* constructor parameters approximate an ACES tone mapping curve
* and the maximum input value is set to 10.0.
*
* @param contrast controls the contrast of the curve, must be > 0.0, values
* in the range 0.5..2.0 are recommended.
* @param midGrayIn sets the input middle gray, between 0.0 and 1.0.
* @param midGrayOut sets the output middle gray, between 0.0 and 1.0.
* @param hdrMax defines the maximum input value that will be mapped to
* output white. Must be >= 1.0.
*/
explicit GenericToneMapper(
float contrast = 1.55f,
float midGrayIn = 0.18f,
float midGrayOut = 0.215f,
float hdrMax = 10.0f
) noexcept;
~GenericToneMapper() noexcept final;
GenericToneMapper(GenericToneMapper const&) = delete;
GenericToneMapper& operator=(GenericToneMapper const&) = delete;
GenericToneMapper(GenericToneMapper&& rhs) noexcept;
GenericToneMapper& operator=(GenericToneMapper&& rhs) noexcept;
math::float3 operator()(math::float3 x) const noexcept override;
/** Returns the contrast of the curve as a strictly positive value. */
float getContrast() const noexcept;
/** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */
float getShoulder() const noexcept;
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
float getMidGrayIn() const noexcept;
/** Returns the middle gray point for output values as a value between 0.0 and 1.0. */
float getMidGrayOut() const noexcept;
/** Returns the maximum input value that will map to output white, as a value >= 1.0. */
float getHdrMax() const noexcept;
/** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */
void setContrast(float contrast) noexcept;
/** Sets the input middle gray, between 0.0 and 1.0. */
void setMidGrayIn(float midGrayIn) noexcept;
/** Sets the output middle gray, between 0.0 and 1.0. */
void setMidGrayOut(float midGrayOut) noexcept;
/** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */
void setHdrMax(float hdrMax) noexcept;
private:
struct Options;
Options* mOptions;
};
/**
* A tone mapper that converts the input HDR RGB color into one of 16 debug colors
* that represent the pixel's exposure. When the output is cyan, the input color
* represents middle gray (18% exposure). Every exposure stop above or below middle
* gray causes a color shift.
*
* The relationship between exposures and colors is:
*
* - -5EV black
* - -4EV darkest blue
* - -3EV darker blue
* - -2EV dark blue
* - -1EV blue
* - OEV cyan
* - +1EV dark green
* - +2EV green
* - +3EV yellow
* - +4EV yellow-orange
* - +5EV orange
* - +6EV bright red
* - +7EV red
* - +8EV magenta
* - +9EV purple
* - +10EV white
*
* This tone mapper is useful to validate and tweak scene lighting.
*/
struct UTILS_PUBLIC DisplayRangeToneMapper final : public ToneMapper {
DisplayRangeToneMapper() noexcept;
~DisplayRangeToneMapper() noexcept override;
math::float3 operator()(math::float3 c) const noexcept override;
};
} // namespace filament
#endif // TNT_FILAMENT_TONEMAPPER_H

View File

@@ -0,0 +1,316 @@
/*
* 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_TRANSFORMMANAGER_H
#define TNT_FILAMENT_TRANSFORMMANAGER_H
#include <filament/FilamentAPI.h>
#include <utils/compiler.h>
#include <utils/EntityInstance.h>
#include <math/mathfwd.h>
#include <iterator>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
class FTransformManager;
/**
* TransformManager is used to add transform components to entities.
*
* A Transform component gives an entity a position and orientation in space in the coordinate
* space of its parent transform. The TransformManager takes care of computing the world-space
* transform of each component (i.e. its transform relative to the root).
*
* Creation and destruction
* ========================
*
* A transform component is created using TransformManager::create() and destroyed by calling
* TransformManager::destroy().
*
* ~~~~~~~~~~~{.cpp}
* filament::Engine* engine = filament::Engine::create();
* utils::Entity object = utils::EntityManager.get().create();
*
* auto& tcm = engine->getTransformManager();
*
* // create the transform component
* tcm.create(object);
*
* // set its transform
* auto i = tcm.getInstance(object);
* tcm.setTransform(i, mat4f::translation({ 0, 0, -1 }));
*
* // destroy the transform component
* tcm.destroy(object);
* ~~~~~~~~~~~
*
*/
class UTILS_PUBLIC TransformManager : public FilamentAPI {
public:
using Instance = utils::EntityInstance<TransformManager>;
class children_iterator {
friend class FTransformManager;
TransformManager const& mManager;
Instance mInstance;
children_iterator(TransformManager const& mgr, Instance instance) noexcept
: mManager(mgr), mInstance(instance) { }
public:
using value_type = Instance;
using difference_type = ptrdiff_t;
using pointer = Instance*;
using reference = Instance&;
using iterator_category = std::forward_iterator_tag;
children_iterator& operator++();
children_iterator operator++(int) { // NOLINT
children_iterator ret(*this);
++(*this);
return ret;
}
bool operator == (const children_iterator& other) const noexcept {
return mInstance == other.mInstance;
}
bool operator != (const children_iterator& other) const noexcept {
return mInstance != other.mInstance;
}
value_type operator*() const { return mInstance; }
};
/**
* Returns whether a particular Entity is associated with a component of this TransformManager
* @param e An Entity.
* @return true if this Entity has a component associated with this manager.
*/
bool hasComponent(utils::Entity e) const noexcept;
/**
* Gets an Instance representing the transform component associated with the given Entity.
* @param e An Entity.
* @return An Instance object, which represents the transform component associated with the Entity e.
* @note Use Instance::isValid() to make sure the component exists.
* @see hasComponent()
*/
Instance getInstance(utils::Entity e) const noexcept;
/**
* Enables or disable the accurate translation mode. Disabled by default.
*
* When accurate translation mode is active, the translation component of all transforms is
* maintained at double precision. This is only useful if the mat4 version of setTransform()
* is used, as well as getTransformAccurate().
*
* @param enable true to enable the accurate translation mode, false to disable.
*
* @see isAccurateTranslationsEnabled
* @see create(utils::Entity, Instance, const math::mat4&);
* @see setTransform(Instance, const math::mat4&)
* @see getTransformAccurate
* @see getWorldTransformAccurate
*/
void setAccurateTranslationsEnabled(bool enable) noexcept;
/**
* Returns whether the high precision translation mode is active.
* @return true if accurate translations mode is active, false otherwise
* @see setAccurateTranslationsEnabled
*/
bool isAccurateTranslationsEnabled() const noexcept;
/**
* Creates a transform component and associate it with the given entity.
* @param entity An Entity to associate a transform component to.
* @param parent The Instance of the parent transform, or Instance{} if no parent.
* @param localTransform The transform to initialize the transform component with.
* This is always relative to the parent.
*
* If this component already exists on the given entity, it is first destroyed as if
* destroy(utils::Entity e) was called.
*
* @see destroy()
*/
void create(utils::Entity entity, Instance parent, const math::mat4f& localTransform);
void create(utils::Entity entity, Instance parent, const math::mat4& localTransform); //!< \overload
void create(utils::Entity entity, Instance parent = {}); //!< \overload
/**
* Destroys this component from the given entity, children are orphaned.
* @param e An entity.
*
* @note If this transform had children, these are orphaned, which means their local
* transform becomes a world transform. Usually it's nonsensical. It's recommended to make
* sure that a destroyed transform doesn't have children.
*
* @see create()
*/
void destroy(utils::Entity e) noexcept;
/**
* Re-parents an entity to a new one.
* @param i The instance of the transform component to re-parent
* @param newParent The instance of the new parent transform
* @attention It is an error to re-parent an entity to a descendant and will cause undefined behaviour.
* @see getInstance()
*/
void setParent(Instance i, Instance newParent) noexcept;
/**
* Returns the parent of a transform component, or the null entity if it is a root.
* @param i The instance of the transform component to query.
*/
utils::Entity getParent(Instance i) const noexcept;
/**
* Returns the number of children of a transform component.
* @param i The instance of the transform component to query.
* @return The number of children of the queried component.
*/
size_t getChildCount(Instance i) const noexcept;
/**
* Gets a list of children for a transform component.
*
* @param i The instance of the transform component to query.
* @param children Pointer to array-of-Entity. The array must have at least "count" elements.
* @param count The maximum number of children to retrieve.
* @return The number of children written to the pointer.
*/
size_t getChildren(Instance i, utils::Entity* children, size_t count) const noexcept;
/**
* Returns an iterator to the Instance of the first child of the given parent.
*
* @param parent Instance of the parent
* @return A forward iterator pointing to the first child of the given parent.
*
* A child_iterator can only safely be dereferenced if it's different from getChildrenEnd(parent)
*/
children_iterator getChildrenBegin(Instance parent) const noexcept;
/**
* Returns an undreferencable iterator representing the end of the children list
*
* @param parent Instance of the parent
* @return A forward iterator.
*
* This iterator cannot be dereferenced
*/
children_iterator getChildrenEnd(Instance parent) const noexcept;
/**
* Sets a local transform of a transform component.
* @param ci The instance of the transform component to set the local transform to.
* @param localTransform The local transform (i.e. relative to the parent).
* @see getTransform()
* @attention This operation can be slow if the hierarchy of transform is too deep, and this
* will be particularly bad when updating a lot of transforms. In that case,
* consider using openLocalTransformTransaction() / commitLocalTransformTransaction().
*/
void setTransform(Instance ci, const math::mat4f& localTransform) noexcept;
/**
* Sets a local transform of a transform component and keeps double precision translation.
* All other values of the transform are stored at single precision.
* @param ci The instance of the transform component to set the local transform to.
* @param localTransform The local transform (i.e. relative to the parent).
* @see getTransform()
* @attention This operation can be slow if the hierarchy of transform is too deep, and this
* will be particularly bad when updating a lot of transforms. In that case,
* consider using openLocalTransformTransaction() / commitLocalTransformTransaction().
*/
void setTransform(Instance ci, const math::mat4& localTransform) noexcept;
/**
* Returns the local transform of a transform component.
* @param ci The instance of the transform component to query the local transform from.
* @return The local transform of the component (i.e. relative to the parent). This always
* returns the value set by setTransform().
* @see setTransform()
*/
const math::mat4f& getTransform(Instance ci) const noexcept;
/**
* Returns the local transform of a transform component.
* @param ci The instance of the transform component to query the local transform from.
* @return The local transform of the component (i.e. relative to the parent). This always
* returns the value set by setTransform().
* @see setTransform()
*/
const math::mat4 getTransformAccurate(Instance ci) const noexcept;
/**
* Return the world transform of a transform component.
* @param ci The instance of the transform component to query the world transform from.
* @return The world transform of the component (i.e. relative to the root). This is the
* composition of this component's local transform with its parent's world transform.
* @see setTransform()
*/
const math::mat4f& getWorldTransform(Instance ci) const noexcept;
/**
* Return the world transform of a transform component.
* @param ci The instance of the transform component to query the world transform from.
* @return The world transform of the component (i.e. relative to the root). This is the
* composition of this component's local transform with its parent's world transform.
* @see setTransform()
*/
const math::mat4 getWorldTransformAccurate(Instance ci) const noexcept;
/**
* Opens a local transform transaction. During a transaction, getWorldTransform() can
* return an invalid transform until commitLocalTransformTransaction() is called. However,
* setTransform() will perform significantly better and in constant time.
*
* This is useful when updating many transforms and the transform hierarchy is deep (say more
* than 4 or 5 levels).
*
* @note If the local transform transaction is already open, this is a no-op.
*
* @see commitLocalTransformTransaction(), setTransform()
*/
void openLocalTransformTransaction() noexcept;
/**
* Commits the currently open local transform transaction. When this returns, calls
* to getWorldTransform() will return the proper value.
*
* @attention failing to call this method when done updating the local transform will cause
* a lot of rendering problems. The system never closes the transaction
* automatically.
*
* @note If the local transform transaction is not open, this is a no-op.
*
* @see openLocalTransformTransaction(), setTransform()
*/
void commitLocalTransformTransaction() noexcept;
};
} // namespace filament
#endif // TNT_TRANSFORMMANAGER_H

View File

@@ -0,0 +1,201 @@
/*
* 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_VERTEXBUFFER_H
#define TNT_FILAMENT_VERTEXBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/MaterialEnums.h>
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
namespace filament {
class FVertexBuffer;
class BufferObject;
class Engine;
/**
* Holds a set of buffers that define the geometry of a Renderable.
*
* The geometry of the Renderable itself is defined by a set of vertex attributes such as
* position, color, normals, tangents, etc...
*
* There is no need to have a 1-to-1 mapping between attributes and buffer. A buffer can hold the
* data of several attributes -- attributes are then referred as being "interleaved".
*
* The buffers themselves are GPU resources, therefore mutating their data can be relatively slow.
* For this reason, it is best to separate the constant data from the dynamic data into multiple
* buffers.
*
* It is possible, and even encouraged, to use a single vertex buffer for several Renderables.
*
* @see IndexBuffer, RenderableManager
*/
class UTILS_PUBLIC VertexBuffer : public FilamentAPI {
struct BuilderDetails;
public:
using AttributeType = backend::ElementType;
using BufferDescriptor = backend::BufferDescriptor;
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Defines how many buffers will be created in this vertex buffer set. These buffers are
* later referenced by index from 0 to \p bufferCount - 1.
*
* This call is mandatory. The default is 0.
*
* @param bufferCount Number of buffers in this vertex buffer set. The maximum value is 8.
* @return A reference to this Builder for chaining calls.
*/
Builder& bufferCount(uint8_t bufferCount) noexcept;
/**
* Size of each buffer in the set in vertex.
*
* @param vertexCount Number of vertices in each buffer in this set.
* @return A reference to this Builder for chaining calls.
*/
Builder& vertexCount(uint32_t vertexCount) noexcept;
/**
* Allows buffers to be swapped out and shared using BufferObject.
*
* If buffer objects mode is enabled, clients must call setBufferObjectAt rather than
* setBufferAt. This allows sharing of data between VertexBuffer objects, but it may
* slightly increase the memory footprint of Filament's internal bookkeeping.
*
* @param enabled If true, enables buffer object mode. False by default.
*/
Builder& enableBufferObjects(bool enabled = true) noexcept;
/**
* Sets up an attribute for this vertex buffer set.
*
* Using \p byteOffset and \p byteStride, attributes can be interleaved in the same buffer.
*
* @param attribute The attribute to set up.
* @param bufferIndex The index of the buffer containing the data for this attribute. Must
* be between 0 and bufferCount() - 1.
* @param attributeType The type of the attribute data (e.g. byte, float3, etc...)
* @param byteOffset Offset in *bytes* into the buffer \p bufferIndex
* @param byteStride Stride in *bytes* to the next element of this attribute. When set to
* zero the attribute size, as defined by \p attributeType is used.
*
* @return A reference to this Builder for chaining calls.
*
* @warning VertexAttribute::TANGENTS must be specified as a quaternion and is how normals
* are specified.
*
* @warning Not all backends support 3-component attributes that are not floats. For help
* with conversion, see geometry::Transcoder.
*
* @see VertexAttribute
*
* This is a no-op if the \p attribute is an invalid enum.
* This is a no-op if the \p bufferIndex is out of bounds.
*
*/
Builder& attribute(VertexAttribute attribute, uint8_t bufferIndex,
AttributeType attributeType,
uint32_t byteOffset = 0, uint8_t byteStride = 0) noexcept;
/**
* Sets whether a given attribute should be normalized. By default attributes are not
* normalized. A normalized attribute is mapped between 0 and 1 in the shader. This applies
* only to integer types.
*
* @param attribute Enum of the attribute to set the normalization flag to.
* @param normalize true to automatically normalize the given attribute.
* @return A reference to this Builder for chaining calls.
*
* This is a no-op if the \p attribute is an invalid enum.
*/
Builder& normalized(VertexAttribute attribute, bool normalize = true) noexcept;
/**
* Creates the VertexBuffer object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this VertexBuffer with.
*
* @return pointer to the newly created object or nullptr if exceptions are disabled and
* an error occurred.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
VertexBuffer* build(Engine& engine);
private:
friend class FVertexBuffer;
};
/**
* Returns the vertex count.
* @return Number of vertices in this vertex buffer set.
*/
size_t getVertexCount() const noexcept;
/**
* Asynchronously copy-initializes the specified buffer from the given buffer data.
*
* Do not use this if you called enableBufferObjects() on the Builder.
*
* @param engine Reference to the filament::Engine to associate this VertexBuffer with.
* @param bufferIndex Index of the buffer to initialize. Must be between 0
* and Builder::bufferCount() - 1.
* @param buffer A BufferDescriptor representing the data used to initialize the buffer at
* index \p bufferIndex. BufferDescriptor points to raw, untyped data that will
* be copied as-is into the buffer.
* @param byteOffset Offset in *bytes* into the buffer at index \p bufferIndex of this vertex
* buffer set.
*/
void setBufferAt(Engine& engine, uint8_t bufferIndex, BufferDescriptor&& buffer,
uint32_t byteOffset = 0);
/**
* Swaps in the given buffer object.
*
* To use this, you must first call enableBufferObjects() on the Builder.
*
* @param engine Reference to the filament::Engine to associate this VertexBuffer with.
* @param bufferIndex Index of the buffer to initialize. Must be between 0
* and Builder::bufferCount() - 1.
* @param bufferObject The handle to the GPU data that will be used in this buffer slot.
*/
void setBufferObjectAt(Engine& engine, uint8_t bufferIndex, BufferObject const* bufferObject);
};
} // namespace filament
#endif // TNT_FILAMENT_VERTEXBUFFER_H

View File

@@ -0,0 +1,873 @@
/*
* 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_VIEW_H
#define TNT_FILAMENT_VIEW_H
#include <filament/Color.h>
#include <filament/FilamentAPI.h>
#include <filament/Options.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <math/mathfwd.h>
namespace filament {
namespace backend {
class CallbackHandler;
} // namespace backend
class Camera;
class ColorGrading;
class MaterialInstance;
class RenderTarget;
class Scene;
class Viewport;
/**
* A View encompasses all the state needed for rendering a Scene.
*
* Renderer::render() operates on View objects. These View objects specify important parameters
* such as:
* - The Scene
* - The Camera
* - The Viewport
* - Some rendering parameters
*
* \note
* View instances are heavy objects that internally cache a lot of data needed for rendering.
* It is not advised for an application to use many View objects.
*
* For example, in a game, a View could be used for the main scene and another one for the
* game's user interface. More View instances could be used for creating special effects (e.g.
* a View is akin to a rendering pass).
*
*
* @see Renderer, Scene, Camera, RenderTarget
*/
class UTILS_PUBLIC View : public FilamentAPI {
public:
using QualityLevel = QualityLevel;
using BlendMode = BlendMode;
using AntiAliasing = AntiAliasing;
using Dithering = Dithering;
using ShadowType = ShadowType;
using DynamicResolutionOptions = DynamicResolutionOptions;
using BloomOptions = BloomOptions;
using FogOptions = FogOptions;
using DepthOfFieldOptions = DepthOfFieldOptions;
using VignetteOptions = VignetteOptions;
using RenderQuality = RenderQuality;
using AmbientOcclusionOptions = AmbientOcclusionOptions;
using TemporalAntiAliasingOptions = TemporalAntiAliasingOptions;
using MultiSampleAntiAliasingOptions = MultiSampleAntiAliasingOptions;
using VsmShadowOptions = VsmShadowOptions;
using SoftShadowOptions = SoftShadowOptions;
using ScreenSpaceReflectionsOptions = ScreenSpaceReflectionsOptions;
using GuardBandOptions = GuardBandOptions;
/**
* Sets the View's name. Only useful for debugging.
* @param name Pointer to the View's name. The string is copied.
*/
void setName(const char* name) noexcept;
/**
* Returns the View's name
*
* @return a pointer owned by the View instance to the View's name.
*
* @attention Do *not* free the pointer or modify its content.
*/
const char* getName() const noexcept;
/**
* Set this View instance's Scene.
*
* @param scene Associate the specified Scene to this View. A Scene can be associated to
* several View instances.\n
* \p scene can be nullptr to dissociate the currently set Scene
* from this View.\n
* The View doesn't take ownership of the Scene pointer (which
* acts as a reference).
*
* @note
* There is no reference-counting.
* Make sure to dissociate a Scene from all Views before destroying it.
*/
void setScene(Scene* scene);
/**
* Returns the Scene currently associated with this View.
* @return A pointer to the Scene associated to this View. nullptr if no Scene is set.
*/
Scene* getScene() noexcept;
/**
* Returns the Scene currently associated with this View.
* @return A pointer to the Scene associated to this View. nullptr if no Scene is set.
*/
Scene const* getScene() const noexcept {
return const_cast<View*>(this)->getScene();
}
/**
* Specifies an offscreen render target to render into.
*
* By default, the view's associated render target is nullptr, which corresponds to the
* SwapChain associated with the engine.
*
* A view with a custom render target cannot rely on Renderer::ClearOptions, which only apply
* to the SwapChain. Such view can use a Skybox instead.
*
* @param renderTarget Render target associated with view, or nullptr for the swap chain.
*/
void setRenderTarget(RenderTarget* renderTarget) noexcept;
/**
* Gets the offscreen render target associated with this view.
*
* Returns nullptr if the render target is the swap chain (which is default).
*
* @see setRenderTarget
*/
RenderTarget* getRenderTarget() const noexcept;
/**
* Sets the rectangular region to render to.
*
* The viewport specifies where the content of the View (i.e. the Scene) is rendered in
* the render target. The Render target is automatically clipped to the Viewport.
*
* @param viewport The Viewport to render the Scene into. The Viewport is a value-type, it is
* therefore copied. The parameter can be discarded after this call returns.
*/
void setViewport(Viewport const& viewport) noexcept;
/**
* Returns the rectangular region that gets rendered to.
* @return A constant reference to View's viewport.
*/
Viewport const& getViewport() const noexcept;
/**
* Sets this View's Camera.
*
* @param camera Associate the specified Camera to this View. A Camera can be associated to
* several View instances.\n
* \p camera can be nullptr to dissociate the currently set Camera from this
* View.\n
* The View doesn't take ownership of the Camera pointer (which
* acts as a reference).
*
* @note
* There is no reference-counting.
* Make sure to dissociate a Camera from all Views before destroying it.
*/
void setCamera(Camera* camera) noexcept;
/**
* Returns the Camera currently associated with this View.
* @return A reference to the Camera associated to this View.
*/
Camera& getCamera() noexcept;
/**
* Returns the Camera currently associated with this View.
* @return A reference to the Camera associated to this View.
*/
Camera const& getCamera() const noexcept {
return const_cast<View*>(this)->getCamera();
}
/**
* Sets the blending mode used to draw the view into the SwapChain.
*
* @param blendMode either BlendMode::OPAQUE or BlendMode::TRANSLUCENT
* @see getBlendMode
*/
void setBlendMode(BlendMode blendMode) noexcept;
/**
*
* @return blending mode set by setBlendMode
* @see setBlendMode
*/
BlendMode getBlendMode() const noexcept;
/**
* Sets which layers are visible.
*
* Renderable objects can have one or several layers associated to them. Layers are
* represented with an 8-bits bitmask, where each bit corresponds to a layer.
*
* This call sets which of those layers are visible. Renderables in invisible layers won't be
* rendered.
*
* @param select a bitmask specifying which layer to set or clear using \p values.
* @param values a bitmask where each bit sets the visibility of the corresponding layer
* (1: visible, 0: invisible), only layers in \p select are affected.
*
* @see RenderableManager::setLayerMask().
*
* @note By default only layer 0 (bitmask 0x01) is visible.
* @note This is a convenient way to quickly show or hide sets of Renderable objects.
*/
void setVisibleLayers(uint8_t select, uint8_t values) noexcept;
/**
* Helper function to enable or disable a visibility layer.
* @param layer layer between 0 and 7 to enable or disable
* @param enabled true to enable the layer, false to disable it
* @see RenderableManager::setVisibleLayers()
*/
inline void setLayerEnabled(size_t layer, bool enabled) noexcept {
const uint8_t mask = 1u << layer;
setVisibleLayers(mask, enabled ? mask : 0);
}
/**
* Get the visible layers.
*
* @see View::setVisibleLayers()
*/
uint8_t getVisibleLayers() const noexcept;
/**
* Enables or disables shadow mapping. Enabled by default.
*
* @param enabled true enables shadow mapping, false disables it.
*
* @see LightManager::Builder::castShadows(),
* RenderableManager::Builder::receiveShadows(),
* RenderableManager::Builder::castShadows(),
*/
void setShadowingEnabled(bool enabled) noexcept;
/**
* @return whether shadowing is enabled
*/
bool isShadowingEnabled() const noexcept;
/**
* Enables or disables screen space refraction. Enabled by default.
*
* @param enabled true enables screen space refraction, false disables it.
*/
void setScreenSpaceRefractionEnabled(bool enabled) noexcept;
/**
* @return whether screen space refraction is enabled
*/
bool isScreenSpaceRefractionEnabled() const noexcept;
/**
* Sets how many samples are to be used for MSAA in the post-process stage.
* Default is 1 and disables MSAA.
*
* @param count number of samples to use for multi-sampled anti-aliasing.\n
* 0: treated as 1
* 1: no anti-aliasing
* n: sample count. Effective sample could be different depending on the
* GPU capabilities.
*
* @note Anti-aliasing can also be performed in the post-processing stage, generally at lower
* cost. See setAntialiasing.
*
* @see setAntialiasing
* @deprecated use setMultiSampleAntiAliasingOptions instead
*/
UTILS_DEPRECATED
void setSampleCount(uint8_t count = 1) noexcept;
/**
* Returns the sample count set by setSampleCount(). Effective sample count could be different.
* A value of 0 or 1 means MSAA is disabled.
*
* @return value set by setSampleCount().
* @deprecated use getMultiSampleAntiAliasingOptions instead
*/
UTILS_DEPRECATED
uint8_t getSampleCount() const noexcept;
/**
* Enables or disables anti-aliasing in the post-processing stage. Enabled by default.
* MSAA can be enabled in addition, see setSampleCount().
*
* @param type FXAA for enabling, NONE for disabling anti-aliasing.
*
* @note For MSAA anti-aliasing, see setSamplerCount().
*
* @see setSampleCount
*/
void setAntiAliasing(AntiAliasing type) noexcept;
/**
* Queries whether anti-aliasing is enabled during the post-processing stage. To query
* whether MSAA is enabled, see getSampleCount().
*
* @return The post-processing anti-aliasing method.
*/
AntiAliasing getAntiAliasing() const noexcept;
/**
* Enables or disable temporal anti-aliasing (TAA). Disabled by default.
*
* @param options temporal anti-aliasing options
*/
void setTemporalAntiAliasingOptions(TemporalAntiAliasingOptions options) noexcept;
/**
* Returns temporal anti-aliasing options.
*
* @return temporal anti-aliasing options
*/
TemporalAntiAliasingOptions const& getTemporalAntiAliasingOptions() const noexcept;
/**
* Enables or disable screen-space reflections. Disabled by default.
*
* @param options screen-space reflections options
*/
void setScreenSpaceReflectionsOptions(ScreenSpaceReflectionsOptions options) noexcept;
/**
* Returns screen-space reflections options.
*
* @return screen-space reflections options
*/
ScreenSpaceReflectionsOptions const& getScreenSpaceReflectionsOptions() const noexcept;
/**
* Enables or disable screen-space guard band. Disabled by default.
*
* @param options guard band options
*/
void setGuardBandOptions(GuardBandOptions options) noexcept;
/**
* Returns screen-space guard band options.
*
* @return guard band options
*/
GuardBandOptions const& getGuardBandOptions() const noexcept;
/**
* Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default.
*
* @param options multi-sample anti-aliasing options
*/
void setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept;
/**
* Returns multi-sample anti-aliasing options.
*
* @return multi-sample anti-aliasing options
*/
MultiSampleAntiAliasingOptions const& getMultiSampleAntiAliasingOptions() const noexcept;
/**
* Sets this View's color grading transforms.
*
* @param colorGrading Associate the specified ColorGrading to this View. A ColorGrading can be
* associated to several View instances.\n
* \p colorGrading can be nullptr to dissociate the currently set
* ColorGrading from this View. Doing so will revert to the use of the
* default color grading transforms.\n
* The View doesn't take ownership of the ColorGrading pointer (which
* acts as a reference).
*
* @note
* There is no reference-counting.
* Make sure to dissociate a ColorGrading from all Views before destroying it.
*/
void setColorGrading(ColorGrading* colorGrading) noexcept;
/**
* Returns the color grading transforms currently associated to this view.
* @return A pointer to the ColorGrading associated to this View.
*/
const ColorGrading* getColorGrading() const noexcept;
/**
* Sets ambient occlusion options.
*
* @param options Options for ambient occlusion.
*/
void setAmbientOcclusionOptions(AmbientOcclusionOptions const& options) noexcept;
/**
* Gets the ambient occlusion options.
*
* @return ambient occlusion options currently set.
*/
AmbientOcclusionOptions const& getAmbientOcclusionOptions() const noexcept;
/**
* Enables or disables bloom in the post-processing stage. Disabled by default.
*
* @param options options
*/
void setBloomOptions(BloomOptions options) noexcept;
/**
* Queries the bloom options.
*
* @return the current bloom options for this view.
*/
BloomOptions getBloomOptions() const noexcept;
/**
* Enables or disables fog. Disabled by default.
*
* @param options options
*/
void setFogOptions(FogOptions options) noexcept;
/**
* Queries the fog options.
*
* @return the current fog options for this view.
*/
FogOptions getFogOptions() const noexcept;
/**
* Enables or disables Depth of Field. Disabled by default.
*
* @param options options
*/
void setDepthOfFieldOptions(DepthOfFieldOptions options) noexcept;
/**
* Queries the depth of field options.
*
* @return the current depth of field options for this view.
*/
DepthOfFieldOptions getDepthOfFieldOptions() const noexcept;
/**
* Enables or disables the vignetted effect in the post-processing stage. Disabled by default.
*
* @param options options
*/
void setVignetteOptions(VignetteOptions options) noexcept;
/**
* Queries the vignette options.
*
* @return the current vignette options for this view.
*/
VignetteOptions getVignetteOptions() const noexcept;
/**
* Enables or disables dithering in the post-processing stage. Enabled by default.
*
* @param dithering dithering type
*/
void setDithering(Dithering dithering) noexcept;
/**
* Queries whether dithering is enabled during the post-processing stage.
*
* @return the current dithering type for this view.
*/
Dithering getDithering() const noexcept;
/**
* Sets the dynamic resolution options for this view. Dynamic resolution options
* controls whether dynamic resolution is enabled, and if it is, how it behaves.
*
* @param options The dynamic resolution options to use on this view
*/
void setDynamicResolutionOptions(DynamicResolutionOptions const& options) noexcept;
/**
* Returns the dynamic resolution options associated with this view.
* @return value set by setDynamicResolutionOptions().
*/
DynamicResolutionOptions getDynamicResolutionOptions() const noexcept;
/**
* Sets the rendering quality for this view. Refer to RenderQuality for more
* information about the different settings available.
*
* @param renderQuality The render quality to use on this view
*/
void setRenderQuality(RenderQuality const& renderQuality) noexcept;
/**
* Returns the render quality used by this view.
* @return value set by setRenderQuality().
*/
RenderQuality getRenderQuality() const noexcept;
/**
* Sets options relative to dynamic lighting for this view.
*
* @param zLightNear Distance from the camera where the lights are expected to shine.
* This parameter can affect performance and is useful because depending
* on the scene, lights that shine close to the camera may not be
* visible -- in this case, using a larger value can improve performance.
* e.g. when standing and looking straight, several meters of the ground
* isn't visible and if lights are expected to shine there, there is no
* point using a short zLightNear. (Default 5m).
*
* @param zLightFar Distance from the camera after which lights are not expected to be visible.
* Similarly to zLightNear, setting this value properly can improve
* performance. (Default 100m).
*
*
* Together zLightNear and zLightFar must be chosen so that the visible influence of lights
* is spread between these two values.
*
*/
void setDynamicLightingOptions(float zLightNear, float zLightFar) noexcept;
/*
* Set the shadow mapping technique this View uses.
*
* The ShadowType affects all the shadows seen within the View.
*
* ShadowType::VSM imposes a restriction on marking renderables as only shadow receivers (but
* not casters). To ensure correct shadowing with VSM, all shadow participant renderables should
* be marked as both receivers and casters. Objects that are guaranteed to not cast shadows on
* themselves or other objects (such as flat ground planes) can be set to not cast shadows,
* which might improve shadow quality.
*
* @warning This API is still experimental and subject to change.
*/
void setShadowType(ShadowType shadow) noexcept;
/**
* Sets VSM shadowing options that apply across the entire View.
*
* Additional light-specific VSM options can be set with LightManager::setShadowOptions.
*
* Only applicable when shadow type is set to ShadowType::VSM.
*
* @param options Options for shadowing.
*
* @see setShadowType
*
* @warning This API is still experimental and subject to change.
*/
void setVsmShadowOptions(VsmShadowOptions const& options) noexcept;
/**
* Returns the VSM shadowing options associated with this View.
*
* @return value set by setVsmShadowOptions().
*/
VsmShadowOptions getVsmShadowOptions() const noexcept;
/**
* Sets soft shadowing options that apply across the entire View.
*
* Additional light-specific soft shadow parameters can be set with LightManager::setShadowOptions.
*
* Only applicable when shadow type is set to ShadowType::DPCF or ShadowType::PCSS.
*
* @param options Options for shadowing.
*
* @see setShadowType
*
* @warning This API is still experimental and subject to change.
*/
void setSoftShadowOptions(SoftShadowOptions const& options) noexcept;
/**
* Returns the soft shadowing options associated with this View.
*
* @return value set by setSoftShadowOptions().
*/
SoftShadowOptions getSoftShadowOptions() const noexcept;
/**
* Enables or disables post processing. Enabled by default.
*
* Post-processing includes:
* - Depth-of-field
* - Bloom
* - Vignetting
* - Temporal Anti-aliasing (TAA)
* - Color grading & gamma encoding
* - Dithering
* - FXAA
* - Dynamic scaling
*
* Disabling post-processing forgoes color correctness as well as some anti-aliasing techniques
* and should only be used for debugging, UI overlays or when using custom render targets
* (see RenderTarget).
*
* @param enabled true enables post processing, false disables it.
*
* @see setBloomOptions, setColorGrading, setAntiAliasing, setDithering, setSampleCount
*/
void setPostProcessingEnabled(bool enabled) noexcept;
//! Returns true if post-processing is enabled. See setPostProcessingEnabled() for more info.
bool isPostProcessingEnabled() const noexcept;
/**
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
* winding order. When the winding order is inverted, front faces are faces with a clockwise
* winding order.
*
* Changing the winding order will directly affect the culling mode in materials
* (see Material::getCullingMode()).
*
* Inverting the winding order of front faces is useful when rendering mirrored reflections
* (water, mirror surfaces, front camera in AR, etc.).
*
* @param inverted True to invert front faces, false otherwise.
*/
void setFrontFaceWindingInverted(bool inverted) noexcept;
/**
* Returns true if the winding order of front faces is inverted.
* See setFrontFaceWindingInverted() for more information.
*/
bool isFrontFaceWindingInverted() const noexcept;
/**
* Enables use of the stencil buffer.
*
* The stencil buffer is an 8-bit, per-fragment unsigned integer stored alongside the depth
* buffer. The stencil buffer is cleared at the beginning of a frame and discarded after the
* color pass.
*
* Each fragment's stencil value is set during rasterization by specifying stencil operations on
* a Material. The stencil buffer can be used as a mask for later rendering by setting a
* Material's stencil comparison function and reference value. Fragments that don't pass the
* stencil test are then discarded.
*
* Post-processing must be enabled in order to use the stencil buffer.
*
* A renderable's priority (see RenderableManager::setPriority) is useful to control the order
* in which primitives are drawn.
*
* @param enabled True to enable the stencil buffer, false disables it (default)
*/
void setStencilBufferEnabled(bool enabled) noexcept;
/**
* Returns true if the stencil buffer is enabled.
* See setStencilBufferEnabled() for more information.
*/
bool isStencilBufferEnabled() const noexcept;
// for debugging...
//! debugging: allows to entirely disable frustum culling. (culling enabled by default).
void setFrustumCullingEnabled(bool culling) noexcept;
//! debugging: returns whether frustum culling is enabled.
bool isFrustumCullingEnabled() const noexcept;
//! debugging: sets the Camera used for rendering. It may be different from the culling camera.
void setDebugCamera(Camera* camera) noexcept;
//! debugging: returns a Camera from the point of view of *the* dominant directional light used for shadowing.
Camera const* getDirectionalLightCamera() const noexcept;
/** Result of a picking query */
struct PickingQueryResult {
utils::Entity renderable{}; //! RenderableManager Entity at the queried coordinates
float depth{}; //! Depth buffer value (1 (near plane) to 0 (infinity))
uint32_t reserved1{};
uint32_t reserved2{};
/**
* screen space coordinates in GL convention, this can be used to compute the view or
* world space position of the picking hit. For e.g.:
* clip_space_position = (fragCoords.xy / viewport.wh, fragCoords.z) * 2.0 - 1.0
* view_space_position = inverse(projection) * clip_space_position
* world_space_position = model * view_space_position
*
* The viewport, projection and model matrices can be obtained from Camera. Because
* pick() has some latency, it might be more accurate to obtain these values at the
* time the View::pick() call is made.
*
* Note: if the Engine is running at FEATURE_LEVEL_0, the precision or `depth` and
* `fragCoords.z` is only 8-bits.
*/
math::float3 fragCoords; //! screen space coordinates in GL convention
};
/** User data for PickingQueryResultCallback */
struct PickingQuery {
// note: this is enough to store a std::function<> -- just saying...
void* storage[4];
};
/** callback type used for picking queries. */
using PickingQueryResultCallback = void(*)(PickingQueryResult const& result, PickingQuery* pq);
/**
* Helper for creating a picking query from Foo::method, by pointer.
* e.g.: pick<Foo, &Foo::bar>(x, y, &foo);
*
* @tparam T Class of the method to call (e.g.: Foo)
* @tparam method Method to call on T (e.g.: &Foo::bar)
* @param x Horizontal coordinate to query in the viewport with origin on the left.
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
* @param instance A pointer to an instance of T
* @param handler Handler to dispatch the callback or nullptr for the default handler.
*/
template<typename T, void(T::*method)(PickingQueryResult const&)>
void pick(uint32_t x, uint32_t y, T* instance, backend::CallbackHandler* handler = nullptr) noexcept {
PickingQuery& query = pick(x, y, [](PickingQueryResult const& result, PickingQuery* pq) {
void* user = pq->storage;
(*static_cast<T**>(user)->*method)(result);
}, handler);
query.storage[0] = instance;
}
/**
* Helper for creating a picking query from Foo::method, by copy for a small object
* e.g.: pick<Foo, &Foo::bar>(x, y, foo);
*
* @tparam T Class of the method to call (e.g.: Foo)
* @tparam method Method to call on T (e.g.: &Foo::bar)
* @param x Horizontal coordinate to query in the viewport with origin on the left.
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
* @param instance An instance of T
* @param handler Handler to dispatch the callback or nullptr for the default handler.
*/
template<typename T, void(T::*method)(PickingQueryResult const&)>
void pick(uint32_t x, uint32_t y, T instance, backend::CallbackHandler* handler = nullptr) noexcept {
static_assert(sizeof(instance) <= sizeof(PickingQuery::storage), "user data too large");
PickingQuery& query = pick(x, y, [](PickingQueryResult const& result, PickingQuery* pq) {
void* user = pq->storage;
T* that = static_cast<T*>(user);
(that->*method)(result);
that->~T();
}, handler);
new(query.storage) T(std::move(instance));
}
/**
* Helper for creating a picking query from a small functor
* e.g.: pick(x, y, [](PickingQueryResult const& result){});
*
* @param x Horizontal coordinate to query in the viewport with origin on the left.
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
* @param functor A functor, typically a lambda function.
* @param handler Handler to dispatch the callback or nullptr for the default handler.
*/
template<typename T>
void pick(uint32_t x, uint32_t y, T functor, backend::CallbackHandler* handler = nullptr) noexcept {
static_assert(sizeof(functor) <= sizeof(PickingQuery::storage), "functor too large");
PickingQuery& query = pick(x, y, handler,
(PickingQueryResultCallback)[](PickingQueryResult const& result, PickingQuery* pq) {
void* user = pq->storage;
T& that = *static_cast<T*>(user);
that(result);
that.~T();
});
new(query.storage) T(std::move(functor));
}
/**
* Creates a picking query. Multiple queries can be created (e.g.: multi-touch).
* Picking queries are all executed when Renderer::render() is called on this View.
* The provided callback is guaranteed to be called at some point in the future.
*
* Typically it takes a couple frames to receive the result of a picking query.
*
* @param x Horizontal coordinate to query in the viewport with origin on the left.
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
* @param callback User callback, called when the picking query result is available.
* @param handler Handler to dispatch the callback or nullptr for the default handler.
* @return A reference to a PickingQuery structure, which can be used to store up to
* 8*sizeof(void*) bytes of user data. This user data is later accessible
* in the PickingQueryResultCallback callback 3rd parameter.
*/
PickingQuery& pick(uint32_t x, uint32_t y, backend::CallbackHandler* handler,
PickingQueryResultCallback callback) noexcept;
/**
* Set the value of material global variables. There are up-to four such variable each of
* type float4. These variables can be read in a user Material with
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param value new value for the variable.
* @see getMaterialGlobal
*/
void setMaterialGlobal(uint32_t index, math::float4 const& value);
/**
* Get the value of the material global variables.
* All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @return current value of the variable.
* @see setMaterialGlobal
*/
math::float4 getMaterialGlobal(uint32_t index) const;
/**
* Get an Entity representing the large scale fog object.
* This entity is always inherited by the View's Scene.
*
* It is for example possible to create a TransformManager component with this
* Entity and apply a transformation globally on the fog.
*
* @return an Entity representing the large scale fog object.
*/
utils::Entity getFogEntity() const noexcept;
/**
* List of available ambient occlusion techniques
* @deprecated use AmbientOcclusionOptions::enabled instead
*/
enum class UTILS_DEPRECATED AmbientOcclusion : uint8_t {
NONE = 0, //!< No Ambient Occlusion
SSAO = 1 //!< Basic, sampling SSAO
};
/**
* Activates or deactivates ambient occlusion.
* @deprecated use setAmbientOcclusionOptions() instead
* @see setAmbientOcclusionOptions
*
* @param ambientOcclusion Type of ambient occlusion to use.
*/
UTILS_DEPRECATED
void setAmbientOcclusion(AmbientOcclusion ambientOcclusion) noexcept;
/**
* Queries the type of ambient occlusion active for this View.
* @deprecated use getAmbientOcclusionOptions() instead
* @see getAmbientOcclusionOptions
*
* @return ambient occlusion type.
*/
UTILS_DEPRECATED
AmbientOcclusion getAmbientOcclusion() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_VIEW_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.
*/
//! \file
#ifndef TNT_FILAMENT_VIEWPORT_H
#define TNT_FILAMENT_VIEWPORT_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <math/scalar.h>
#include <math/mathfwd.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
/**
* Viewport describes a view port in pixel coordinates
*
* A view port is represented by its left-bottom coordinate, width and height in pixels.
*/
class UTILS_PUBLIC Viewport : public backend::Viewport {
public:
/**
* Creates a Viewport of zero width and height at the origin.
*/
Viewport() noexcept : backend::Viewport{} {}
/**
* Creates a Viewport from its left-bottom coordinates, width and height in pixels
*
* @param left left coordinate in pixel
* @param bottom bottom coordinate in pixel
* @param width width in pixel
* @param height height in pixel
*/
Viewport(int32_t left, int32_t bottom, uint32_t width, uint32_t height) noexcept
: backend::Viewport{ left, bottom, width, height } {
}
/**
* Returns whether the area of the view port is null.
*
* @return true if either width or height is 0 pixel.
*/
bool empty() const noexcept { return !width || !height; }
private:
/**
* Compares two Viewports for equality
* @param lhs reference to the left hand side Viewport
* @param rhs reference to the right hand side Viewport
* @return true if \p rhs and \p lhs are identical.
*/
friend bool operator==(Viewport const& lhs, Viewport const& rhs) noexcept {
return (&rhs == &lhs) ||
(rhs.left == lhs.left && rhs.bottom == lhs.bottom &&
rhs.width == lhs.width && rhs.height == lhs.height);
}
/**
* Compares two Viewports for inequality
* @param lhs reference to the left hand side Viewport
* @param rhs reference to the right hand side Viewport
* @return true if \p rhs and \p lhs are different.
*/
friend bool operator!=(Viewport const& lhs, Viewport const& rhs) noexcept {
return !(rhs == lhs);
}
};
} // namespace filament
#endif // TNT_FILAMENT_VIEWPORT_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,84 @@
/*
* 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_FILAMESHIO_FILAMESH_H
#define TNT_FILAMENT_FILAMESHIO_FILAMESH_H
#include <filament/Box.h>
namespace filamesh {
using Box = filament::Box;
static const char MAGICID[] { 'F', 'I', 'L', 'A', 'M', 'E', 'S', 'H' };
static const uint32_t VERSION = 1;
enum IndexType : uint32_t {
UI32 = 0,
UI16 = 1,
};
enum Flags : uint32_t {
INTERLEAVED = 1 << 0,
TEXCOORD_SNORM16 = 1 << 1,
COMPRESSION = 1 << 2,
};
// Each of these fields specifies a number of bytes within the compressed data. This is ignored
// when the INTERLEAVED flag is enabled.
struct CompressionHeader {
uint32_t positions;
uint32_t tangents;
uint32_t colors;
uint32_t uv0;
uint32_t uv1;
};
struct Header {
uint32_t version;
uint32_t parts;
Box aabb;
uint32_t flags;
uint32_t offsetPosition;
uint32_t stridePosition;
uint32_t offsetTangents;
uint32_t strideTangents;
uint32_t offsetColor;
uint32_t strideColor;
uint32_t offsetUV0;
uint32_t strideUV0;
uint32_t offsetUV1;
uint32_t strideUV1;
uint32_t vertexCount;
uint32_t vertexSize;
uint32_t indexType;
uint32_t indexCount;
uint32_t indexSize;
};
struct Part {
uint32_t offset;
uint32_t indexCount;
uint32_t minIndex;
uint32_t maxIndex;
uint32_t material;
Box aabb;
};
} // namespace filamesh
#endif // TNT_FILAMENT_FILAMESHIO_FILAMESH_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

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