MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Textures.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12#pragma once
13
14#include "CoreMinimal.h"
15#include "Mcro/Concepts.h"
16#include "Mcro/AssertMacros.h"
17#include "Engine/TextureRenderTarget2D.h"
18
19/** @brief This namespace contain utilities regarding high-level cross-platform and cross-rhi texture objects */
21{
22 using namespace Mcro::Concepts;
23
24 /** @brief Get the lower level RHI texture from a high level UTexture2D object if it's possible, nullptr otherwise */
25 MCRO_API FRHITexture* GetRhiTexture2D(UTexture* target);
26
27 /** @brief Describing a struct which can give texture size and layout information */
28 template <typename T>
29 concept CTextureSize = requires(T t, typename T::FormatType)
30 {
31 t.Width;
32 t.Height;
33 t.Format;
34 };
35
36 /** @brief Specialize this function template to define the unknown format for an RHI texture format */
37 template <CEnum FormatType>
38 constexpr auto GetUnknownFormat() { return static_cast<FormatType>(0); }
39
40 template <> constexpr auto GetUnknownFormat<EPixelFormat>() { return PF_Unknown; }
41 template <> constexpr auto GetUnknownFormat<ETextureRenderTargetFormat>() { return RTF_R8; }
42
43 /** @brief Specialize this function template to define format conversion of equivalent formats between RHIs */
44 template <CEnum ToFormatType, CEnum FromFormatType>
45 requires (!CSameAs<ToFormatType, FromFormatType>)
46 ToFormatType ConvertFormat(FromFormatType from)
47 {
48 return static_cast<ToFormatType>(from);
49 }
50
51 /** @brief Special case when ToFormatType and FromFormatType are the same there's no need for conversion */
52 template <CEnum ToFormatType, CEnum FromFormatType>
53 requires CSameAs<ToFormatType, FromFormatType>
54 ToFormatType ConvertFormat(FromFormatType from)
55 {
56 return from;
57 }
58
59 template <>
60 FORCEINLINE_DEBUGGABLE ETextureRenderTargetFormat ConvertFormat<ETextureRenderTargetFormat, EPixelFormat>(EPixelFormat from)
61 {
62 switch (from)
63 {
64 case PF_G8: return RTF_R8;
65 case PF_R8G8: return RTF_RG8;
66 case PF_B8G8R8A8: return RTF_RGBA8;
67
68 case PF_R16F: return RTF_R16f;
69 case PF_G16R16F: return RTF_RG16f;
70 case PF_FloatRGBA: return RTF_RGBA16f;
71
72 case PF_R32_FLOAT: return RTF_R32f;
73 case PF_G32R32F: return RTF_RG32f;
74 case PF_A32B32G32R32F: return RTF_RGBA32f;
75 case PF_A2B10G10R10: return RTF_RGB10A2;
76 default:
77 {
78 ASSERT_QUIT(false, RTF_R8,
79 ->WithMessageF(TEXT_"Unhandled ETextureRenderTargetFormat entry {0}", GetPixelFormatString(from))
80 )
81 return RTF_R8;
82 };
83 }
84 }
85
86 template <>
87 FORCEINLINE_DEBUGGABLE EPixelFormat ConvertFormat<EPixelFormat, ETextureRenderTargetFormat>(ETextureRenderTargetFormat from)
88 {
89 // I know about GetPixelFormatFromRenderTargetFormat but I also have better error handling
90 switch (from)
91 {
92 case RTF_R8: return PF_G8;
93 case RTF_RG8: return PF_R8G8;
94 case RTF_RGBA8: return PF_B8G8R8A8;
95 case RTF_RGBA8_SRGB: return PF_B8G8R8A8;
96
97 case RTF_R16f: return PF_R16F;
98 case RTF_RG16f: return PF_G16R16F;
99 case RTF_RGBA16f: return PF_FloatRGBA;
100
101 case RTF_R32f: return PF_R32_FLOAT;
102 case RTF_RG32f: return PF_G32R32F;
103 case RTF_RGBA32f: return PF_A32B32G32R32F;
104 case RTF_RGB10A2: return PF_A2B10G10R10;
105 default:
106 {
107 auto enumName = UEnum::GetValueAsString(from);
108 ASSERT_QUIT(false, PF_Unknown,
109 ->WithMessageF(TEXT_"Unhandled ETextureRenderTargetFormat entry {0}", enumName)
110 );
111 return PF_Unknown;
112 }
113 }
114 }
115
116 /**
117 * @brief A simple texture size description which can be used for checking the need to recreate a texture resource.
118 * @tparam SizeType the integral type for texture size
119 * @tparam InFormatType the type of the format enum
120 * @todo This may get generalized to other type of resources in the future.
121 */
122 template <CScalar SizeType, CEnum InFormatType>
124 {
125 using FormatType = InFormatType;
126
128
129 template <CScalar SizeTypeArg, CEnum FormatTypeArg>
130 TTextureSize(SizeTypeArg width, SizeTypeArg height, FormatTypeArg format)
131 : Width(static_cast<SizeType>(width))
132 , Height(static_cast<SizeType>(height))
133 , Format(ConvertFormat<InFormatType>(format))
134 {}
135
136 template <CTextureSize OtherTextureSize>
137 TTextureSize(OtherTextureSize const& other)
138 : Width(static_cast<SizeType>(other.Width))
139 , Height(static_cast<SizeType>(other.Height))
140 , Format(ConvertFormat<InFormatType>(other.Format))
141 {}
142
143 template <CTextureSize OtherTextureSize>
144 TTextureSize(OtherTextureSize&& other)
145 : Width(static_cast<SizeType>(other.Width))
146 , Height(static_cast<SizeType>(other.Height))
147 , Format(ConvertFormat<InFormatType>(other.Format))
148 {}
149
150 SizeType Width = 0;
151 SizeType Height = 0;
153
154 operator bool() const
155 {
156 return Width > 0 && Height > 0 && Format != GetUnknownFormat<InFormatType>();
157 }
158
159 template <CTextureSize OtherTextureSize>
160 operator OtherTextureSize() const
161 {
162 return OtherTextureSize(
163 Width, Height,
165 );
166 }
167 };
168
169 template <CTextureSize Left, CTextureSize Right>
170 bool operator == (Left const& l, Right const& r)
171 {
172 return l.Width == r.Width
173 && l.Height == r.Height
174 && l.Format == ConvertFormat<typename Left::FormatType>(r.Format)
175 ;
176 }
177
178 template <CTextureSize Left, CTextureSize Right>
179 bool operator != (Left const& l, Right const& r) { return !(l == r); }
180
182
183 MCRO_API FUnrealTextureSize GetTextureSize(UTexture* texture);
184}
#define ASSERT_QUIT(condition, returnOnFailure,...)
Use this instead of check macro if the checked expression shouldn't be ignored in shipping builds....
This header exists because STL headers in Android doesn't define STL concepts (other than same_as whi...
#define TEXT_
A convenience alternative to Unreal's own TEXT macro but this one doesn't require parenthesis around ...
Definition TextMacros.h:53
Describing a struct which can give texture size and layout information.
Definition Textures.h:29
This namespace contain utilities regarding high-level cross-platform and cross-rhi texture objects.
Definition Textures.h:21
constexpr auto GetUnknownFormat< ETextureRenderTargetFormat >()
Definition Textures.h:41
FORCEINLINE_DEBUGGABLE EPixelFormat ConvertFormat< EPixelFormat, ETextureRenderTargetFormat >(ETextureRenderTargetFormat from)
Definition Textures.h:87
MCRO_API FUnrealTextureSize GetTextureSize(UTexture *texture)
FORCEINLINE_DEBUGGABLE ETextureRenderTargetFormat ConvertFormat< ETextureRenderTargetFormat, EPixelFormat >(EPixelFormat from)
Definition Textures.h:60
constexpr auto GetUnknownFormat< EPixelFormat >()
Definition Textures.h:40
constexpr auto GetUnknownFormat()
Specialize this function template to define the unknown format for an RHI texture format.
Definition Textures.h:38
bool operator==(Left const &l, Right const &r)
Definition Textures.h:170
bool operator!=(Left const &l, Right const &r)
Definition Textures.h:179
MCRO_API FRHITexture * GetRhiTexture2D(UTexture *target)
Get the lower level RHI texture from a high level UTexture2D object if it's possible,...
ToFormatType ConvertFormat(FromFormatType from)
Specialize this function template to define format conversion of equivalent formats between RHIs.
Definition Textures.h:46
A simple texture size description which can be used for checking the need to recreate a texture resou...
Definition Textures.h:124
TTextureSize(OtherTextureSize &&other)
Definition Textures.h:144
TTextureSize(OtherTextureSize const &other)
Definition Textures.h:137
TTextureSize(SizeTypeArg width, SizeTypeArg height, FormatTypeArg format)
Definition Textures.h:130