Blender V4.3
gpencil_draw_data.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DRW_render.hh"
10
11#include "DNA_light_types.h"
12
13#include "BKE_image.hh"
14
15#include "BLI_hash.h"
16#include "BLI_math_color.h"
17#include "BLI_memblock.h"
18
19#include "GPU_uniform_buffer.hh"
20
21#include "IMB_imbuf_types.hh"
22
23#include "gpencil_engine.h"
24
25/* -------------------------------------------------------------------- */
30{
31 GPENCIL_MaterialPool *matpool = static_cast<GPENCIL_MaterialPool *>(
33 matpool->next = nullptr;
34 matpool->used_count = 0;
35 if (matpool->ubo == nullptr) {
36 matpool->ubo = GPU_uniformbuf_create(sizeof(matpool->mat_data));
37 }
38 pd->last_material_pool = matpool;
39 return matpool;
40}
41
42static GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_premult)
43{
44 ImageUser iuser = {nullptr};
45 GPUTexture *gpu_tex = nullptr;
46
47 gpu_tex = BKE_image_get_gpu_texture(image, &iuser);
48 *r_alpha_premult = (gpu_tex) ? (image->alpha_mode == IMA_ALPHA_PREMUL) : false;
49
50 return gpu_tex;
51}
52
53static void gpencil_uv_transform_get(const float ofs[2],
54 const float scale[2],
55 const float rotation,
56 float r_rot_scale[2][2],
57 float r_offset[2])
58{
59 /* OPTI this could use 3x2 matrices and reduce the number of operations drastically. */
60 float mat[4][4];
61 unit_m4(mat);
62 /* Offset to center. */
63 translate_m4(mat, 0.5f, 0.5f, 0.0f);
64 /* Reversed order. */
65 rescale_m4(mat, blender::float3{1.0f / scale[0], 1.0f / scale[1], 0.0});
66 rotate_m4(mat, 'Z', -rotation);
67 translate_m4(mat, ofs[0], ofs[1], 0.0f);
68 /* Convert to 3x2 */
69 copy_v2_v2(r_rot_scale[0], mat[0]);
70 copy_v2_v2(r_rot_scale[1], mat[1]);
71 copy_v2_v2(r_offset, mat[3]);
72}
73
74static void gpencil_shade_color(float color[3])
75{
76 /* This is scene refereed color, not gamma corrected and not per perceptual.
77 * So we lower the threshold a bit. (1.0 / 3.0) */
78 if (color[0] + color[1] + color[2] > 1.1) {
79 add_v3_fl(color, -0.25f);
80 }
81 else {
82 add_v3_fl(color, 0.15f);
83 }
84 CLAMP3(color, 0.0f, 1.0f);
85}
86
87/* Apply all overrides from the solid viewport mode to the GPencil material. */
90 Object *ob,
91 int color_type,
92 MaterialGPencilStyle *gp_style,
93 const eV3DShadingLightingMode lighting_mode)
94{
95 static MaterialGPencilStyle gp_style_tmp;
96
97 switch (color_type) {
100 /* Random uses a random color by layer and this is done using the tint
101 * layer. A simple color by object, like meshes, is not practical in
102 * grease pencil. */
103 copy_v4_v4(gp_style_tmp.stroke_rgba, gp_style->stroke_rgba);
104 copy_v4_v4(gp_style_tmp.fill_rgba, gp_style->fill_rgba);
105 gp_style = &gp_style_tmp;
108 break;
110 gp_style_tmp = blender::dna::shallow_copy(*gp_style);
111 gp_style = &gp_style_tmp;
112 if ((gp_style->stroke_style == GP_MATERIAL_STROKE_STYLE_TEXTURE) && (gp_style->sima)) {
113 copy_v4_fl(gp_style->stroke_rgba, 1.0f);
114 gp_style->mix_stroke_factor = 0.0f;
115 }
116
117 if ((gp_style->fill_style == GP_MATERIAL_FILL_STYLE_TEXTURE) && (gp_style->ima)) {
118 copy_v4_fl(gp_style->fill_rgba, 1.0f);
119 gp_style->mix_factor = 0.0f;
120 }
121 else if (gp_style->fill_style == GP_MATERIAL_FILL_STYLE_GRADIENT) {
122 /* gp_style->fill_rgba is needed for correct gradient. */
123 gp_style->mix_factor = 0.0f;
124 }
125 break;
127 gp_style = &gp_style_tmp;
130 copy_v3_v3(gp_style->fill_rgba, pd->v3d_single_color);
131 gp_style->fill_rgba[3] = 1.0f;
132 copy_v4_v4(gp_style->stroke_rgba, gp_style->fill_rgba);
133 if (lighting_mode != V3D_LIGHTING_FLAT) {
135 }
136 break;
138 gp_style = &gp_style_tmp;
141 copy_v4_v4(gp_style->fill_rgba, ob->color);
142 copy_v4_v4(gp_style->stroke_rgba, ob->color);
143 if (lighting_mode != V3D_LIGHTING_FLAT) {
145 }
146 break;
148 gp_style = &gp_style_tmp;
151 copy_v4_fl(gp_style->fill_rgba, 1.0f);
152 copy_v4_fl(gp_style->stroke_rgba, 1.0f);
153 break;
154 default:
155 break;
156 }
157 return gp_style;
158}
159
161 Object *ob,
162 int *ofs,
163 const bool is_vertex_mode)
164{
166
167 int mat_len = max_ii(1, BKE_object_material_count_eval(ob));
168
169 bool reuse_matpool = matpool && ((matpool->used_count + mat_len) <= GPENCIL_MATERIAL_BUFFER_LEN);
170
171 if (reuse_matpool) {
172 /* Share the matpool with other objects. Return offset to first material. */
173 *ofs = matpool->used_count;
174 }
175 else {
176 matpool = gpencil_material_pool_add(pd);
177 *ofs = 0;
178 }
179
180 /* Force vertex color in solid mode with vertex paint mode. Same behavior as meshes. */
181 int color_type = (pd->v3d_color_type != -1 && is_vertex_mode) ? V3D_SHADING_VERTEX_COLOR :
182 pd->v3d_color_type;
184 (pd->v3d != nullptr) ? eV3DShadingLightingMode(pd->v3d->shading.light) :
186
187 GPENCIL_MaterialPool *pool = matpool;
188 for (int i = 0; i < mat_len; i++) {
189 if ((i > 0) && (pool->used_count == GPENCIL_MATERIAL_BUFFER_LEN)) {
190 pool->next = gpencil_material_pool_add(pd);
191 pool = pool->next;
192 }
193 int mat_id = pool->used_count++;
194
195 gpMaterial *mat_data = &pool->mat_data[mat_id];
197
198 if (gp_style->mode == GP_MATERIAL_MODE_LINE) {
199 mat_data->flag = 0;
200 }
201 else {
202 switch (gp_style->alignment_mode) {
205 break;
208 break;
210 default:
212 break;
213 }
214
215 if (gp_style->mode == GP_MATERIAL_MODE_DOT) {
216 mat_data->flag |= GP_STROKE_DOTS;
217 }
218 }
219
220 if ((gp_style->mode != GP_MATERIAL_MODE_LINE) ||
221 (gp_style->flag & GP_MATERIAL_DISABLE_STENCIL))
222 {
223 mat_data->flag |= GP_STROKE_OVERLAP;
224 }
225
226 /* Material with holdout. */
227 if (gp_style->flag & GP_MATERIAL_IS_STROKE_HOLDOUT) {
228 mat_data->flag |= GP_STROKE_HOLDOUT;
229 }
230 if (gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT) {
231 mat_data->flag |= GP_FILL_HOLDOUT;
232 }
233
234 gp_style = gpencil_viewport_material_overrides(pd, ob, color_type, gp_style, lighting_mode);
235
236 /* Dots or Squares rotation. */
237 mat_data->alignment_rot[0] = cosf(gp_style->alignment_rotation);
238 mat_data->alignment_rot[1] = sinf(gp_style->alignment_rotation);
239
240 /* Stroke Style */
241 if ((gp_style->stroke_style == GP_MATERIAL_STROKE_STYLE_TEXTURE) && (gp_style->sima)) {
242 bool premul;
243 pool->tex_stroke[mat_id] = gpencil_image_texture_get(gp_style->sima, &premul);
244 mat_data->flag |= pool->tex_stroke[mat_id] ? GP_STROKE_TEXTURE_USE : 0;
245 mat_data->flag |= premul ? GP_STROKE_TEXTURE_PREMUL : 0;
246 copy_v4_v4(mat_data->stroke_color, gp_style->stroke_rgba);
247 mat_data->stroke_texture_mix = 1.0f - gp_style->mix_stroke_factor;
248 mat_data->stroke_u_scale = 500.0f / gp_style->texture_pixsize;
249 }
250 else /* if (gp_style->stroke_style == GP_MATERIAL_STROKE_STYLE_SOLID) */ {
251 pool->tex_stroke[mat_id] = nullptr;
252 mat_data->flag &= ~GP_STROKE_TEXTURE_USE;
253 copy_v4_v4(mat_data->stroke_color, gp_style->stroke_rgba);
254 mat_data->stroke_texture_mix = 0.0f;
255 }
256
257 /* Fill Style */
258 if ((gp_style->fill_style == GP_MATERIAL_FILL_STYLE_TEXTURE) && (gp_style->ima)) {
259 bool use_clip = (gp_style->flag & GP_MATERIAL_TEX_CLAMP) != 0;
260 bool premul;
261 pool->tex_fill[mat_id] = gpencil_image_texture_get(gp_style->ima, &premul);
262 mat_data->flag |= pool->tex_fill[mat_id] ? GP_FILL_TEXTURE_USE : 0;
263 mat_data->flag |= premul ? GP_FILL_TEXTURE_PREMUL : 0;
264 mat_data->flag |= use_clip ? GP_FILL_TEXTURE_CLIP : 0;
266 gp_style->texture_scale,
267 gp_style->texture_angle,
268 reinterpret_cast<float(*)[2]>(&mat_data->fill_uv_rot_scale),
269 mat_data->fill_uv_offset);
270 copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
271 mat_data->fill_texture_mix = 1.0f - gp_style->mix_factor;
272 }
273 else if (gp_style->fill_style == GP_MATERIAL_FILL_STYLE_GRADIENT) {
274 bool use_radial = (gp_style->gradient_type == GP_MATERIAL_GRADIENT_RADIAL);
275 pool->tex_fill[mat_id] = nullptr;
276 mat_data->flag |= GP_FILL_GRADIENT_USE;
277 mat_data->flag |= use_radial ? GP_FILL_GRADIENT_RADIAL : 0;
279 gp_style->texture_scale,
280 gp_style->texture_angle,
281 reinterpret_cast<float(*)[2]>(&mat_data->fill_uv_rot_scale),
282 mat_data->fill_uv_offset);
283 copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
284 copy_v4_v4(mat_data->fill_mix_color, gp_style->mix_rgba);
285 mat_data->fill_texture_mix = 1.0f - gp_style->mix_factor;
286 if (gp_style->flag & GP_MATERIAL_FLIP_FILL) {
287 swap_v4_v4(mat_data->fill_color, mat_data->fill_mix_color);
288 }
289 }
290 else /* if (gp_style->fill_style == GP_MATERIAL_FILL_STYLE_SOLID) */ {
291 pool->tex_fill[mat_id] = nullptr;
292 copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
293 mat_data->fill_texture_mix = 0.0f;
294 }
295 }
296
297 return matpool;
298}
299
301 int mat_id,
302 GPUTexture **r_tex_stroke,
303 GPUTexture **r_tex_fill,
304 GPUUniformBuf **r_ubo_mat)
305{
306 GPENCIL_MaterialPool *matpool = first_pool;
307 BLI_assert(mat_id >= 0);
308 int pool_id = mat_id / GPENCIL_MATERIAL_BUFFER_LEN;
309 for (int i = 0; i < pool_id; i++) {
310 matpool = matpool->next;
311 }
312 mat_id = mat_id % GPENCIL_MATERIAL_BUFFER_LEN;
313 *r_ubo_mat = matpool->ubo;
314 if (r_tex_fill) {
315 *r_tex_fill = matpool->tex_fill[mat_id];
316 }
317 if (r_tex_stroke) {
318 *r_tex_stroke = matpool->tex_stroke[mat_id];
319 }
320}
321
324/* -------------------------------------------------------------------- */
329{
330 GPENCIL_LightPool *lightpool = static_cast<GPENCIL_LightPool *>(
332 lightpool->light_used = 0;
333 /* Tag light list end. */
334 lightpool->light_data[0].color[0] = -1.0;
335 if (lightpool->ubo == nullptr) {
336 lightpool->ubo = GPU_uniformbuf_create(sizeof(lightpool->light_data));
337 }
338 pd->last_light_pool = lightpool;
339 return lightpool;
340}
341
342void gpencil_light_ambient_add(GPENCIL_LightPool *lightpool, const float color[3])
343{
344 if (lightpool->light_used >= GPENCIL_LIGHT_BUFFER_LEN) {
345 return;
346 }
347
348 gpLight *gp_light = &lightpool->light_data[lightpool->light_used];
349 gp_light->type = GP_LIGHT_TYPE_AMBIENT;
350 copy_v3_v3(gp_light->color, color);
351 lightpool->light_used++;
352
353 if (lightpool->light_used < GPENCIL_LIGHT_BUFFER_LEN) {
354 /* Tag light list end. */
355 gp_light[1].color[0] = -1.0f;
356 }
357}
358
359static float light_power_get(const Light *la)
360{
361 if (la->type == LA_AREA) {
362 return 1.0f / (4.0f * M_PI);
363 }
364 if (ELEM(la->type, LA_SPOT, LA_LOCAL)) {
365 return 1.0f / (4.0f * M_PI * M_PI);
366 }
367
368 return 1.0f / M_PI;
369}
370
372{
373 Light *la = (Light *)ob->data;
374
375 if (lightpool->light_used >= GPENCIL_LIGHT_BUFFER_LEN) {
376 return;
377 }
378
379 gpLight *gp_light = &lightpool->light_data[lightpool->light_used];
380 float(*mat)[4] = reinterpret_cast<float(*)[4]>(&gp_light->right);
381
382 if (la->type == LA_SPOT) {
383 copy_m4_m4(mat, ob->world_to_object().ptr());
384 gp_light->type = GP_LIGHT_TYPE_SPOT;
385 gp_light->spot_size = cosf(la->spotsize * 0.5f);
386 gp_light->spot_blend = (1.0f - gp_light->spot_size) * la->spotblend;
387 }
388 else if (la->type == LA_AREA) {
389 /* Simulate area lights using a spot light. */
390 normalize_m4_m4(mat, ob->object_to_world().ptr());
391 invert_m4(mat);
392 gp_light->type = GP_LIGHT_TYPE_SPOT;
393 gp_light->spot_size = cosf(M_PI_2);
394 gp_light->spot_blend = (1.0f - gp_light->spot_size) * 1.0f;
395 }
396 else if (la->type == LA_SUN) {
397 normalize_v3_v3(gp_light->forward, ob->object_to_world().ptr()[2]);
398 gp_light->type = GP_LIGHT_TYPE_SUN;
399 }
400 else {
401 gp_light->type = GP_LIGHT_TYPE_POINT;
402 }
403 copy_v4_v4(gp_light->position, ob->object_to_world().location());
404 copy_v3_v3(gp_light->color, &la->r);
405 mul_v3_fl(gp_light->color, la->energy * light_power_get(la));
406
407 lightpool->light_used++;
408
409 if (lightpool->light_used < GPENCIL_LIGHT_BUFFER_LEN) {
410 /* Tag light list end. */
411 gp_light[1].color[0] = -1.0f;
412 }
413}
414
416{
417 GPENCIL_LightPool *lightpool = pd->last_light_pool;
418
419 if (lightpool == nullptr) {
420 lightpool = gpencil_light_pool_add(pd);
421 }
422 /* TODO(fclem): Light linking. */
423 // gpencil_light_pool_populate(lightpool, ob);
424
425 return lightpool;
426}
427
428void gpencil_material_pool_free(void *storage)
429{
430 GPENCIL_MaterialPool *matpool = (GPENCIL_MaterialPool *)storage;
431 DRW_UBO_FREE_SAFE(matpool->ubo);
432}
433
434void gpencil_light_pool_free(void *storage)
435{
436 GPENCIL_LightPool *lightpool = (GPENCIL_LightPool *)storage;
437 DRW_UBO_FREE_SAFE(lightpool->ubo);
438}
439
442/* -------------------------------------------------------------------- */
457
459{
462
463 /* NOTE(@fclem): Putting this stuff in view-layer means it is shared by all viewports.
464 * For now it is ok, but in the future, it could become a problem if we implement
465 * the caching system. */
466 if (*vldata == nullptr) {
467 *vldata = static_cast<GPENCIL_ViewLayerData *>(
468 MEM_callocN(sizeof(**vldata), "GPENCIL_ViewLayerData"));
469
471 (*vldata)->gp_material_pool = BLI_memblock_create(sizeof(GPENCIL_MaterialPool));
472 (*vldata)->gp_maskbit_pool = BLI_memblock_create(BLI_BITMAP_SIZE(GP_MAX_MASKBITS));
473 (*vldata)->gp_object_pool = BLI_memblock_create(sizeof(GPENCIL_tObject));
474 (*vldata)->gp_layer_pool = BLI_memblock_create(sizeof(GPENCIL_tLayer));
475 (*vldata)->gp_vfx_pool = BLI_memblock_create(sizeof(GPENCIL_tVfx));
476 }
477
478 return *vldata;
479}
480
GPUTexture * BKE_image_get_gpu_texture(Image *image, ImageUser *iuser)
Definition image_gpu.cc:476
int BKE_object_material_count_eval(const struct Object *ob)
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_BITMAP_SIZE(_num)
Definition BLI_bitmap.h:36
MINLINE int max_ii(int a, int b)
#define M_PI_2
#define M_PI
void normalize_m4_m4(float rmat[4][4], const float mat[4][4]) ATTR_NONNULL()
void unit_m4(float m[4][4])
Definition rct.c:1127
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
void rescale_m4(float mat[4][4], const float scale[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void rotate_m4(float mat[4][4], char axis, float angle)
bool invert_m4(float mat[4][4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void swap_v4_v4(float a[4], float b[4])
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void copy_v4_fl(float r[4], float f)
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_memblock_create(elem_size)
#define ELEM(...)
#define CLAMP3(vec, b, c)
@ IMA_ALPHA_PREMUL
@ LA_AREA
@ LA_LOCAL
@ LA_SPOT
@ LA_SUN
@ GP_MATERIAL_FILL_STYLE_GRADIENT
@ GP_MATERIAL_FILL_STYLE_TEXTURE
@ GP_MATERIAL_FILL_STYLE_SOLID
@ GP_MATERIAL_FOLLOW_OBJ
@ GP_MATERIAL_FOLLOW_PATH
@ GP_MATERIAL_FOLLOW_FIXED
@ GP_MATERIAL_STROKE_STYLE_SOLID
@ GP_MATERIAL_STROKE_STYLE_TEXTURE
@ GP_MATERIAL_FLIP_FILL
@ GP_MATERIAL_DISABLE_STENCIL
@ GP_MATERIAL_IS_STROKE_HOLDOUT
@ GP_MATERIAL_IS_FILL_HOLDOUT
@ GP_MATERIAL_TEX_CLAMP
@ GP_MATERIAL_MODE_DOT
@ GP_MATERIAL_MODE_LINE
@ GP_MATERIAL_GRADIENT_RADIAL
@ V3D_SHADING_TEXTURE_COLOR
@ V3D_SHADING_VERTEX_COLOR
@ V3D_SHADING_MATERIAL_COLOR
@ V3D_SHADING_OBJECT_COLOR
@ V3D_SHADING_RANDOM_COLOR
@ V3D_SHADING_SINGLE_COLOR
eV3DShadingLightingMode
@ V3D_LIGHTING_FLAT
@ V3D_LIGHTING_STUDIO
#define DRW_UBO_FREE_SAFE(ubo)
#define GPU_uniformbuf_create(size)
Contains defines and structs used throughout the imbuf module.
#define sinf(x)
#define cosf(x)
void ** DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void(*callback)(void *storage))
draw_view in_light_buf[] float
#define GPENCIL_MATERIAL_BUFFER_LEN
#define GPENCIL_LIGHT_BUFFER_LEN
GPENCIL_MaterialPool * gpencil_material_pool_create(GPENCIL_PrivateData *pd, Object *ob, int *ofs, const bool is_vertex_mode)
void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
GPENCIL_LightPool * gpencil_light_pool_add(GPENCIL_PrivateData *pd)
static void gpencil_shade_color(float color[3])
GPENCIL_LightPool * gpencil_light_pool_create(GPENCIL_PrivateData *pd, Object *)
static GPENCIL_MaterialPool * gpencil_material_pool_add(GPENCIL_PrivateData *pd)
static MaterialGPencilStyle * gpencil_viewport_material_overrides(GPENCIL_PrivateData *pd, Object *ob, int color_type, MaterialGPencilStyle *gp_style, const eV3DShadingLightingMode lighting_mode)
static void gpencil_uv_transform_get(const float ofs[2], const float scale[2], const float rotation, float r_rot_scale[2][2], float r_offset[2])
GPENCIL_ViewLayerData * GPENCIL_view_layer_data_ensure()
static GPUTexture * gpencil_image_texture_get(Image *image, bool *r_alpha_premult)
void gpencil_light_pool_free(void *storage)
void gpencil_material_pool_free(void *storage)
static float light_power_get(const Light *la)
static void gpencil_view_layer_data_free(void *storage)
void gpencil_light_ambient_add(GPENCIL_LightPool *lightpool, const float color[3])
void gpencil_material_resources_get(GPENCIL_MaterialPool *first_pool, int mat_id, GPUTexture **r_tex_stroke, GPUTexture **r_tex_fill, GPUUniformBuf **r_ubo_mat)
#define GP_MAX_MASKBITS
DrawEngineType draw_engine_gpencil_type
@ GP_LIGHT_TYPE_AMBIENT
@ GP_LIGHT_TYPE_SUN
@ GP_LIGHT_TYPE_POINT
@ GP_LIGHT_TYPE_SPOT
@ GP_FILL_TEXTURE_USE
@ GP_STROKE_DOTS
@ GP_STROKE_HOLDOUT
@ GP_STROKE_TEXTURE_PREMUL
@ GP_STROKE_ALIGNMENT_STROKE
@ GP_FILL_TEXTURE_PREMUL
@ GP_STROKE_TEXTURE_USE
@ GP_STROKE_ALIGNMENT_OBJECT
@ GP_FILL_GRADIENT_USE
@ GP_FILL_TEXTURE_CLIP
@ GP_FILL_GRADIENT_RADIAL
@ GP_STROKE_OVERLAP
@ GP_FILL_HOLDOUT
@ GP_STROKE_ALIGNMENT_FIXED
struct gpLight gpLight
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN]
struct GPUUniformBuf * ubo
gpMaterial mat_data[GPENCIL_MATERIAL_BUFFER_LEN]
struct GPUTexture * tex_fill[GPENCIL_MATERIAL_BUFFER_LEN]
struct GPUUniformBuf * ubo
struct GPENCIL_MaterialPool * next
struct GPUTexture * tex_stroke[GPENCIL_MATERIAL_BUFFER_LEN]
GPENCIL_LightPool * last_light_pool
struct BLI_memblock * gp_material_pool
struct View3D * v3d
struct BLI_memblock * gp_light_pool
GPENCIL_MaterialPool * last_material_pool
struct BLI_memblock * gp_vfx_pool
struct BLI_memblock * gp_material_pool
struct BLI_memblock * gp_maskbit_pool
struct BLI_memblock * gp_light_pool
struct BLI_memblock * gp_layer_pool
struct BLI_memblock * gp_object_pool
float energy
float spotblend
float spotsize
short type
float color[4]
View3DShading shading
gpMaterialFlag flag