509 lines
22 KiB
C++
Executable File
509 lines
22 KiB
C++
Executable File
/*
|
|
* 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::IndirectLight* 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;
|
|
|
|
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 FaceOffsets = backend::FaceOffsets; //!< Cube map faces offsets
|
|
using Usage = backend::TextureUsage; //!< Usage affects texel layout
|
|
using Swizzle = backend::TextureSwizzle; //!< Texture swizzle
|
|
|
|
static bool isTextureFormatSupported(Engine& engine, InternalFormat format) 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 UTILS_PUBLIC 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
|
|
*
|
|
* @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.
|
|
*/
|
|
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 textue 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;
|
|
|
|
/**
|
|
* Specify the image of a 2D texture for a level.
|
|
*
|
|
* @param engine Engine this texture is associated to.
|
|
* @param level Level to set the image for.
|
|
* @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_2D or
|
|
* Sampler::SAMPLER_EXTERNAL. IF the later is specified
|
|
* and external textures are supported by the driver implementation,
|
|
* this method will have no effect, otherwise it will behave as if the
|
|
* texture was specified with driver::SamplerType::SAMPLER_2D.
|
|
*
|
|
* @note
|
|
* This is equivalent to calling:
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* setImage(engine, level, 0, 0, getWidth(level), getHeight(level), buffer);
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* @see Builder::sampler()
|
|
*/
|
|
void setImage(Engine& engine, size_t level, PixelBufferDescriptor&& buffer) const;
|
|
|
|
/**
|
|
* Updates a sub-image of a 2D texture for a level.
|
|
*
|
|
* @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 width Width of the sub-region to update.
|
|
* @param height Height 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_2D or
|
|
* Sampler::SAMPLER_EXTERNAL. IF the later is specified
|
|
* and external textures are supported by the driver implementation,
|
|
* this method will have no effect, otherwise it will behave as if the
|
|
* texture was specified with Sampler::SAMPLER_2D.
|
|
*
|
|
* @see Builder::sampler()
|
|
*/
|
|
void setImage(Engine& engine, size_t level,
|
|
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
|
|
PixelBufferDescriptor&& buffer) const;
|
|
|
|
/**
|
|
* Updates a sub-image of a 3D texture or 2D texture array for a level.
|
|
*
|
|
* @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 or Sampler::SAMPLER_2D_array.
|
|
*
|
|
* @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;
|
|
|
|
/**
|
|
* 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()
|
|
*/
|
|
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
|
|
*
|
|
* @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
|
|
*
|
|
* @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);
|
|
};
|
|
|
|
} // namespace filament
|
|
|
|
#endif // TNT_FILAMENT_TEXTURE_H
|