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/** This namespace contain utilities regarding high-level cross-platform and cross-rhi texture objects */
21{
22 using namespace Mcro::Concepts;
23
24 /** 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 /** 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 /** 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 /** 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 /** 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 %s"), 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 %s"), *enumName)
110 );
111 return PF_Unknown;
112 }
113 }
114 }
115
116 /**
117 * A simple texture size description which can be used for checking the need to recreate a texture resource.
118 *
119 * @todo This may get generalized to other type of resources in the future.
120 * @tparam SizeType the integral type for texture size
121 * @tparam InFormatType the type of the format enum
122 */
123 template <CScalar SizeType, CEnum InFormatType>
125 {
126 using FormatType = InFormatType;
127
129
130 template <CScalar SizeTypeArg, CEnum FormatTypeArg>
131 TTextureSize(SizeTypeArg width, SizeTypeArg height, FormatTypeArg format)
132 : Width(static_cast<SizeType>(width))
133 , Height(static_cast<SizeType>(height))
134 , Format(ConvertFormat<InFormatType>(format))
135 {}
136
137 template <CTextureSize OtherTextureSize>
138 TTextureSize(OtherTextureSize const& other)
139 : Width(static_cast<SizeType>(other.Width))
140 , Height(static_cast<SizeType>(other.Height))
141 , Format(ConvertFormat<InFormatType>(other.Format))
142 {}
143
144 template <CTextureSize OtherTextureSize>
145 TTextureSize(OtherTextureSize&& other)
146 : Width(static_cast<SizeType>(other.Width))
147 , Height(static_cast<SizeType>(other.Height))
148 , Format(ConvertFormat<InFormatType>(other.Format))
149 {}
150
151 SizeType Width = 0;
152 SizeType Height = 0;
154
155 operator bool() const
156 {
157 return Width > 0 && Height > 0 && Format != GetUnknownFormat<InFormatType>();
158 }
159
160 template <CTextureSize OtherTextureSize>
161 operator OtherTextureSize() const
162 {
163 return OtherTextureSize(
164 Width, Height,
166 );
167 }
168 };
169
170 template <CTextureSize Left, CTextureSize Right>
171 bool operator == (Left const& l, Right const& r)
172 {
173 return l.Width == r.Width
174 && l.Height == r.Height
175 && l.Format == ConvertFormat<typename Left::FormatType>(r.Format)
176 ;
177 }
178
179 template <CTextureSize Left, CTextureSize Right>
180 bool operator != (Left const& l, Right const& r) { return !(l == r); }
181
183
184 MCRO_API FUnrealTextureSize GetTextureSize(UTexture* texture);
185}
#define ASSERT_QUIT(condition, returnOnFailure,...)
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()
Definition Textures.h:38
bool operator==(Left const &l, Right const &r)
Definition Textures.h:171
bool operator!=(Left const &l, Right const &r)
Definition Textures.h:180
MCRO_API FRHITexture * GetRhiTexture2D(UTexture *target)
ToFormatType ConvertFormat(FromFormatType from)
Definition Textures.h:46
TTextureSize(OtherTextureSize &&other)
Definition Textures.h:145
TTextureSize(OtherTextureSize const &other)
Definition Textures.h:138
TTextureSize(SizeTypeArg width, SizeTypeArg height, FormatTypeArg format)
Definition Textures.h:131