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
8
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/* -------------------------------------------------------------------- */
28
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
323
324/* -------------------------------------------------------------------- */
327
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
441
442/* -------------------------------------------------------------------- */
445
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
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 rotate_m4(float mat[4][4], char axis, float angle)
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 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_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_STROKE_STYLE_SOLID
@ GP_MATERIAL_STROKE_STYLE_TEXTURE
@ GP_MATERIAL_GRADIENT_RADIAL
@ GP_MATERIAL_FOLLOW_OBJ
@ GP_MATERIAL_FOLLOW_PATH
@ GP_MATERIAL_FOLLOW_FIXED
@ 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.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
#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_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
VecBase< float, 3 > float3
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
short type
float color[4]
View3DShading shading
gpMaterialFlag flag