Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_CORE_XLCOREPIPELINEINFO_H_
24 : #define XENOLITH_CORE_XLCOREPIPELINEINFO_H_
25 :
26 : #include "XLCore.h"
27 : #include "XLCoreEnum.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
30 :
31 : static constexpr auto EmptyTextureName = "org.xenolith.EmptyImage";
32 : static constexpr auto SolidTextureName = "org.xenolith.SolidImage";
33 :
34 : /**
35 : * ColorMode defines how to map texture color to shader color representation
36 : *
37 : * In Solid mode, texture color will be sent directly to shader
38 : * In Custom mode, you can define individual mapping for each channel
39 : *
40 : * (see ComponentMapping)
41 : */
42 : struct ColorMode {
43 : static const ColorMode SolidColor;
44 : static const ColorMode IntensityChannel;
45 : static const ColorMode AlphaChannel;
46 :
47 : enum Mode {
48 : Solid,
49 : Custom
50 : };
51 :
52 174041 : uint32_t mode : 4;
53 168280 : uint32_t r : 7;
54 168280 : uint32_t g : 7;
55 168280 : uint32_t b : 7;
56 168280 : uint32_t a : 7;
57 :
58 174630 : ColorMode() : mode(Solid), r(0), g(0), b(0), a(0) { }
59 32 : ColorMode(ComponentMapping r, ComponentMapping g, ComponentMapping b, ComponentMapping a)
60 32 : : mode(Custom), r(stappler::toInt(r)), g(stappler::toInt(g)), b(stappler::toInt(b)), a(stappler::toInt(a)) { }
61 :
62 2165 : ColorMode(ComponentMapping color, ComponentMapping a)
63 2165 : : mode(Custom), r(stappler::toInt(color)), g(stappler::toInt(color)), b(stappler::toInt(color)), a(stappler::toInt(a)) { }
64 :
65 : ColorMode(const ColorMode &) = default;
66 : ColorMode(ColorMode &&) = default;
67 : ColorMode &operator=(const ColorMode &) = default;
68 : ColorMode &operator=(ColorMode &&) = default;
69 :
70 174041 : bool operator==(const ColorMode &n) const = default;
71 2890 : bool operator!=(const ColorMode &n) const = default;
72 :
73 164780 : Mode getMode() const { return Mode(mode); }
74 64 : ComponentMapping getR() const { return ComponentMapping(r); }
75 64 : ComponentMapping getG() const { return ComponentMapping(g); }
76 64 : ComponentMapping getB() const { return ComponentMapping(b); }
77 3932 : ComponentMapping getA() const { return ComponentMapping(a); }
78 :
79 864 : uint32_t toInt() const { return *(uint32_t *)this; }
80 : operator uint32_t () const { return *(uint32_t *)this; }
81 : };
82 :
83 : // uint32_t-sized blend description
84 : struct BlendInfo {
85 42214 : uint32_t enabled : 4;
86 42214 : uint32_t srcColor : 4;
87 42214 : uint32_t dstColor : 4;
88 42214 : uint32_t opColor : 4;
89 42202 : uint32_t srcAlpha : 4;
90 42202 : uint32_t dstAlpha : 4;
91 42202 : uint32_t opAlpha : 4;
92 42202 : uint32_t writeMask : 4;
93 :
94 86386 : BlendInfo() : enabled(0)
95 86386 : , srcColor(toInt(BlendFactor::One)) , dstColor(toInt(BlendFactor::OneMinusSrcAlpha)) , opColor(toInt(BlendOp::Add))
96 86386 : , srcAlpha(toInt(BlendFactor::One)) , dstAlpha(toInt(BlendFactor::OneMinusSrcAlpha)) , opAlpha(toInt(BlendOp::Add))
97 86386 : , writeMask(toInt(ColorComponentFlags::All)) { }
98 :
99 10 : BlendInfo(BlendFactor src, BlendFactor dst, BlendOp op = BlendOp::Add,
100 : ColorComponentFlags flags = ColorComponentFlags::All)
101 10 : : enabled(1), srcColor(toInt(src)), dstColor(toInt(dst)), opColor(toInt(op))
102 10 : , srcAlpha(toInt(src)), dstAlpha(toInt(dst)), opAlpha(toInt(op)), writeMask(toInt(flags)) { }
103 :
104 23486 : BlendInfo(BlendFactor srcColor, BlendFactor dstColor, BlendOp opColor,
105 : BlendFactor srcAlpha, BlendFactor dstAlpha, BlendOp opAlpha,
106 : ColorComponentFlags flags = ColorComponentFlags::All)
107 23486 : : enabled(1), srcColor(toInt(srcColor)), dstColor(toInt(dstColor)), opColor(toInt(opColor))
108 23486 : , srcAlpha(toInt(srcAlpha)), dstAlpha(toInt(dstAlpha)), opAlpha(toInt(opAlpha)), writeMask(toInt(flags)) { }
109 :
110 42214 : bool operator==(const BlendInfo &other) const = default;
111 12 : bool operator!=(const BlendInfo &other) const = default;
112 :
113 196397 : bool isEnabled() const {
114 196397 : return enabled != 0;
115 : }
116 : };
117 :
118 : struct DepthInfo {
119 42202 : uint32_t writeEnabled : 4;
120 42202 : uint32_t testEnabled : 4;
121 42202 : uint32_t compare : 24; // gl::CompareOp
122 :
123 73150 : DepthInfo() : writeEnabled(0), testEnabled(0), compare(0) { }
124 :
125 23506 : DepthInfo(bool write, bool test, CompareOp compareOp)
126 23506 : : writeEnabled(write ? 1 : 0), testEnabled(test ? 1 : 0), compare(toInt(compareOp)) { }
127 :
128 42202 : bool operator==(const DepthInfo &other) const = default;
129 : bool operator!=(const DepthInfo &other) const = default;
130 : };
131 :
132 : struct DepthBounds {
133 42202 : bool enabled = false;
134 42202 : float min = 0.0f;
135 42202 : float max = 0.0f;
136 :
137 42202 : bool operator==(const DepthBounds &other) const = default;
138 : bool operator!=(const DepthBounds &other) const = default;
139 : };
140 :
141 : struct StencilInfo {
142 0 : StencilOp fail = StencilOp::Keep;
143 0 : StencilOp pass = StencilOp::Keep;
144 0 : StencilOp depthFail = StencilOp::Keep;
145 0 : CompareOp compare = CompareOp::Never;
146 0 : uint32_t compareMask = 0;
147 0 : uint32_t writeMask = 0;
148 0 : uint32_t reference = 0;
149 :
150 0 : friend bool operator==(const StencilInfo &l, const StencilInfo &r) = default;
151 : friend bool operator!=(const StencilInfo &l, const StencilInfo &r) = default;
152 : };
153 :
154 : using LineWidth = ValueWrapper<float, class LineWidthFlag>;
155 :
156 : class PipelineMaterialInfo {
157 : public:
158 : PipelineMaterialInfo();
159 : PipelineMaterialInfo(const PipelineMaterialInfo &) = default;
160 : PipelineMaterialInfo &operator=(const PipelineMaterialInfo &) = default;
161 :
162 : template <typename T, typename ... Args, typename = std::enable_if_t<std::negation_v<std::is_same<T, PipelineMaterialInfo>>> >
163 70 : PipelineMaterialInfo(T &&t, Args && ... args) : PipelineMaterialInfo() {
164 70 : setup(std::forward<T>(t));
165 70 : setup(std::forward<Args>(args)...);
166 70 : }
167 :
168 : void setBlendInfo(const BlendInfo &);
169 : void setDepthInfo(const DepthInfo &);
170 : void setDepthBounds(const DepthBounds &);
171 : void enableStencil(const StencilInfo &);
172 : void enableStencil(const StencilInfo &front, const StencilInfo &back);
173 : void disableStancil();
174 : void setLineWidth(float lineWidth);
175 :
176 1240 : const BlendInfo &getBlendInfo() const { return blend; }
177 250348 : const DepthInfo &getDepthInfo() const { return depth; }
178 63 : const DepthBounds &getDepthBounds() const { return bounds; }
179 :
180 0 : bool isStancilEnabled() const { return stencil; }
181 0 : const StencilInfo &getStencilInfoFront() const { return front; }
182 0 : const StencilInfo &getStencilInfoBack() const { return back; }
183 :
184 8324 : float getLineWidth() const { return lineWidth; }
185 :
186 42202 : bool operator==(const PipelineMaterialInfo &tmp2) const {
187 84404 : return this->blend == tmp2.blend && this->depth == tmp2.depth && this->bounds == tmp2.bounds
188 42202 : && this->stencil == tmp2.stencil && (!this->stencil || (this->front == tmp2.front && this->back == tmp2.back))
189 84404 : && this->lineWidth == tmp2.lineWidth;
190 : }
191 :
192 : bool operator!=(const PipelineMaterialInfo &tmp2) const {
193 : return this->blend != tmp2.blend || this->depth != tmp2.depth || this->bounds != tmp2.bounds
194 : || this->stencil != tmp2.stencil || (this->stencil && (this->front != tmp2.front || this->back != tmp2.back))
195 : || this->lineWidth != tmp2.lineWidth;
196 : }
197 :
198 216 : size_t hash() const {
199 216 : return hash::hashSize((const char *)this, sizeof(PipelineMaterialInfo));
200 : }
201 :
202 : String data() const;
203 : String description() const;
204 :
205 : protected:
206 : void _setup(const BlendInfo &);
207 : void _setup(const DepthInfo &);
208 : void _setup(const DepthBounds &);
209 : void _setup(const StencilInfo &);
210 : void _setup(LineWidth lineWidth);
211 :
212 : template <typename T>
213 150 : void setup(T &&t) {
214 150 : _setup(std::forward<T>(t));
215 150 : }
216 :
217 : template <typename T, typename ... Args>
218 10 : void setup(T &&t, Args && ... args) {
219 10 : setup(std::forward<T>(t));
220 10 : setup(std::forward<Args>(args)...);
221 10 : }
222 :
223 : void setup() { }
224 :
225 : BlendInfo blend;
226 : DepthInfo depth;
227 : DepthBounds bounds;
228 : StencilInfo front;
229 : StencilInfo back;
230 : uint32_t stencil = 0;
231 : float lineWidth = 0.0f; // 0.0f - draw triangles, < 0.0f - points, > 0.0f - lines with width
232 : };
233 :
234 : }
235 :
236 : #endif /* XENOLITH_CORE_XLCOREPIPELINEINFO_H_ */
|