From 331b6caf7e64631e558cf7192c1bee0e96659bea Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 16 Mar 2020 12:08:09 -0700 Subject: Moved filtering functions to new FilterintTools.hpp. Added FilterTexture2DBilinear function. --- Common/interface/AdvancedMath.hpp | 112 ---------------------- Common/interface/FilteringTools.hpp | 183 ++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 112 deletions(-) create mode 100644 Common/interface/FilteringTools.hpp (limited to 'Common/interface') diff --git a/Common/interface/AdvancedMath.hpp b/Common/interface/AdvancedMath.hpp index 4d8b0c98..ad14d2a7 100644 --- a/Common/interface/AdvancedMath.hpp +++ b/Common/interface/AdvancedMath.hpp @@ -34,8 +34,6 @@ #include "BasicMath.hpp" -#include "../../Graphics/GraphicsEngine/interface/Sampler.h" - namespace Diligent { @@ -662,116 +660,6 @@ void TraceLineThroughGrid(float2 f2Start, } } - -/// Linear texture filter sample info -// -// w -// | - - - - - >| -// -----X-------|-------X-------|----*--X-------|-------X -// i0-1.5 i0+0.5 i1+0.5 i1+1.5 -// -// T[*] = lerp(T[i0], T[i1], w) -// -struct LinearTexFilterSampleInfo -{ - /// First sample index - Int32 i0 = 0; - - /// Second sample index - Int32 i1 = 0; - - /// Blend weight - float w = 0.f; - - LinearTexFilterSampleInfo() noexcept {} - - LinearTexFilterSampleInfo(Int32 _i0, Int32 _i1, float _w) noexcept : - i0{_i0}, - i1{_i1}, - w{_w} - { - } - - bool operator==(const LinearTexFilterSampleInfo& rhs) const - { - return i0 == rhs.i0 && i1 == rhs.i1 && w == rhs.w; - } - - bool operator!=(const LinearTexFilterSampleInfo& rhs) const - { - return !(*this == rhs); - } -}; - -/// Returns linear texture filter sample info, see Diligent::LinearTexFilterSampleInfo. -/// -/// \tparam AddressMode - Texture addressing mode, see Diligent::TEXTURE_ADDRESS_MODE. -/// \tparam IsNormalized - Whether sample coordinate is normalized. -/// -/// \param [in] Width - Texture width. -/// \param [in] u - Texture sample coordinate. -/// \return Linear texture filter sample information, see Diligent::LinearTexFilterSampleInfo. -template -LinearTexFilterSampleInfo GetLinearTexFilterSampleInfo(Uint32 Width, float u) -{ - float x = IsNormalized ? u * static_cast(Width) : u; - float x0 = std::floor(x - 0.5f); - - // clang-format off - LinearTexFilterSampleInfo SampleInfo - { - static_cast(x0), - static_cast(x0 + 1), - x - 0.5f - x0 - }; - // clang-format on - - auto WrapCoord = [](Int32 i, Uint32 Width) // - { - auto w = static_cast(Width); - - // Note that the sign of a%b is implementation-dependent when one of the operands is negative. - // a/b, to the contrary, is always well-defined. - i = i - (i / w) * w; - return i < 0 ? i + w : i; - }; - - auto MirrorCoord = [WrapCoord](Int32 i, Uint32 Width) // - { - i = WrapCoord(i, Width * 2); - - auto w = static_cast(Width); - return i >= w ? (w * 2 - 1) - i : i; - }; - - switch (AddressMode) - { - case TEXTURE_ADDRESS_UNKNOWN: - // do nothing - break; - - case TEXTURE_ADDRESS_WRAP: - SampleInfo.i0 = WrapCoord(SampleInfo.i0, Width); - SampleInfo.i1 = WrapCoord(SampleInfo.i1, Width); - break; - - case TEXTURE_ADDRESS_MIRROR: - SampleInfo.i0 = MirrorCoord(SampleInfo.i0, Width); - SampleInfo.i1 = MirrorCoord(SampleInfo.i1, Width); - break; - - case TEXTURE_ADDRESS_CLAMP: - SampleInfo.i0 = clamp(SampleInfo.i0, 0, static_cast(Width - 1)); - SampleInfo.i1 = clamp(SampleInfo.i1, 0, static_cast(Width - 1)); - break; - - default: - UNEXPECTED("Unexpected texture address mode"); - } - - return SampleInfo; -} - } // namespace Diligent namespace std diff --git a/Common/interface/FilteringTools.hpp b/Common/interface/FilteringTools.hpp new file mode 100644 index 00000000..9dc3a671 --- /dev/null +++ b/Common/interface/FilteringTools.hpp @@ -0,0 +1,183 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * 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. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "../../Platforms/interface/PlatformDefinitions.h" + +#include "BasicMath.hpp" + +#include "../../Graphics/GraphicsEngine/interface/Sampler.h" + +namespace Diligent +{ + +/// Linear texture filter sample info +// +// w +// | - - - - - >| +// -----X-------|-------X-------|----*--X-------|-------X +// i0-1.5 i0+0.5 i1+0.5 i1+1.5 +// +// T[*] = lerp(T[i0], T[i1], w) +// +struct LinearTexFilterSampleInfo +{ + /// First sample index + Int32 i0 = 0; + + /// Second sample index + Int32 i1 = 0; + + /// Blend weight + float w = 0.f; + + LinearTexFilterSampleInfo() noexcept {} + + LinearTexFilterSampleInfo(Int32 _i0, Int32 _i1, float _w) noexcept : + i0{_i0}, + i1{_i1}, + w{_w} + { + } + + bool operator==(const LinearTexFilterSampleInfo& rhs) const + { + return i0 == rhs.i0 && i1 == rhs.i1 && w == rhs.w; + } + + bool operator!=(const LinearTexFilterSampleInfo& rhs) const + { + return !(*this == rhs); + } +}; + +/// Returns linear texture filter sample info, see Diligent::LinearTexFilterSampleInfo. +/// +/// \tparam AddressMode - Texture addressing mode, see Diligent::TEXTURE_ADDRESS_MODE. +/// \tparam IsNormalizedCoord - Whether sample coordinate is normalized. +/// +/// \param [in] Width - Texture width. +/// \param [in] u - Texture sample coordinate. +/// \return Linear texture filter sample information, see Diligent::LinearTexFilterSampleInfo. +template +LinearTexFilterSampleInfo GetLinearTexFilterSampleInfo(Uint32 Width, float u) +{ + float x = IsNormalizedCoord ? u * static_cast(Width) : u; + float x0 = std::floor(x - 0.5f); + + // clang-format off + LinearTexFilterSampleInfo SampleInfo + { + static_cast(x0), + static_cast(x0 + 1), + x - 0.5f - x0 + }; + // clang-format on + + auto WrapCoord = [](Int32 i, Uint32 Width) // + { + auto w = static_cast(Width); + + // Note that the sign of a%b is implementation-dependent when one of the operands is negative. + // a/b, to the contrary, is always well-defined. + i = i - (i / w) * w; + return i < 0 ? i + w : i; + }; + + auto MirrorCoord = [WrapCoord](Int32 i, Uint32 Width) // + { + i = WrapCoord(i, Width * 2); + + auto w = static_cast(Width); + return i >= w ? (w * 2 - 1) - i : i; + }; + + switch (AddressMode) + { + case TEXTURE_ADDRESS_UNKNOWN: + // do nothing + break; + + case TEXTURE_ADDRESS_WRAP: + SampleInfo.i0 = WrapCoord(SampleInfo.i0, Width); + SampleInfo.i1 = WrapCoord(SampleInfo.i1, Width); + break; + + case TEXTURE_ADDRESS_MIRROR: + SampleInfo.i0 = MirrorCoord(SampleInfo.i0, Width); + SampleInfo.i1 = MirrorCoord(SampleInfo.i1, Width); + break; + + case TEXTURE_ADDRESS_CLAMP: + SampleInfo.i0 = clamp(SampleInfo.i0, 0, static_cast(Width - 1)); + SampleInfo.i1 = clamp(SampleInfo.i1, 0, static_cast(Width - 1)); + break; + + default: + UNEXPECTED("Unexpected texture address mode"); + } + + return SampleInfo; +} + +/// Samples 2D texture using bilinear filter. +/// +/// \tparam PixelType - Pixel type. +/// \tparam AddressModeU - U coordinate address mode. +/// \tparam AddressModeV - V coordinate address mode. +/// \tparam IsNormalizedCoord - Whether sample coordinates are normalized. +/// +/// \param [in] Width - Texture width. +/// \param [in] Height - Texture height. +/// \param [in] pData - Pointer to the texture data. +/// \param [in] Stride - Data stride, in pixels. +/// \param [in] u - Sample u coordinate. +/// \param [in] v - Sample v coordinate. +/// \return - Filtered texture sample. +template +PixelType FilterTexture2DBilinear(Uint32 Width, + Uint32 Height, + const PixelType* pData, + Uint32 Stride, + float u, + float v) +{ + auto UFilterInfo = GetLinearTexFilterSampleInfo(Width, u); + auto VFilterInfo = GetLinearTexFilterSampleInfo(Height, v); + + auto S00 = pData[UFilterInfo.i0 + VFilterInfo.i0 * Stride]; + auto S10 = pData[UFilterInfo.i1 + VFilterInfo.i0 * Stride]; + auto S01 = pData[UFilterInfo.i0 + VFilterInfo.i1 * Stride]; + auto S11 = pData[UFilterInfo.i1 + VFilterInfo.i1 * Stride]; + return lerp(lerp(S00, S10, UFilterInfo.w), lerp(S01, S11, UFilterInfo.w), VFilterInfo.w); +} + +} // namespace Diligent -- cgit v1.2.3