VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
blendState.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 09.11.2025.
5//
6#include "blendState.h"
7
8namespace visutwin::canvas
9{
10 // masks (to only keep relevant bits)
11 const uint32_t opMask = 0b111;
12 const uint32_t factorMask = 0b1111;
13
14 // Shifts values to where individual parts are stored
15 constexpr uint32_t colorOpShift = 0; // 00 - 02 (3bits)
16 constexpr uint32_t colorSrcFactorShift = 3; // 03 - 06 (4bits)
17 constexpr uint32_t colorDstFactorShift = 7; // 07 - 10 (4bits)
18 constexpr uint32_t alphaOpShift = 11; // 11 - 13 (3bits)
19 constexpr uint32_t alphaSrcFactorShift = 14; // 14 - 17 (4bits)
20 constexpr uint32_t alphaDstFactorShift = 18; // 18 - 21 (4bits)
21 constexpr uint32_t redWriteShift = 22; // 22 (1 bit)
22 constexpr uint32_t greenWriteShift = 23; // 23 (1 bit)
23 constexpr uint32_t blueWriteShift = 24; // 24 (1 bit)
24 constexpr uint32_t alphaWriteShift = 25; // 25 (1 bit)
25 constexpr uint32_t blendShift = 26; // 26 (1 bit)
26
28 {
29 // JS default equivalent: color writes enabled, blending disabled.
30 _target0.set(redWriteShift);
31 _target0.set(greenWriteShift);
32 _target0.set(blueWriteShift);
33 _target0.set(alphaWriteShift);
34 }
35
37 {
38 return _target0.test(blendShift);
39 }
40
42 {
43 return _target0.test(redWriteShift);
44 }
45
47 {
48 return _target0.test(greenWriteShift);
49 }
50
52 {
53 return _target0.test(blueWriteShift);
54 }
55
57 {
58 return _target0.test(alphaWriteShift);
59 }
60
62 {
63 return getField(_target0, colorOpShift, opMask);
64 }
65
67 {
68 return getField(_target0, colorSrcFactorShift, factorMask);
69 }
70
72 {
73 return getField(_target0, colorDstFactorShift, factorMask);
74 }
75
77 {
78 return getField(_target0, alphaOpShift, opMask);
79 }
80
82 {
83 return getField(_target0, alphaSrcFactorShift, factorMask);
84 }
85
87 {
88 return getField(_target0, alphaDstFactorShift, factorMask);
89 }
90
91 // --- Setters ---
92
93 void BlendState::setField(int shift, uint32_t mask, uint32_t value)
94 {
95 // Clear the bits in the field, then set the new value
96 const int width = __builtin_popcount(mask);
97 for (int i = 0; i < width; ++i) {
98 _target0.reset(shift + i);
99 }
100 for (int i = 0; i < width; ++i) {
101 if (value & (1u << i)) {
102 _target0.set(shift + i);
103 }
104 }
105 }
106
107 void BlendState::setEnabled(bool value)
108 {
109 if (value) {
110 _target0.set(blendShift);
111 } else {
112 _target0.reset(blendShift);
113 }
114 }
115
117 {
118 setField(colorOpShift, opMask, static_cast<uint32_t>(op));
119 }
120
122 {
123 setField(colorSrcFactorShift, factorMask, static_cast<uint32_t>(factor));
124 }
125
127 {
128 setField(colorDstFactorShift, factorMask, static_cast<uint32_t>(factor));
129 }
130
132 {
133 setField(alphaOpShift, opMask, static_cast<uint32_t>(op));
134 }
135
137 {
138 setField(alphaSrcFactorShift, factorMask, static_cast<uint32_t>(factor));
139 }
140
142 {
143 setField(alphaDstFactorShift, factorMask, static_cast<uint32_t>(factor));
144 }
145
146 void BlendState::setRedWrite(bool value)
147 {
148 if (value) _target0.set(redWriteShift); else _target0.reset(redWriteShift);
149 }
150
152 {
153 if (value) _target0.set(greenWriteShift); else _target0.reset(greenWriteShift);
154 }
155
157 {
158 if (value) _target0.set(blueWriteShift); else _target0.reset(blueWriteShift);
159 }
160
162 {
163 if (value) _target0.set(alphaWriteShift); else _target0.reset(alphaWriteShift);
164 }
165
166 // --- Factory methods ---
167
180
182 {
183 // BLEND_MULTIPLICATIVE: output.rgb * framebuffer.rgb
184 // srcFactor = DST_COLOR, dstFactor = ZERO, op = ADD
185 // Result: src * dst + dst * 0 = src * dst
186 BlendState state;
187 state.setEnabled(true);
194 return state;
195 }
196
198 {
199 // BLEND_ADDITIVE: particles glow and accumulate light.
200 // srcFactor = SRC_ALPHA, dstFactor = ONE, op = ADD
201 // Result: src * srcAlpha + dst * 1 = premultiplied src + dst
202 BlendState state;
203 state.setEnabled(true);
210 return state;
211 }
212}
void setGreenWrite(bool value)
void setAlphaSrcFactor(int factor)
static BlendState alphaBlend()
void setColorDstFactor(int factor)
static BlendState multiplicativeBlend()
void setAlphaDstFactor(int factor)
void setColorSrcFactor(int factor)
static BlendState additiveBlend()
void setAlphaWrite(bool value)
void setBlueWrite(bool value)
constexpr int BLENDMODE_ONE_MINUS_SRC_ALPHA
Definition blendState.h:21
constexpr uint32_t alphaWriteShift
constexpr uint32_t alphaDstFactorShift
const uint32_t factorMask
constexpr int BLENDMODE_ONE
Definition blendState.h:14
const uint32_t opMask
constexpr uint32_t greenWriteShift
constexpr uint32_t blendShift
constexpr uint32_t colorOpShift
constexpr int BLENDEQUATION_ADD
Definition blendState.h:28
constexpr int BLENDMODE_ZERO
Definition blendState.h:13
constexpr uint32_t blueWriteShift
constexpr uint32_t alphaSrcFactorShift
constexpr uint32_t colorDstFactorShift
constexpr int BLENDMODE_SRC_ALPHA
Definition blendState.h:19
constexpr uint32_t alphaOpShift
constexpr int BLENDMODE_DST_COLOR
Definition blendState.h:17
constexpr uint32_t colorSrcFactorShift
constexpr uint32_t redWriteShift