-
Notifications
You must be signed in to change notification settings - Fork 1
/
draw.hpp
340 lines (281 loc) · 6.74 KB
/
draw.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2019-2021 Sergey Chaban <sergey.chaban@gmail.com>
#ifndef DRW_NO_VULKAN
# define DRW_NO_VULKAN 0
#endif
#define DRW_IMPL_BEGIN namespace {
#define DRW_IMPL_END }
namespace Draw {
enum Mode {
DRWMODE_STD,
DRWMODE_DISCARD,
DRWMODE_SHADOW_CAST
};
enum TexUnit {
TEXUNIT_Base = 0,
TEXUNIT_Bump,
TEXUNIT_Spec,
TEXUNIT_Surf,
TEXUNIT_BumpPat,
TEXUNIT_Shadow,
TEXUNIT_COUNT
};
enum PrimType {
PRIMTYPE_POLY = 0,
PRIMTYPE_SPRITE = 1
};
struct Font {
struct SymInfo {
xt_float2 size;
int idxOrg;
int numTris;
};
int numSyms;
int numPnts;
int numTris;
xt_float2* pPnts;
uint16_t* pTris;
SymInfo* pSyms;
};
inline float clip_gamma(const float gamma) { return nxCalc::max(gamma, 0.01f); }
struct Context {
sxView view;
sxHemisphereLight hemi;
struct Spec {
cxVec mDir;
xt_float3 mClr;
float mShadowing;
bool mEnabled;
void set_dir(const cxVec& v) {
mDir = v.get_normalized();
}
void set_rgb(const float r, const float g, const float b) {
mClr.x = r;
mClr.y = g;
mClr.z = b;
}
void reset() {
mDir.set(0.0f, 0.0f, -1.0f);
mClr.fill(1.0f);
mShadowing = 1.0f;
mEnabled = true;
}
} spec;
sxFog fog;
struct CC {
sxToneMap mToneMap;
xt_float3 mGamma;
xt_float3 mExposure;
void set_gamma(const float gval) {
mGamma.fill(clip_gamma(gval));
}
void set_gamma_rgb(const float r, const float g, const float b) {
mGamma.set(clip_gamma(r), clip_gamma(g), clip_gamma(b));
}
void set_exposure(const float e) {
mExposure.fill(e);
}
void set_exposure_rgb(const float r, const float g, const float b) {
mExposure.set(r, g, b);
}
void set_linear_white(const float val) {
mToneMap.set_linear_white(val);
}
void set_linear_white_rgb(const float r, const float g, const float b) {
mToneMap.set_linear_white_rgb(r, g, b);
}
void set_linear_gain(const float val) {
mToneMap.set_linear_gain(val);
}
void set_linear_gain_rgb(const float r, const float g, const float b) {
mToneMap.set_linear_gain_rgb(r, g, b);
}
void set_linear_bias(const float val) {
mToneMap.set_linear_bias(val);
}
void set_linear_bias_rgb(const float r, const float g, const float b) {
mToneMap.set_linear_bias_rgb(r, g, b);
}
xt_float3 get_inv_gamma() const {
xt_float3 invGamma;
invGamma.set(nxCalc::rcp0(mGamma.x), nxCalc::rcp0(mGamma.y), nxCalc::rcp0(mGamma.z));
return invGamma;
}
void reset() {
mToneMap.reset();
set_exposure(-1.0f);
set_gamma(2.2f);
}
} cc;
struct Shadow {
cxMtx mViewProjMtx;
cxMtx mMtx;
cxVec mDir;
float mDens;
float mDensBias;
float mOffsBias;
float mWghtBias;
float mFadeStart;
float mFadeEnd;
void set_dir(const cxVec& v) {
mDir = v.get_normalized();
}
void set_dir_degrees(const float dx, const float dy) {
set_dir(nxQuat::from_degrees(dx, dy, 0.0f).apply(nxVec::get_axis(exAxis::PLUS_Z)));
}
float get_density() const {
return nxCalc::max(mDens + mDensBias, 0.0f);
}
void reset() {
set_dir_degrees(70, 140);
mDens = 1.0f;
mDensBias = 0.0f;
mOffsBias = 0.0f;
mWghtBias = 0.0f;
mFadeStart = 0.0f;
mFadeEnd = 0.0f;
mViewProjMtx.identity();
mMtx.identity();
}
} shadow;
struct Glb {
bool useSpec;
bool useBump;
void reset() {
useSpec = true;
useBump = true;
}
} glb;
struct Ext {
xt_float4* pArgs;
size_t numArgs;
void reset() {
pArgs = nullptr;
numArgs = 0;
}
} ext;
void reset() {
view.reset();
hemi.reset();
spec.reset();
fog.reset();
cc.reset();
shadow.reset();
glb.reset();
ext.reset();
}
bool ck_bbox_shadow_receive(const cxAABB& bbox) const {
float sfadeStart = shadow.mFadeStart;
float sfadeEnd = shadow.mFadeEnd;
bool recvFlg = true;
if (sfadeEnd > 0.0f && sfadeEnd > sfadeStart) {
cxVec vpos = view.mPos;
cxVec npos = bbox.closest_pnt(vpos);
if (nxVec::dist(vpos, npos) > sfadeEnd) {
recvFlg = false;
}
}
return recvFlg;
}
};
struct MtlContext {
const sxModelData::Material* pMtl;
uintptr_t baseTex;
uintptr_t bumpTex;
uintptr_t surfTex;
uintptr_t shadowTex;
};
struct MdlParam {
struct ExtIfc {
void (*draw_batch)(cxModelWork* pWk, const int ibat, const Mode mode, const Context* pCtx, const MtlContext& mtlCtx);
};
ExtIfc* pExtIfc;
xt_float3 baseColorScl;
float shadowOffsBias;
float shadowWeightBias;
float shadowDensScl;
void reset() {
pExtIfc = nullptr;
baseColorScl.fill(1.0f);
shadowOffsBias = 0.0f;
shadowWeightBias = 0.0f;
shadowDensScl = 1.0f;
}
};
struct PrimGeom {
struct {
uint32_t org;
uint32_t num;
const sxPrimVtx* pSrc;
} vtx;
struct {
uint32_t org;
uint32_t num;
const uint16_t* pSrc;
} idx;
};
struct Prim {
sxTextureData* pTex;
xt_texcoord texOffs;
xt_rgba clr;
cxMtx* pMtx;
uint32_t org;
uint32_t num;
PrimType type;
bool indexed;
bool dblSided;
bool alphaBlend;
bool depthWrite;
};
struct Quad {
xt_float2 pos[4];
xt_float2 tex[4];
xt_float2 rot[2];
cxColor color;
xt_float3 gamma;
float refWidth;
float refHeight;
sxTextureData* pTex;
cxColor* pClrs;
void clear() {
nxCore::mem_zero((void*)this, sizeof(Quad));
}
void set_gamma(const float gval) {
gamma.fill(clip_gamma(gval));
}
void set_gamma_rgb(const float r, const float g, const float b) {
gamma.set(clip_gamma(r), clip_gamma(g), clip_gamma(b));
}
};
struct Symbol {
cxColor clr;
xt_float2 rot[2];
int sym;
float ox;
float oy;
float sx;
float sy;
};
struct Ifc {
struct Info {
const char* pName;
bool needOGLContext;
} info;
void (*init)(const int shadowSize, cxResourceManager* pRsrcMgr, Font* pFont);
void (*reset)();
int (*get_screen_width)();
int (*get_screen_height)();
cxMtx (*get_shadow_bias_mtx)();
void (*init_prims)(const uint32_t maxVtx, const uint32_t maxIdx);
void (*prim_geom)(const PrimGeom* pGeom);
void (*begin)(const cxColor& clearColor);
void (*end)();
void (*batch)(cxModelWork* pWk, const int ibat, const Mode mode, const Context* pCtx);
void (*prim)(const Prim* pPrim, const Context* pCtx);
void (*quad)(const Quad* pQuad);
void (*symbol)(const Symbol* pSym);
};
int32_t register_ifc_impl(Ifc* pIfc);
Ifc* find_ifc_impl(const char* pName);
Ifc* get_ifc_impl();
} // Draw