remove windows specific headers

This commit is contained in:
Nick Fisher
2024-06-07 20:42:07 +10:00
parent 58d9ce04be
commit f7cc0ce6ad
159 changed files with 0 additions and 35936 deletions

View File

@@ -1,39 +0,0 @@
/*
* 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

@@ -1,223 +0,0 @@
/*
* 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

@@ -1,74 +0,0 @@
/*
* 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

@@ -1,28 +0,0 @@
/*
* 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

View File

@@ -1,136 +0,0 @@
/*
* 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 HwSync;
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 SyncHandle = Handle<HwSync>;
using TextureHandle = Handle<HwTexture>;
using TimerQueryHandle = Handle<HwTimerQuery>;
using VertexBufferHandle = Handle<HwVertexBuffer>;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_HANDLE_H

View File

@@ -1,48 +0,0 @@
/*
* 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

@@ -1,317 +0,0 @@
/*
* 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

@@ -1,86 +0,0 @@
/*
* 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>
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;
};
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;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H

View File

@@ -1,104 +0,0 @@
/*
* 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

@@ -1,129 +0,0 @@
/*
* 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;
};
using UniformBlockInfo = std::array<utils::CString, UNIFORM_BINDING_COUNT>;
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;
// 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;
// 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;
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; }
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;
}
private:
friend utils::io::ostream& operator<<(utils::io::ostream& out, const Program& builder);
UniformBlockInfo mUniformBlocks = {};
SamplerGroupInfo mSamplerGroups = {};
ShaderSource mShadersSource;
utils::CString mName;
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
utils::FixedCapacityVector<SpecializationConstant> mSpecializationConstants;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H

View File

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

View File

@@ -1,39 +0,0 @@
/*
* 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

@@ -1,92 +0,0 @@
/*
* 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

@@ -1,261 +0,0 @@
/*
* 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;
/**
* 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;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -1,71 +0,0 @@
/*
* 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
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

@@ -1,69 +0,0 @@
/*
* 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;
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

@@ -1,120 +0,0 @@
/*
* 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>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports EGL.
*/
class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
protected:
// --------------------------------------------------------------------------------------------
// 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;
/**
* 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;
// supported extensions detected at runtime
struct {
struct {
bool OES_EGL_image_external_essl3 = false;
} gl;
struct {
bool KHR_no_config_context = false;
bool KHR_gl_colorspace = false;
} egl;
} ext;
private:
void initializeGlExtensions() noexcept;
EGLConfig findSwapChainConfig(uint64_t flags) const;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H

View File

@@ -1,82 +0,0 @@
/*
* 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

@@ -1,37 +0,0 @@
/*
* 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

@@ -1,67 +0,0 @@
/*
* 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

@@ -1,64 +0,0 @@
/*
* 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>
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;
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 = {};
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H

View File

@@ -1,55 +0,0 @@
/*
* 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

@@ -1,49 +0,0 @@
/*
* 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>
namespace filament::backend {
/**
* A Platform interface that creates a Vulkan backend.
*/
class VulkanPlatform : public Platform {
public:
struct SurfaceBundle {
void* surface;
// On certain platforms, the extent of the surface cannot be queried from Vulkan. In those
// situations, we allow the frontend to pass in the extent to use in creating the swap
// chains. Platform implementation should set extent to 0 if they do not expect to set the
// swap chain extent.
uint32_t width;
uint32_t height;
};
// Given a Vulkan instance and native window handle, creates the platform-specific surface.
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept = 0;
~VulkanPlatform() override;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H

View File

@@ -1,85 +0,0 @@
/*
* 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

@@ -1,298 +0,0 @@
/*
* 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

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CAMUTILS_COMPILER_H
#define CAMUTILS_COMPILER_H
#if __has_attribute(visibility)
# define CAMUTILS_PUBLIC __attribute__((visibility("default")))
#else
# define CAMUTILS_PUBLIC
#endif
#endif // CAMUTILS_COMPILER_H

View File

@@ -1,98 +0,0 @@
/*
* 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

@@ -1,71 +0,0 @@
/*
* 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

@@ -1,861 +0,0 @@
/*
* 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;
// For finding properties and running semantic analysis, we always use the same code gen
// permutation. This is the first permutation generated with default arguments passed to matc.
static constexpr const CodeGenParams mSemanticCodeGenParams = {
.shaderModel = ShaderModel::MOBILE,
.targetApi = TargetApi::OPENGL,
.targetLanguage = TargetLanguage::SPIRV
};
// 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 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 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>;
//! 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,
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,
OutputType type, int location) noexcept
: name(outputName), qualifier(qualifier), target(target), type(type),
location(location) { }
utils::CString name;
VariableQualifier qualifier;
OutputTarget target;
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
private:
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() noexcept;
// Multiple calls to findProperties accumulate the property sets across fragment
// and vertex shaders in mProperties.
bool findProperties(filament::backend::ShaderStage type,
MaterialBuilder::PropertyList& p) noexcept;
bool runSemanticAnalysis(MaterialInfo const& info) 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 = {};
};
} // namespace filamat
template<> struct utils::EnableBitMaskOperators<filamat::MaterialBuilder::TargetApi>
: public std::true_type {};
#endif

View File

@@ -1,103 +0,0 @@
/*
* 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

@@ -1,242 +0,0 @@
/*
* 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:
/**
* 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 5 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;
};
/**
* 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:
enum class Kernel : uint8_t {
D_GGX, // Trowbridge-reitz distribution
};
/**
* 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 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{};
};
#endif //TNT_IBL_PREFILTER_IBLPREFILTER_H

View File

@@ -1,240 +0,0 @@
/*
* 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

@@ -1,117 +0,0 @@
/*
* 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

@@ -1,526 +0,0 @@
/*
* 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

@@ -1,214 +0,0 @@
/*
* 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

@@ -1,485 +0,0 @@
/*
* 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

@@ -1,256 +0,0 @@
/*
* 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-sRGB;
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
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

@@ -1,137 +0,0 @@
/*
* 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

@@ -1,761 +0,0 @@
/*
* 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 <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 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 {
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;
};
/**
* Creates an instance of Engine
*
* @param backend Which driver backend to use.
*
* @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.
*
* @param sharedGLContext A platform-dependant OpenGL context used as a shared context
* when creating filament's internal context.
* Setting this parameter will force filament to use the OpenGL
* implementation (instead of Vulkan for instance).
*
* @param config A pointer to optional parameters to specify memory size
* configuration options. If nullptr, then defaults used.
*
* @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.
*
* \remark
* This method is thread-safe.
*/
static Engine* create(Backend backend = Backend::DEFAULT,
Platform* platform = nullptr, void* sharedGLContext = nullptr,
const Config* config = nullptr);
#if UTILS_HAS_THREADING
/**
* A callback used with Engine::createAsync() called once the engine is initialized and it is
* safe to call Engine::getEngine(token). This callback is invoked from an arbitrary worker
* thread. Engine::getEngine() CANNOT be called from that thread, instead it must be called
* from the same thread than Engine::createAsync() was called from.
*
* @param user User provided parameter given in createAsync().
*
* @param token An opaque token used to call Engine::getEngine().
*/
using CreateCallback = void(void* user, void* token);
/**
* Creates an instance of Engine asynchronously
*
* @param callback Callback called once the engine is initialized and it is safe to
* call Engine::getEngine.
*
* @param user A user provided pointer that is given back to callback unmodified.
*
* @param backend Which driver backend to use.
*
* @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.
*
* @param sharedGLContext A platform-dependant OpenGL context used as a shared context
* when creating filament's internal context.
* Setting this parameter will force filament to use the OpenGL
* implementation (instead of Vulkan for instance).
*
* @param config A pointer to optional parameters to specify memory size
* configuration options
*/
static void createAsync(CreateCallback callback, void* user,
Backend backend = Backend::DEFAULT,
Platform* platform = nullptr, void* sharedGLContext = nullptr,
const Config* config = nullptr);
/**
* 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;
/**
* @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.
void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity
/**
* 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

@@ -1,129 +0,0 @@
/*
* 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

@@ -1,86 +0,0 @@
/*
* 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

@@ -1,61 +0,0 @@
/*
* 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

@@ -1,127 +0,0 @@
/*
* 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

@@ -1,125 +0,0 @@
/*
* 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

@@ -1,349 +0,0 @@
/*
* 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

@@ -1,964 +0,0 @@
/*
* 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

@@ -1,318 +0,0 @@
/*
* 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/DriverEnums.h>
#include <utils/compiler.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;
};
/**
* 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

@@ -1,94 +0,0 @@
/*
* 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"),
MaterialProperties = charTo64bitNum("MAT_PROP"),
MaterialConstants = charTo64bitNum("MAT_CONS"),
MaterialName = charTo64bitNum("MAT_NAME"),
MaterialVersion = charTo64bitNum("MAT_VERS"),
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

@@ -1,249 +0,0 @@
/*
* 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 <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 = 32;
/**
* 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
};
enum class UserVariantFilterBit : uint32_t {
DIRECTIONAL_LIGHTING = 0x01,
DYNAMIC_LIGHTING = 0x02,
SHADOW_RECEIVER = 0x04,
SKINNING = 0x08,
FOG = 0x10,
VSM = 0x20,
SSR = 0x40,
};
using UserVariantFilterMask = uint32_t;
} // namespace filament
#endif

View File

@@ -1,475 +0,0 @@
/*
* 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 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;
/**
* 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

@@ -1,143 +0,0 @@
/*
* 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

@@ -1,524 +0,0 @@
/*
* 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 simulate a more anisotropic phase-function.
*/
bool fogColorFromIbl = false;
/**
* 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

@@ -1,189 +0,0 @@
/*
* 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.
*
* All RenderTargets must have a non-null COLOR attachment.
*
* 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

@@ -1,763 +0,0 @@
/*
* 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 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;
/**
* 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 instance 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.
* It generally doesn't make sense to use VERTEX_DOMAIN_OBJECT in the material, since it
* would pull the same transform for all instances.
*
* @param instanceCount the number of instances silently clamped between 1 and 32767.
*/
Builder& instances(size_t instanceCount) 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;
/**
* 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

@@ -1,580 +0,0 @@
/*
* 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

@@ -1,175 +0,0 @@
/*
* 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

@@ -1,122 +0,0 @@
/*
* 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

@@ -1,181 +0,0 @@
/*
* 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

@@ -1,214 +0,0 @@
/*
* 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

@@ -1,259 +0,0 @@
/*
* 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

@@ -1,548 +0,0 @@
/*
* 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

@@ -1,205 +0,0 @@
/*
* 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

@@ -1,227 +0,0 @@
/*
* 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

@@ -1,316 +0,0 @@
/*
* 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

@@ -1,201 +0,0 @@
/*
* 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

@@ -1,839 +0,0 @@
/*
* 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.
*/
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;
/**
* 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

@@ -1,91 +0,0 @@
/*
* 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

@@ -1,120 +0,0 @@
/*
* 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

@@ -1,131 +0,0 @@
/*
* 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

@@ -1,334 +0,0 @@
/*
* 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

@@ -1,105 +0,0 @@
/*
* 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

@@ -1,120 +0,0 @@
/*
* 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

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

View File

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

View File

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

View File

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

View File

@@ -1,110 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GLTFIO_NODEMANAGER_H
#define GLTFIO_NODEMANAGER_H
#include <filament/FilamentAPI.h>
#include <utils/bitset.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/EntityInstance.h>
#include <utils/FixedCapacityVector.h>
namespace utils {
class Entity;
} // namespace utils
namespace filament::gltfio {
class FNodeManager;
/**
* NodeManager is used to add annotate entities with glTF-specific information.
*
* Node components are created by gltfio and exposed to users to allow inspection.
*
* Nodes do not store the glTF hierarchy or names; see TransformManager and NameComponentManager.
*/
class UTILS_PUBLIC NodeManager {
public:
using Instance = utils::EntityInstance<NodeManager>;
using Entity = utils::Entity;
using CString = utils::CString;
using SceneMask = utils::bitset32;
static constexpr size_t MAX_SCENE_COUNT = 32;
/**
* Returns whether a particular Entity is associated with a component of this NodeManager
* @param e An Entity.
* @return true if this Entity has a component associated with this manager.
*/
bool hasComponent(Entity e) const noexcept;
/**
* Gets an Instance representing the node component associated with the given Entity.
* @param e An Entity.
* @return An Instance object, which represents the node component associated with the Entity e.
* @note Use Instance::isValid() to make sure the component exists.
* @see hasComponent()
*/
Instance getInstance(Entity e) const noexcept;
/**
* Creates a node component and associates it with the given entity.
* @param entity An Entity to associate a node component with.
*
* If this component already exists on the given entity, it is first destroyed as if
* destroy(Entity e) was called.
*
* @see destroy()
*/
void create(Entity entity);
/**
* Destroys this component from the given entity.
* @param e An entity.
*
* @see create()
*/
void destroy(Entity e) noexcept;
void setMorphTargetNames(Instance ci, utils::FixedCapacityVector<CString> names) noexcept;
const utils::FixedCapacityVector<CString>& getMorphTargetNames(Instance ci) const noexcept;
void setExtras(Instance ci, CString extras) noexcept;
const CString& getExtras(Instance ci) const noexcept;
void setSceneMembership(Instance ci, SceneMask scenes) noexcept;
SceneMask getSceneMembership(Instance ci) const noexcept;
protected:
NodeManager() noexcept = default;
~NodeManager() = default;
public:
NodeManager(NodeManager const&) = delete;
NodeManager(NodeManager&&) = delete;
NodeManager& operator=(NodeManager const&) = delete;
NodeManager& operator=(NodeManager&&) = delete;
};
} // namespace filament::gltfio
#endif // GLTFIO_NODEMANAGER_H

View File

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

View File

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

View File

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

View File

@@ -1,128 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GLTFIO_MATH_H
#define GLTFIO_MATH_H
#include <math/quat.h>
#include <math/vec3.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/TVecHelpers.h>
#include <utils/compiler.h>
namespace filament::gltfio {
template <typename T>
UTILS_PUBLIC T cubicSpline(const T& vert0, const T& tang0, const T& vert1, const T& tang1, float t) {
float tt = t * t, ttt = tt * t;
float s2 = -2 * ttt + 3 * tt, s3 = ttt - tt;
float s0 = 1 - s2, s1 = s3 - tt + t;
T p0 = vert0;
T m0 = tang0;
T p1 = vert1;
T m1 = tang1;
return s0 * p0 + s1 * m0 * t + s2 * p1 + s3 * m1 * t;
}
UTILS_PUBLIC inline void decomposeMatrix(const filament::math::mat4f& mat, filament::math::float3* translation,
filament::math::quatf* rotation, filament::math::float3* scale) {
using namespace filament::math;
// Extract translation.
*translation = mat[3].xyz;
// Extract upper-left for determinant computation.
const float a = mat[0][0];
const float b = mat[0][1];
const float c = mat[0][2];
const float d = mat[1][0];
const float e = mat[1][1];
const float f = mat[1][2];
const float g = mat[2][0];
const float h = mat[2][1];
const float i = mat[2][2];
const float A = e * i - f * h;
const float B = f * g - d * i;
const float C = d * h - e * g;
// Extract scale.
const float det(a * A + b * B + c * C);
float scalex = length(float3({a, b, c}));
float scaley = length(float3({d, e, f}));
float scalez = length(float3({g, h, i}));
float3 s = { scalex, scaley, scalez };
if (det < 0) {
s = -s;
}
*scale = s;
// Remove scale from the matrix if it is not close to zero.
mat4f clone = mat;
if (std::abs(det) > std::numeric_limits<float>::epsilon()) {
clone[0] /= s.x;
clone[1] /= s.y;
clone[2] /= s.z;
// Extract rotation
*rotation = clone.toQuaternion();
} else {
// Set to identity if close to zero
*rotation = quatf(1.0f);
}
}
UTILS_PUBLIC inline filament::math::mat4f composeMatrix(const filament::math::float3& translation,
const filament::math::quatf& rotation, const filament::math::float3& scale) {
float tx = translation[0];
float ty = translation[1];
float tz = translation[2];
float qx = rotation[0];
float qy = rotation[1];
float qz = rotation[2];
float qw = rotation[3];
float sx = scale[0];
float sy = scale[1];
float sz = scale[2];
return filament::math::mat4f(
(1 - 2 * qy*qy - 2 * qz*qz) * sx,
(2 * qx*qy + 2 * qz*qw) * sx,
(2 * qx*qz - 2 * qy*qw) * sx,
0.f,
(2 * qx*qy - 2 * qz*qw) * sy,
(1 - 2 * qx*qx - 2 * qz*qz) * sy,
(2 * qy*qz + 2 * qx*qw) * sy,
0.f,
(2 * qx*qz + 2 * qy*qw) * sz,
(2 * qy*qz - 2 * qx*qw) * sz,
(1 - 2 * qx*qx - 2 * qy*qy) * sz,
0.f, tx, ty, tz, 1.f);
}
inline filament::math::mat3f matrixFromUvTransform(const float offset[2], float rotation,
const float scale[2]) {
float tx = offset[0];
float ty = offset[1];
float sx = scale[0];
float sy = scale[1];
float c = cos(rotation);
float s = sin(rotation);
return filament::math::mat3f(sx * c, sx * s, tx, -sy * s, sy * c, ty, 0.0f, 0.0f, 1.0f);
};
} // namespace filament::gltfio
#endif // GLTFIO_MATH_H

View File

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

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IBL_CUBEMAPIBL_H
#define IBL_CUBEMAPIBL_H
#include <math/vec3.h>
#include <utils/Slice.h>
#include <utils/compiler.h>
#include <vector>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class Cubemap;
class Image;
/**
* Generates cubemaps for the IBL.
*/
class UTILS_PUBLIC CubemapIBL {
public:
typedef void (*Progress)(size_t, float, void*);
/**
* Computes a roughness LOD using prefiltered importance sampling GGX
*
* @param dst the destination cubemap
* @param levels a list of prefiltered lods of the source environment
* @param linearRoughness roughness
* @param maxNumSamples number of samples for importance sampling
* @param updater a callback for the caller to track progress
*/
static void roughnessFilter(
utils::JobSystem& js, Cubemap& dst, const utils::Slice<Cubemap>& levels,
float linearRoughness, size_t maxNumSamples, math::float3 mirror, bool prefilter,
Progress updater = nullptr, void* userdata = nullptr);
static void roughnessFilter(
utils::JobSystem& js, Cubemap& dst, const std::vector<Cubemap>& levels,
float linearRoughness, size_t maxNumSamples, math::float3 mirror, bool prefilter,
Progress updater = nullptr, void* userdata = nullptr);
//! Computes the "DFG" term of the "split-sum" approximation and stores it in a 2D image
static void DFG(utils::JobSystem& js, Image& dst, bool multiscatter, bool cloth);
/**
* Computes the diffuse irradiance using prefiltered importance sampling GGX
*
* @note Usually this is done using spherical harmonics instead.
*
* @param dst the destination cubemap
* @param levels a list of prefiltered lods of the source environment
* @param maxNumSamples number of samples for importance sampling
* @param updater a callback for the caller to track progress
*
* @see CubemapSH
*/
static void diffuseIrradiance(utils::JobSystem& js, Cubemap& dst, const std::vector<Cubemap>& levels,
size_t maxNumSamples = 1024, Progress updater = nullptr, void* userdata = nullptr);
// for debugging. ignore.
static void brdf(utils::JobSystem& js, Cubemap& dst, float linearRoughness);
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAPIBL_H */

View File

@@ -1,125 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IBL_CUBEMAPSH_H
#define IBL_CUBEMAPSH_H
#include <utils/compiler.h>
#include <math/mat3.h>
#include <math/vec3.h>
#include <memory>
#include <vector>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class Cubemap;
/**
* Computes spherical harmonics
*/
class UTILS_PUBLIC CubemapSH {
public:
/**
* Spherical Harmonics decomposition of the given cubemap
* Optionally calculates irradiance by convolving with truncated cos.
*/
static std::unique_ptr<math::float3[]> computeSH(
utils::JobSystem& js, const Cubemap& cm, size_t numBands, bool irradiance);
/**
* Render given spherical harmonics into a cubemap
*/
static void renderSH(utils::JobSystem& js, Cubemap& cm,
const std::unique_ptr<math::float3[]>& sh, size_t numBands);
static void windowSH(std::unique_ptr<math::float3[]>& sh, size_t numBands, float cutoff);
/**
* Compute spherical harmonics of the irradiance of the given cubemap.
* The SH basis are pre-scaled for easier rendering by the shader. The resulting coefficients
* are not spherical harmonics (as they're scalled by various factors). In particular they
* cannot be rendered with renderSH() above. Instead use renderPreScaledSH3Bands() which
* is exactly the code ran by our shader.
*/
static void preprocessSHForShader(std::unique_ptr<math::float3[]>& sh);
/**
* Render pre-scaled irrandiance SH
*/
static void renderPreScaledSH3Bands(utils::JobSystem& js, Cubemap& cm,
const std::unique_ptr<math::float3[]>& sh);
static constexpr size_t getShIndex(ssize_t m, size_t l) {
return SHindex(m, l);
}
private:
class float5 {
float v[5];
public:
float5() = default;
constexpr float5(float a, float b, float c, float d, float e) : v{ a, b, c, d, e } {}
constexpr float operator[](size_t i) const { return v[i]; }
float& operator[](size_t i) { return v[i]; }
};
static inline const float5 multiply(const float5 M[5], float5 x) noexcept {
return float5{
M[0][0] * x[0] + M[1][0] * x[1] + M[2][0] * x[2] + M[3][0] * x[3] + M[4][0] * x[4],
M[0][1] * x[0] + M[1][1] * x[1] + M[2][1] * x[2] + M[3][1] * x[3] + M[4][1] * x[4],
M[0][2] * x[0] + M[1][2] * x[1] + M[2][2] * x[2] + M[3][2] * x[3] + M[4][2] * x[4],
M[0][3] * x[0] + M[1][3] * x[1] + M[2][3] * x[2] + M[3][3] * x[3] + M[4][3] * x[4],
M[0][4] * x[0] + M[1][4] * x[1] + M[2][4] * x[2] + M[3][4] * x[3] + M[4][4] * x[4]
};
};
static inline constexpr size_t SHindex(ssize_t m, size_t l) {
return l * (l + 1) + m;
}
static void computeShBasis(float* SHb, size_t numBands, const math::float3& s);
static float Kml(ssize_t m, size_t l);
static std::vector<float> Ki(size_t numBands);
static constexpr float computeTruncatedCosSh(size_t l);
static float sincWindow(size_t l, float w);
static math::float3 rotateShericalHarmonicBand1(math::float3 band1, math::mat3f const& M);
static float5 rotateShericalHarmonicBand2(float5 const& band2, math::mat3f const& M);
// debugging only...
static float Legendre(ssize_t l, ssize_t m, float x);
static float TSH(int l, int m, const math::float3& d);
static void printShBase(std::ostream& out, int l, int m);
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAPSH_H */

View File

@@ -1,124 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IBL_CUBEMAP_UTILS_H
#define IBL_CUBEMAP_UTILS_H
#include <ibl/Cubemap.h>
#include <ibl/Image.h>
#include <utils/compiler.h>
#include <functional>
namespace utils {
class JobSystem;
} // namespace utils
namespace filament {
namespace ibl {
class CubemapIBL;
/**
* Create and convert Cubemap formats
*/
class UTILS_PUBLIC CubemapUtils {
public:
//! Creates a cubemap object and its backing Image
static Cubemap create(Image& image, size_t dim, bool horizontal = true);
struct EmptyState {
};
template<typename STATE>
using ScanlineProc = std::function<
void(STATE& state, size_t y, Cubemap::Face f, Cubemap::Texel* data, size_t width)>;
template<typename STATE>
using ReduceProc = std::function<void(STATE& state)>;
//! process the cubemap using multithreading
template<typename STATE>
static void process(Cubemap& cm,
utils::JobSystem& js,
ScanlineProc<STATE> proc,
ReduceProc<STATE> reduce = [](STATE&) {},
const STATE& prototype = STATE());
//! process the cubemap
template<typename STATE>
static void processSingleThreaded(Cubemap& cm,
utils::JobSystem& js,
ScanlineProc<STATE> proc,
ReduceProc<STATE> reduce = [](STATE&) {},
const STATE& prototype = STATE());
//! clamps image to acceptable range
static void clamp(Image& src);
static void highlight(Image& src);
//! Downsamples a cubemap by helf in x and y using a box filter
static void downsampleCubemapLevelBoxFilter(utils::JobSystem& js, Cubemap& dst, const Cubemap& src);
//! Return the name of a face (suitable for a file name)
static const char* getFaceName(Cubemap::Face face);
//! computes the solid angle of a pixel of a face of a cubemap
static float solidAngle(size_t dim, size_t u, size_t v);
//! Sets a Cubemap faces from a cross image
static void setAllFacesFromCross(Cubemap& cm, const Image& image);
private:
//move these into cmgen?
static void setFaceFromCross(Cubemap& cm, Cubemap::Face face, const Image& image);
static Image createCubemapImage(size_t dim, bool horizontal = true);
#ifndef FILAMENT_IBL_LITE
public:
//! Converts horizontal or vertical cross Image to a Cubemap
static void crossToCubemap(utils::JobSystem& js, Cubemap& dst, const Image& src);
//! Converts equirectangular Image to a Cubemap
static void equirectangularToCubemap(utils::JobSystem& js, Cubemap& dst, const Image& src);
//! Converts a Cubemap to an equirectangular Image
static void cubemapToEquirectangular(utils::JobSystem& js, Image& dst, const Cubemap& src);
//! Converts a Cubemap to an octahedron
static void cubemapToOctahedron(utils::JobSystem& js, Image& dst, const Cubemap& src);
//! mirror the cubemap in the horizontal direction
static void mirrorCubemap(utils::JobSystem& js, Cubemap& dst, const Cubemap& src);
//! generates a UV grid in the cubemap -- useful for debugging.
static void generateUVGrid(utils::JobSystem& js, Cubemap& cml, size_t gridFrequencyX, size_t gridFrequencyY);
#endif
friend class CubemapIBL;
};
} // namespace ibl
} // namespace filament
#endif /* IBL_CUBEMAP_UTILS_H */

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IBL_IMAGE_H
#define IBL_IMAGE_H
#include <math/scalar.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/compiler.h>
#include <memory>
namespace filament {
namespace ibl {
class UTILS_PUBLIC Image {
public:
Image();
Image(size_t w, size_t h, size_t stride = 0);
void reset();
void set(Image const& image);
void subset(Image const& image, size_t x, size_t y, size_t w, size_t h);
bool isValid() const { return mData != nullptr; }
size_t getWidth() const { return mWidth; }
size_t getStride() const { return mBpr / getBytesPerPixel(); }
size_t getHeight() const { return mHeight; }
size_t getBytesPerRow() const { return mBpr; }
size_t getBytesPerPixel() const { return sizeof(math::float3); }
void* getData() const { return mData; }
size_t getSize() const { return mBpr * mHeight; }
void* getPixelRef(size_t x, size_t y) const;
std::unique_ptr<uint8_t[]> detach() { return std::move(mOwnedData); }
private:
size_t mBpr = 0;
size_t mWidth = 0;
size_t mHeight = 0;
std::unique_ptr<uint8_t[]> mOwnedData;
void* mData = nullptr;
};
inline void* Image::getPixelRef(size_t x, size_t y) const {
return static_cast<uint8_t*>(mData) + y * getBytesPerRow() + x * getBytesPerPixel();
}
} // namespace ibl
} // namespace filament
#endif /* IBL_IMAGE_H */

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IBL_UTILITIES_H
#define IBL_UTILITIES_H
#include <math.h>
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament {
namespace ibl {
template<typename T>
static inline constexpr T sq(T x) {
return x * x;
}
template<typename T>
static inline constexpr T log4(T x) {
// log2(x)/log2(4)
// log2(x)/2
return std::log2(x) * T(0.5);
}
inline bool isPOT(size_t x) {
return !(x & (x - 1));
}
inline filament::math::float2 hammersley(uint32_t i, float iN) {
constexpr float tof = 0.5f / 0x80000000U;
uint32_t bits = i;
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return { i * iN, bits * tof };
}
} // namespace ibl
} // namespace filament
#endif /* IBL_UTILITIES_H */

View File

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

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IMAGE_IMAGEOPS_H
#define IMAGE_IMAGEOPS_H
#include <image/LinearImage.h>
#include <utils/compiler.h>
#include <cstddef>
#include <initializer_list>
namespace image {
// Concatenates images horizontally to create a filmstrip atlas, similar to numpy's hstack.
UTILS_PUBLIC LinearImage horizontalStack(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage horizontalStack(LinearImage const* img, size_t count);
// Concatenates images vertically to create a filmstrip atlas, similar to numpy's vstack.
UTILS_PUBLIC LinearImage verticalStack(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage verticalStack(LinearImage const* img, size_t count);
// Horizontally or vertically mirror the given image.
UTILS_PUBLIC LinearImage horizontalFlip(const LinearImage& image);
UTILS_PUBLIC LinearImage verticalFlip(const LinearImage& image);
// Transforms normals (components live in [-1,+1]) into colors (components live in [0,+1]).
UTILS_PUBLIC LinearImage vectorsToColors(const LinearImage& image);
UTILS_PUBLIC LinearImage colorsToVectors(const LinearImage& image);
// Creates a single-channel image by extracting the selected channel.
UTILS_PUBLIC LinearImage extractChannel(const LinearImage& image, uint32_t channel);
// Constructs a multi-channel image by copying data from a sequence of single-channel images.
UTILS_PUBLIC LinearImage combineChannels(std::initializer_list<LinearImage> images);
UTILS_PUBLIC LinearImage combineChannels(LinearImage const* img, size_t count);
// Generates a new image with rows & columns swapped.
UTILS_PUBLIC LinearImage transpose(const LinearImage& image);
// Extracts pixels by specifying a crop window where (0,0) is the top-left corner of the image.
// The boundary is specified as Left Top Right Bottom.
UTILS_PUBLIC
LinearImage cropRegion(const LinearImage& image, uint32_t l, uint32_t t, uint32_t r, uint32_t b);
// Lexicographically compares two images, similar to memcmp.
UTILS_PUBLIC int compare(const LinearImage& a, const LinearImage& b, float epsilon = 0.0f);
// Sets all pixels in all channels to the given value.
UTILS_PUBLIC void clearToValue(LinearImage& img, float value);
// Called by the coordinate field generator to query if a pixel is within the region of interest.
using PresenceCallback = bool(*)(const LinearImage& img, uint32_t col, uint32_t row, void* user);
// Generates a two-channel field of non-normalized coordinates that indicate the nearest pixel
// whose presence function returns true. This is the first step before generating a distance
// field or generalized Voronoi map.
UTILS_PUBLIC
LinearImage computeCoordField(const LinearImage& src, PresenceCallback presence, void* user);
// Generates a single-channel Euclidean distance field with positive values outside the region
// of interest in the source image, and zero values inside. If sqrt is false, the computed
// distances are squared. If signed distance (SDF) is desired, this function can be called a second
// time using an inverted source field.
UTILS_PUBLIC LinearImage edtFromCoordField(const LinearImage& coordField, bool sqrt);
// Dereferences the given coordinate field. Useful for creating Voronoi diagrams or dilated images.
UTILS_PUBLIC
LinearImage voronoiFromCoordField(const LinearImage& coordField, const LinearImage& src);
// Copies content of a source image into a target image. Requires width/height/channels to match.
UTILS_PUBLIC void blitImage(LinearImage& target, const LinearImage& source);
} // namespace image
#endif /* IMAGE_LINEARIMAGE_H */

View File

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

View File

@@ -1,289 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IMAGE_KTX1BUNDLE_H
#define IMAGE_KTX1BUNDLE_H
#include <math/vec3.h>
#include <utils/compiler.h>
#include <cstdint>
#include <memory>
namespace image {
struct KtxInfo {
uint32_t endianness;
uint32_t glType;
uint32_t glTypeSize;
uint32_t glFormat;
uint32_t glInternalFormat;
uint32_t glBaseInternalFormat;
uint32_t pixelWidth;
uint32_t pixelHeight;
uint32_t pixelDepth;
};
struct KtxBlobIndex {
uint32_t mipLevel;
uint32_t arrayIndex;
uint32_t cubeFace;
};
struct KtxBlobList;
struct KtxMetadata;
/**
* Ktx1Bundle is a structured set of opaque data blobs that can be passed straight to the GPU, such
* that a single bundle corresponds to a single texture object. It is well suited for storing
* block-compressed texture data.
*
* One bundle may be comprised of several mipmap levels, cubemap faces, and array elements. The
* number of blobs is immutable, and is determined as follows.
*
* blob_count = mip_count * array_length * (cubemap ? 6 : 1)
*
* Bundles can be quickly serialized to a certain file format (see below link), but this class lives
* in the image lib rather than imageio because it has no dependencies, and does not support CPU
* decoding.
*
* https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
*/
class UTILS_PUBLIC Ktx1Bundle {
public:
~Ktx1Bundle();
/**
* Creates a hierarchy of empty texture blobs, to be filled later via setBlob().
*/
Ktx1Bundle(uint32_t numMipLevels, uint32_t arrayLength, bool isCubemap);
/**
* Creates a new bundle by deserializing the given data.
*
* Typically, this constructor is used to consume the contents of a KTX file.
*/
Ktx1Bundle(uint8_t const* bytes, uint32_t nbytes);
/**
* Serializes the bundle into the given target memory. Returns false if there's not enough
* memory.
*
* Typically, this method is used to write out the contents of a KTX file.
*/
bool serialize(uint8_t* destination, uint32_t numBytes) const;
/**
* Computes the size (in bytes) of the serialized bundle.
*/
uint32_t getSerializedLength() const;
/**
* Gets or sets information about the texture object, such as format and type.
*/
KtxInfo const& getInfo() const { return mInfo; }
KtxInfo& info() { return mInfo; }
/**
* Gets or sets key/value metadata.
*/
const char* getMetadata(const char* key, size_t* valueSize = nullptr) const;
void setMetadata(const char* key, const char* value);
/**
* Parses the key="sh" metadata and returns 3 bands of data.
*
* Assumes 3 bands for a total of 9 RGB coefficients.
* Returns true if successful.
*/
bool getSphericalHarmonics(filament::math::float3* result);
/**
* Gets the number of miplevels (this is never zero).
*/
uint32_t getNumMipLevels() const { return mNumMipLevels; }
/**
* Gets the number of array elements (this is never zero).
*/
uint32_t getArrayLength() const { return mArrayLength; }
/**
* Returns whether or not this is a cubemap.
*/
bool isCubemap() const { return mNumCubeFaces > 1; }
/**
* Retrieves a weak reference to a given data blob. Returns false if the given blob index is out
* of bounds, or if the blob at the given index is empty.
*/
bool getBlob(KtxBlobIndex index, uint8_t** data, uint32_t* size) const;
/**
* Copies the given data into the blob at the given index, replacing whatever is already there.
* Returns false if the given blob index is out of bounds.
*/
bool setBlob(KtxBlobIndex index, uint8_t const* data, uint32_t size);
/**
* Allocates the blob at the given index to the given number of bytes. This allows subsequent
* calls to setBlob to be thread-safe.
*/
bool allocateBlob(KtxBlobIndex index, uint32_t size);
// The following constants help clients populate the "info" struct. Most of them have corollary
// constants in the OpenGL headers.
static constexpr uint32_t R8 = 0x8229;
static constexpr uint32_t R8_SNORM = 0x8F94;
static constexpr uint32_t R8UI = 0x8232;
static constexpr uint32_t R8I = 0x8231;
static constexpr uint32_t STENCIL_INDEX8 = 0x8D48;
static constexpr uint32_t R16F = 0x822D;
static constexpr uint32_t R16UI = 0x8234;
static constexpr uint32_t R16I = 0x8233;
static constexpr uint32_t RG8 = 0x822B;
static constexpr uint32_t RG8_SNORM = 0x8F95;
static constexpr uint32_t RG8UI = 0x8238;
static constexpr uint32_t RG8I = 0x8237;
static constexpr uint32_t RGB565 = 0x8D62;
static constexpr uint32_t RGB5_A1 = 0x8057;
static constexpr uint32_t RGBA4 = 0x8056;
static constexpr uint32_t DEPTH_COMPONENT16 = 0x81A5;
static constexpr uint32_t RGB8 = 0x8051;
static constexpr uint32_t SRGB8 = 0x8C41;
static constexpr uint32_t RGB8_SNORM = 0x8F96;
static constexpr uint32_t RGB8UI = 0x8D7D;
static constexpr uint32_t RGB8I = 0x8D8F;
static constexpr uint32_t DEPTH_COMPONENT24 = 0x81A6;
static constexpr uint32_t R32F = 0x822E;
static constexpr uint32_t R32UI = 0x8236;
static constexpr uint32_t R32I = 0x8235;
static constexpr uint32_t RG16F = 0x822F;
static constexpr uint32_t RG16UI = 0x823A;
static constexpr uint32_t RG16I = 0x8239;
static constexpr uint32_t R11F_G11F_B10F = 0x8C3A;
static constexpr uint32_t RGB9_E5 = 0x8C3D;
static constexpr uint32_t RGBA8 = 0x8058;
static constexpr uint32_t SRGB8_ALPHA8 = 0x8C43;
static constexpr uint32_t RGBA8_SNORM = 0x8F97;
static constexpr uint32_t RGB10_A2 = 0x8059;
static constexpr uint32_t RGBA8UI = 0x8D7C;
static constexpr uint32_t RGBA8I = 0x8D8E;
static constexpr uint32_t DEPTH_COMPONENT32F = 0x8CAC;
static constexpr uint32_t DEPTH24_STENCIL8 = 0x88F0;
static constexpr uint32_t DEPTH32F_STENCIL8 = 0x8CAD;
static constexpr uint32_t RGB16F = 0x881B;
static constexpr uint32_t RGB16UI = 0x8D77;
static constexpr uint32_t RGB16I = 0x8D89;
static constexpr uint32_t RG32F = 0x8230;
static constexpr uint32_t RG32UI = 0x823C;
static constexpr uint32_t RG32I = 0x823B;
static constexpr uint32_t RGBA16F = 0x881A;
static constexpr uint32_t RGBA16UI = 0x8D76;
static constexpr uint32_t RGBA16I = 0x8D88;
static constexpr uint32_t RGB32F = 0x8815;
static constexpr uint32_t RGB32UI = 0x8D71;
static constexpr uint32_t RGB32I = 0x8D83;
static constexpr uint32_t RGBA32F = 0x8814;
static constexpr uint32_t RGBA32UI = 0x8D70;
static constexpr uint32_t RGBA32I = 0x8D82;
static constexpr uint32_t RED = 0x1903;
static constexpr uint32_t RG = 0x8227;
static constexpr uint32_t RGB = 0x1907;
static constexpr uint32_t RGBA = 0x1908;
static constexpr uint32_t BGR = 0x80E0;
static constexpr uint32_t BGRA = 0x80E1;
static constexpr uint32_t LUMINANCE = 0x1909;
static constexpr uint32_t LUMINANCE_ALPHA = 0x190A;
static constexpr uint32_t UNSIGNED_BYTE = 0x1401;
static constexpr uint32_t UNSIGNED_SHORT = 0x1403;
static constexpr uint32_t HALF_FLOAT = 0x140B;
static constexpr uint32_t FLOAT = 0x1406;
static constexpr uint32_t ENDIAN_DEFAULT = 0x04030201;
static constexpr uint32_t RGB_S3TC_DXT1 = 0x83F0;
static constexpr uint32_t RGBA_S3TC_DXT1 = 0x83F1;
static constexpr uint32_t RGBA_S3TC_DXT3 = 0x83F2;
static constexpr uint32_t RGBA_S3TC_DXT5 = 0x83F3;
static constexpr uint32_t R_RGTC_BC4_UNORM = 0x8DBB;
static constexpr uint32_t R_RGTC_BC4_SNORM = 0x8DBC;
static constexpr uint32_t RG_RGTC_BC5_UNORM = 0x8DBD;
static constexpr uint32_t RG_RGTC_BC5_SNORM = 0x8DBE;
static constexpr uint32_t RGBA_BPTC_BC7 = 0x8E8C;
static constexpr uint32_t SRGB8_ALPHA8_BPTC_BC7 = 0x8E8D;
static constexpr uint32_t RGB_BPTC_BC6H_SNORM = 0x8E8E;
static constexpr uint32_t RGB_BPTC_BC6H_UNORM = 0x8E8F;
static constexpr uint32_t RGBA_ASTC_4x4 = 0x93B0;
static constexpr uint32_t RGBA_ASTC_5x4 = 0x93B1;
static constexpr uint32_t RGBA_ASTC_5x5 = 0x93B2;
static constexpr uint32_t RGBA_ASTC_6x5 = 0x93B3;
static constexpr uint32_t RGBA_ASTC_6x6 = 0x93B4;
static constexpr uint32_t RGBA_ASTC_8x5 = 0x93B5;
static constexpr uint32_t RGBA_ASTC_8x6 = 0x93B6;
static constexpr uint32_t RGBA_ASTC_8x8 = 0x93B7;
static constexpr uint32_t RGBA_ASTC_10x5 = 0x93B8;
static constexpr uint32_t RGBA_ASTC_10x6 = 0x93B9;
static constexpr uint32_t RGBA_ASTC_10x8 = 0x93BA;
static constexpr uint32_t RGBA_ASTC_10x10 = 0x93BB;
static constexpr uint32_t RGBA_ASTC_12x10 = 0x93BC;
static constexpr uint32_t RGBA_ASTC_12x12 = 0x93BD;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_4x4 = 0x93D0;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_5x4 = 0x93D1;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_5x5 = 0x93D2;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_6x5 = 0x93D3;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_6x6 = 0x93D4;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_8x5 = 0x93D5;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_8x6 = 0x93D6;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_8x8 = 0x93D7;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_10x5 = 0x93D8;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_10x6 = 0x93D9;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_10x8 = 0x93DA;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_10x10 = 0x93DB;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_12x10 = 0x93DC;
static constexpr uint32_t SRGB8_ALPHA8_ASTC_12x12 = 0x93DD;
static constexpr uint32_t R11_EAC = 0x9270;
static constexpr uint32_t SIGNED_R11_EAC = 0x9271;
static constexpr uint32_t RG11_EAC = 0x9272;
static constexpr uint32_t SIGNED_RG11_EAC = 0x9273;
static constexpr uint32_t RGB8_ETC2 = 0x9274;
static constexpr uint32_t SRGB8_ETC2 = 0x9275;
static constexpr uint32_t RGB8_ALPHA1_ETC2 = 0x9276;
static constexpr uint32_t SRGB8_ALPHA1_ETC = 0x9277;
static constexpr uint32_t RGBA8_ETC2_EAC = 0x9278;
static constexpr uint32_t SRGB8_ALPHA8_ETC2_EAC = 0x9279;
private:
image::KtxInfo mInfo = {};
uint32_t mNumMipLevels;
uint32_t mArrayLength;
uint32_t mNumCubeFaces;
std::unique_ptr<KtxBlobList> mBlobs;
std::unique_ptr<KtxMetadata> mMetadata;
};
} // namespace image
#endif /* IMAGE_Ktx1Bundle_H */

View File

@@ -1,121 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IMAGE_LINEARIMAGE_H
#define IMAGE_LINEARIMAGE_H
#include <utils/compiler.h>
#include <cstdint>
/**
* Types and free functions for the Filament core imaging library, primarily used for offline tools,
* but with minimal dependencies to support potential use by the renderer.
*/
namespace image {
/**
* LinearImage is a handle to packed floating point data arranged into a row-major grid.
*
* We use this object as input/output for core algorithms that wish to be agnostic of source and
* destination formats. The number of channels is arbitrary (1 or more) but we often use 3-channel
* images to represent color data.
*
* The underlying pixel data has shared ownership semantics to allow clients to easily pass around
* the image object without incurring a deep copy. Shared access to pixels is not thread safe.
*
* By convention, we do not use channel major order (i.e. planar). However we provide a free
* function in ImageOps to combine planar data. Pixels are stored such that the row stride is simply
* width * channels * sizeof(float).
*/
class UTILS_PUBLIC LinearImage {
public:
~LinearImage();
/**
* Allocates a zeroed-out image.
*/
LinearImage(uint32_t width, uint32_t height, uint32_t channels);
/**
* Makes a shallow copy with shared pixel data.
*/
LinearImage(const LinearImage& that);
LinearImage& operator=(const LinearImage& that);
/**
* Creates an empty (invalid) image.
*/
LinearImage() : mDataRef(nullptr), mData(nullptr), mWidth(0), mHeight(0), mChannels(0) {}
operator bool() const { return mData != nullptr; }
/**
* Gets a pointer to the underlying pixel data.
*/
float* getPixelRef() { return mData; }
template<typename T> T* get() { return reinterpret_cast<T*>(mData); }
/**
* Gets a pointer to immutable pixel data.
*/
float const* getPixelRef() const { return mData; }
template<typename T> T const* get() const { return reinterpret_cast<T const*>(mData); }
/**
* Gets a pointer to the pixel data at the given column and row. (not bounds checked)
*/
float* getPixelRef(uint32_t column, uint32_t row) {
return mData + (column + row * mWidth) * mChannels;
}
template<typename T>
T* get(uint32_t column, uint32_t row) {
return reinterpret_cast<T*>(getPixelRef(column, row));
}
/**
* Gets a pointer to the immutable pixel data at the given column and row. (not bounds checked)
*/
float const* getPixelRef(uint32_t column, uint32_t row) const {
return mData + (column + row * mWidth) * mChannels;
}
template<typename T>
T const* get(uint32_t column, uint32_t row) const {
return reinterpret_cast<T const*>(getPixelRef(column, row));
}
uint32_t getWidth() const { return mWidth; }
uint32_t getHeight() const { return mHeight; }
uint32_t getChannels() const { return mChannels; }
void reset() { *this = LinearImage(); }
bool isValid() const { return mData; }
private:
struct SharedReference;
SharedReference* mDataRef = nullptr;
float* mData;
uint32_t mWidth;
uint32_t mHeight;
uint32_t mChannels;
};
} // namespace image
#endif /* IMAGE_LINEARIMAGE_H */

View File

@@ -1,170 +0,0 @@
/*
* 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 IMAGE_BASISENCODER_H_
#define IMAGE_BASISENCODER_H_
#include <stddef.h>
#include <stdint.h>
#include <utils/compiler.h>
#include <image/LinearImage.h>
namespace image {
struct BasisEncoderBuilderImpl;
struct BasisEncoderImpl;
class UTILS_PUBLIC BasisEncoder {
public:
enum class IntermediateFormat {
UASTC,
ETC1S,
};
class Builder {
public:
/**
* Constructs a Ktx2 builder with a fixed number of miplevels and layers.
*
* The number of mips and layers is required up front to allow pre-allocation of the
* appropriate BasisU input vectors.
*
* @param mipCount number of mipmap levels, including the base; must be at least 1.
* @param layerCount either 1 or the number of layers in an array texture.
*
* For cubemaps and cubemap arrays, multiply the layer count by 6 and pack the faces in
* standard GL order.
*/
Builder(size_t mipCount, size_t layerCount) noexcept;
~Builder() noexcept;
Builder(Builder&& that) noexcept;
Builder& operator=(Builder&& that) noexcept;
/**
* Enables the linear flag. (default value: FALSE)
*
* This does two things:
* (1) Specifies that the image should be encoded without a transfer function.
* (2) Adds a tag to the ktx file that tells the loader that no transfer function was used.
*
* Note that the tag does not actually affect the compression process, it's basically just a
* hint to the reader. At the time of this writing, BasisU does not make a distinction
* between sRGB targets and linear targets.
*/
Builder& linear(bool enabled) noexcept;
/**
* Enables cubemap or cubemap array mode. (default value: FALSE)
*
* When this is enabled the number of layers should be divisible by 6.
*/
Builder& cubemap(bool enabled) noexcept;
/**
* Chooses the intermediate format as described in the BasisU docs. (default value: UASTC)
*
* For highest quality, use UASTC.
*/
Builder& intermediateFormat(IntermediateFormat format) noexcept;
/**
* Specifies that only the first component of the incoming LinearImage should be honored.
*
* default value: FALSE
*/
Builder& grayscale(bool enabled) noexcept;
/**
* Specifies that the incoming image should be transfored from [-1, +1] to [0, 1] before it
* passed to the Basis encoder.
*
* default value: FALSE
*/
Builder& normals(bool enabled) noexcept;
/**
* Initializes the basis encoder with the given number of jobs.
*
* default value: 4
*/
Builder& jobs(size_t count) noexcept;
/**
* Supresses status messages.
*
* default value: FALSE
*/
Builder& quiet(bool enabled) noexcept;
/**
* Submits image data in linear floating-point format.
*
* This must be called for every miplevel.
*/
Builder& miplevel(size_t mipIndex, size_t layerIndex, const LinearImage& image) noexcept;
/**
* Creates a BasisU encoder and returns null if an error occurred.
*/
BasisEncoder* build();
private:
BasisEncoderBuilderImpl* mImpl;
Builder(const Builder&) = delete;
Builder& operator=(const Builder&) = delete;
};
~BasisEncoder() noexcept;
BasisEncoder(BasisEncoder&& that) noexcept;
BasisEncoder& operator=(BasisEncoder&& that) noexcept;
/**
* Triggers compression of all miplevels and waits until all jobs are done.
*
* The resulting KTX2 contents can be retrieved using the getters below.
*
* @returns false if an error occurred.
*/
bool encode();
/**
* Gets the number of bytes in the generated KTX2 file.
*
* This can only be called if encode() is successfully called first.
*/
size_t getKtx2ByteCount() const noexcept;
/**
* Gets the content of the generated KTX2 file.
*
* This memory is owned by BasisEncoder and is freed when the encoder is freed.
* This can only be called if encode() is successfully called first.
*/
uint8_t const* getKtx2Data() const noexcept;
private:
BasisEncoder(BasisEncoderImpl*) noexcept;
BasisEncoder(const BasisEncoder&) = delete;
BasisEncoder& operator=(const BasisEncoder&) = delete;
BasisEncoderImpl* mImpl;
friend struct BasisEncoderBuilderImpl;
};
} // namespace image
#endif // IMAGE_BASISENCODER_H_

View File

@@ -1,47 +0,0 @@
/*
* 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 IMAGE_HDRDECODER_H_
#define IMAGE_HDRDECODER_H_
#include <imageio/ImageDecoder.h>
namespace image {
class HDRDecoder : public ImageDecoder::Decoder {
public:
static HDRDecoder* create(std::istream& stream);
static bool checkSignature(char const* buf);
HDRDecoder(const HDRDecoder&) = delete;
HDRDecoder& operator=(const HDRDecoder&) = delete;
private:
explicit HDRDecoder(std::istream& stream);
~HDRDecoder() override;
// ImageDecoder::Decoder interface
LinearImage decode() override;
static const char sigRadiance[];
static const char sigRGBE[];
std::istream& mStream;
std::streampos mStreamStartPos;
};
} // namespace image
#endif /* IMAGE_IMAGEDECODER_H_ */

View File

@@ -1,69 +0,0 @@
/*
* 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 IMAGE_IMAGEDECODER_H_
#define IMAGE_IMAGEDECODER_H_
#include <iosfwd>
#include <string>
#include <image/LinearImage.h>
#include <utils/compiler.h>
namespace image {
class UTILS_PUBLIC ImageDecoder {
public:
enum class ColorSpace {
LINEAR,
SRGB
};
// Returns linear floating-point data, or a non-valid image if an error occured.
static LinearImage decode(std::istream& stream, const std::string& sourceName,
ColorSpace sourceSpace = ColorSpace::SRGB);
class Decoder {
public:
virtual LinearImage decode() = 0;
virtual ~Decoder() = default;
ColorSpace getColorSpace() const noexcept {
return mColorSpace;
}
void setColorSpace(ColorSpace colorSpace) noexcept {
mColorSpace = colorSpace;
}
private:
ColorSpace mColorSpace = ColorSpace::SRGB;
};
private:
enum class Format {
NONE,
PNG,
HDR,
PSD,
EXR
};
};
} // namespace image
#endif /* IMAGE_IMAGEDECODER_H_ */

View File

@@ -1,34 +0,0 @@
/*
* Copyright 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.
*/
#include <image/LinearImage.h>
#include <utils/Path.h>
namespace image {
enum class ComparisonMode {
SKIP,
COMPARE,
UPDATE,
};
// Saves an image to disk or does a load-and-compare, depending on comparison mode.
// This makes it easy for unit tests to have compare / update commands.
// The passed-in image is the "result image" and the expected image is the "golden image".
void updateOrCompare(LinearImage result, const utils::Path& golden, ComparisonMode, float epsilon);
} // namespace image

View File

@@ -1,64 +0,0 @@
/*
* 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 IMAGE_IMAGEENCODER_H_
#define IMAGE_IMAGEENCODER_H_
#include <iosfwd>
#include <string>
#include <image/LinearImage.h>
#include <utils/compiler.h>
namespace image {
class UTILS_PUBLIC ImageEncoder {
public:
enum class Format {
PNG, // 8-bit sRGB, 1 or 3 channels
PNG_LINEAR, // 8-bit linear RGB, 1 or 3 channels
HDR, // 8-bit linear RGBE, 3 channels only
RGBM, // 8-bit RGBM, as PNG, 3 channels only
PSD, // 16-bit sRGB or 32-bit linear RGB, 3 channels only
// Default: 16 bit
EXR, // 16-bit linear RGB (half-float), 3 channels only
// Default: PIZ compression
DDS, // 8-bit sRGB, 1, 2 or 3 channels;
// 16-bit or 32-bit linear RGB, 1, 2 or 3 channels
// Default: 16 bit
DDS_LINEAR, // 8-bit, 16-bit or 32-bit linear RGB, 1, 2 or 3 channels
// Default: 16 bit
RGB_10_11_11_REV, // RGBA PNG file, but containing 11_11_10 data
};
// Consumes linear floating-point data, returns false if unable to encode.
static bool encode(std::ostream& stream, Format format, const LinearImage& image,
const std::string& compression, const std::string& destName);
static Format chooseFormat(const std::string& name, bool forceLinear = false);
static std::string chooseExtension(Format format);
class Encoder {
public:
virtual bool encode(const LinearImage& image) = 0;
virtual ~Encoder() = default;
};
};
} // namespace image
#endif /* IMAGE_IMAGEENCODER_H_ */

View File

@@ -1,149 +0,0 @@
/*
* 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 KTXREADER_KTX1READER_H
#define KTXREADER_KTX1READER_H
#include <image/Ktx1Bundle.h>
#include <filament/Texture.h>
namespace filament {
class Engine;
}
namespace ktxreader {
using KtxInfo = image::KtxInfo;
using Ktx1Bundle = image::Ktx1Bundle;
/**
* Allows clients to create Filament textures from Ktx1Bundle objects.
*/
namespace Ktx1Reader {
using Texture = filament::Texture;
using Engine = filament::Engine;
using TextureFormat = Texture::InternalFormat;
using CompressedPixelDataType = Texture::CompressedType;
using PixelDataType = Texture::Type;
using PixelDataFormat = Texture::Format;
using PixelBufferDescriptor = Texture::PixelBufferDescriptor;
using Callback = void(*)(void* userdata);
CompressedPixelDataType toCompressedPixelDataType(const KtxInfo& info);
PixelDataType toPixelDataType(const KtxInfo& info);
PixelDataFormat toPixelDataFormat(const KtxInfo& info);
bool isCompressed(const KtxInfo& info);
TextureFormat toTextureFormat(const KtxInfo& info);
template<typename T>
T toCompressedFilamentEnum(uint32_t format) {
switch (format) {
case Ktx1Bundle::RGB_S3TC_DXT1: return T::DXT1_RGB;
case Ktx1Bundle::RGBA_S3TC_DXT1: return T::DXT1_RGBA;
case Ktx1Bundle::RGBA_S3TC_DXT3: return T::DXT3_RGBA;
case Ktx1Bundle::RGBA_S3TC_DXT5: return T::DXT5_RGBA;
case Ktx1Bundle::R_RGTC_BC4_UNORM: return T::RED_RGTC1;
case Ktx1Bundle::R_RGTC_BC4_SNORM: return T::SIGNED_RED_RGTC1;
case Ktx1Bundle::RG_RGTC_BC5_UNORM: return T::RED_GREEN_RGTC2;
case Ktx1Bundle::RG_RGTC_BC5_SNORM: return T::SIGNED_RED_GREEN_RGTC2;
case Ktx1Bundle::RGBA_BPTC_BC7: return T::RGBA_BPTC_UNORM;
case Ktx1Bundle::SRGB8_ALPHA8_BPTC_BC7: return T::SRGB_ALPHA_BPTC_UNORM;
case Ktx1Bundle::RGB_BPTC_BC6H_SNORM: return T::RGB_BPTC_SIGNED_FLOAT;
case Ktx1Bundle::RGB_BPTC_BC6H_UNORM: return T::RGB_BPTC_UNSIGNED_FLOAT;
case Ktx1Bundle::RGBA_ASTC_4x4: return T::RGBA_ASTC_4x4;
case Ktx1Bundle::RGBA_ASTC_5x4: return T::RGBA_ASTC_5x4;
case Ktx1Bundle::RGBA_ASTC_5x5: return T::RGBA_ASTC_5x5;
case Ktx1Bundle::RGBA_ASTC_6x5: return T::RGBA_ASTC_6x5;
case Ktx1Bundle::RGBA_ASTC_6x6: return T::RGBA_ASTC_6x6;
case Ktx1Bundle::RGBA_ASTC_8x5: return T::RGBA_ASTC_8x5;
case Ktx1Bundle::RGBA_ASTC_8x6: return T::RGBA_ASTC_8x6;
case Ktx1Bundle::RGBA_ASTC_8x8: return T::RGBA_ASTC_8x8;
case Ktx1Bundle::RGBA_ASTC_10x5: return T::RGBA_ASTC_10x5;
case Ktx1Bundle::RGBA_ASTC_10x6: return T::RGBA_ASTC_10x6;
case Ktx1Bundle::RGBA_ASTC_10x8: return T::RGBA_ASTC_10x8;
case Ktx1Bundle::RGBA_ASTC_10x10: return T::RGBA_ASTC_10x10;
case Ktx1Bundle::RGBA_ASTC_12x10: return T::RGBA_ASTC_12x10;
case Ktx1Bundle::RGBA_ASTC_12x12: return T::RGBA_ASTC_12x12;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_4x4: return T::SRGB8_ALPHA8_ASTC_4x4;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_5x4: return T::SRGB8_ALPHA8_ASTC_5x4;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_5x5: return T::SRGB8_ALPHA8_ASTC_5x5;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_6x5: return T::SRGB8_ALPHA8_ASTC_6x5;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_6x6: return T::SRGB8_ALPHA8_ASTC_6x6;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_8x5: return T::SRGB8_ALPHA8_ASTC_8x5;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_8x6: return T::SRGB8_ALPHA8_ASTC_8x6;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_8x8: return T::SRGB8_ALPHA8_ASTC_8x8;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_10x5: return T::SRGB8_ALPHA8_ASTC_10x5;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_10x6: return T::SRGB8_ALPHA8_ASTC_10x6;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_10x8: return T::SRGB8_ALPHA8_ASTC_10x8;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_10x10: return T::SRGB8_ALPHA8_ASTC_10x10;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_12x10: return T::SRGB8_ALPHA8_ASTC_12x10;
case Ktx1Bundle::SRGB8_ALPHA8_ASTC_12x12: return T::SRGB8_ALPHA8_ASTC_12x12;
case Ktx1Bundle::R11_EAC: return T::EAC_R11;
case Ktx1Bundle::SIGNED_R11_EAC: return T::EAC_R11_SIGNED;
case Ktx1Bundle::RG11_EAC: return T::EAC_RG11;
case Ktx1Bundle::SIGNED_RG11_EAC: return T::EAC_RG11_SIGNED;
case Ktx1Bundle::RGB8_ETC2: return T::ETC2_RGB8;
case Ktx1Bundle::SRGB8_ETC2: return T::ETC2_SRGB8;
case Ktx1Bundle::RGB8_ALPHA1_ETC2: return T::ETC2_RGB8_A1;
case Ktx1Bundle::SRGB8_ALPHA1_ETC: return T::ETC2_SRGB8_A1;
case Ktx1Bundle::RGBA8_ETC2_EAC: return T::ETC2_EAC_RGBA8;
case Ktx1Bundle::SRGB8_ALPHA8_ETC2_EAC: return T::ETC2_EAC_SRGBA8;
}
return (T) 0xffff;
}
/**
* Creates a Texture object from a KTX file and populates all of its faces and miplevels.
*
* @param engine Used to create the Filament Texture
* @param ktx In-memory representation of a KTX file
* @param srgb Requests an sRGB format from the KTX file
* @param callback Gets called after all texture data has been uploaded to the GPU
* @param userdata Passed into the callback
*/
Texture* createTexture(Engine* engine, const Ktx1Bundle& ktx, bool srgb,
Callback callback, void* userdata);
/**
* Creates a Texture object from a KTX bundle, populates all of its faces and miplevels,
* and automatically destroys the bundle after all the texture data has been uploaded.
*
* @param engine Used to create the Filament Texture
* @param ktx In-memory representation of a KTX file
* @param srgb Requests an sRGB format from the KTX file
*/
Texture* createTexture(Engine* engine, Ktx1Bundle* ktx, bool srgb);
CompressedPixelDataType toCompressedPixelDataType(const KtxInfo& info);
PixelDataType toPixelDataType(const KtxInfo& info);
PixelDataFormat toPixelDataFormat(const KtxInfo& info);
bool isCompressed(const KtxInfo& info);
bool isSrgbTextureFormat(TextureFormat format);
TextureFormat toTextureFormat(const KtxInfo& info);
} // namespace Ktx1Reader
} // namespace ktxreader
#endif

View File

@@ -1,203 +0,0 @@
/*
* 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 KTXREADER_KTX2READER_H
#define KTXREADER_KTX2READER_H
#include <cstdint>
#include <cstddef>
#include <filament/Texture.h>
#include <utils/FixedCapacityVector.h>
namespace filament {
class Engine;
}
namespace basist {
class ktx2_transcoder;
}
namespace ktxreader {
class Ktx2Reader {
public:
using Engine = filament::Engine;
using Texture = filament::Texture;
enum class TransferFunction { LINEAR, sRGB };
enum class Result {
SUCCESS,
COMPRESSED_TRANSCODE_FAILURE,
UNCOMPRESSED_TRANSCODE_FAILURE,
FORMAT_UNSUPPORTED,
FORMAT_ALREADY_REQUESTED,
};
Ktx2Reader(Engine& engine, bool quiet = false);
~Ktx2Reader();
/**
* Requests that the reader constructs Filament textures with given internal format.
*
* This MUST be called at least once before calling load().
*
* As a reminder, a basis-encoded KTX2 can be quickly transcoded to any number of formats,
* so you need to tell it what formats your hw supports. That's why this method exists.
*
* Call requestFormat as many times as needed; formats that are submitted early are
* considered higher priority.
*
* If BasisU knows a priori that the given format is not available (e.g. if the build has
* disabled it), the format is not added and FORMAT_UNSUPPORTED is returned.
*
* Returns FORMAT_ALREADY_REQUESTED if the given format has already been requested.
*
* Hint: BasisU supports the following uncompressed formats: RGBA8, RGB565, RGBA4.
*/
Result requestFormat(Texture::InternalFormat format) noexcept;
/**
* Removes the given format from the list, or does nothing if it hasn't been requested.
*/
void unrequestFormat(Texture::InternalFormat format) noexcept;
/**
* Attempts to create and load a Filament texture from the given KTX2 blob.
*
* If none of the requested formats can be extracted from the data, this returns null.
*
* This method iterates through the requested format list, checking each one against the
* platform's capabilities and its availability from the transcoder. When a suitable format
* is determined, it then performs lossless decompression (zstd) before transcoding the data
* into the final format.
*
* The transfer function specified here is used in two ways:
* 1) It is checked against the transfer function that was specified as metadata
* in the KTX2 blob. If they do not match, this method fails.
* 2) It is used as a filter when determining the final internal format.
*/
Texture* load(const void* data, size_t size, TransferFunction transfer);
/**
* Asynchronous Interface
* ======================
*
* Alternative API suitable for asynchronous transcoding of mipmap levels.
* If unsure that you need to use this, then don't, just call load() instead.
* Usage pseudocode:
*
* auto async = reader->asyncCreate(data, size, TransferFunction::LINEAR);
* mTexture = async->getTexture();
* auto backgroundThread = spawnThread({ async->doTranscoding(); })
* backgroundThread.wait();
* async->uploadImages();
* reader->asyncDestroy(async);
*
* In the documentation comments, "foreground thread" refers to the thread that the
* Filament Engine was created on.
*/
class Async {
public:
/**
* Retrieves the Texture object.
*
* The texture is available immediately, but does not have its miplevels ready until
* after doTranscoding() and the subsequent uploadImages() have been completed. The
* caller has ownership over this texture and is responsible for freeing it after all
* miplevels have been uploaded.
*/
Texture* getTexture() const noexcept;
/**
* Loads all mipmaps from the KTX2 file and transcodes them to the resolved format.
*
* This does not return until all mipmaps have been transcoded. This is typically
* called from a background thread.
*/
Result doTranscoding();
/**
* Uploads pending mipmaps to the texture.
*
* This can safely be called while doTranscoding() is still working in another thread.
* Since this calls Texture::setImage(), it should be called from the foreground thread;
* see "Thread safety" in the documentation for filament::Engine.
*/
void uploadImages();
protected:
Async() noexcept = default;
virtual ~Async();
public:
Async(Async const&) = delete;
Async(Async&&) = delete;
Async& operator=(Async const&) = delete;
Async& operator=(Async&&) = delete;
friend class Ktx2Reader;
};
/**
* Creates a texture without starting the transcode process.
*
* This method is an alternative to load() that allows users to populate mipmap levels
* asynchronously. The texture object however is still created synchronously.
*
* - For a usage example, see the documentation for the Async object.
* - Creates a copy of the given buffer, allowing clients to free it immediately.
* - Returns null if none of the requested formats can be extracted from the data.
*
* This method iterates through the requested format list, checking each one against the
* platform's capabilities and its availability from the transcoder. When a suitable format
* is determined, it then performs lossless decompression (zstd) before transcoding the data
* into the final format.
*
* The transfer function specified here is used in two ways:
* 1) It is checked against the transfer function that was specified as metadata
* in the KTX2 blob. If they do not match, this method fails.
* 2) It is used as a filter when determining the final internal format.
*/
Async* asyncCreate(const void* data, size_t size, TransferFunction transfer);
/**
* Frees the given async object and sets it to null.
*
* This frees the original source data (i.e. the raw content of the KTX2 file) but does not
* free the associated Texture object. This can be done after transcoding has finished.
*/
void asyncDestroy(Async** async);
private:
Ktx2Reader(const Ktx2Reader&) = delete;
Ktx2Reader& operator=(const Ktx2Reader&) = delete;
Ktx2Reader(Ktx2Reader&& that) noexcept = delete;
Ktx2Reader& operator=(Ktx2Reader&& that) noexcept = delete;
Texture* createTexture(basist::ktx2_transcoder* transcoder, const void* data,
size_t size, TransferFunction transfer);
Engine& mEngine;
basist::ktx2_transcoder* const mTranscoder;
utils::FixedCapacityVector<Texture::InternalFormat> mRequestedFormats;
bool mQuiet;
};
} // namespace ktxreader
#endif

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